おおくまねこ

職業プログラマーです。興味のある話題を書いています。

scala-steward を個人レポジトリの GitHub Actions で動作させられた記録

はじめに

scala-stewardGitHub Actions から実行し、

自分のレポジトリに対してライブラリ更新ができるようにできたので、

その時の内容を記載します。

 

設定方法がよくわからなかったり、設定項目が何が必要かがわかりにくかったりしたので

それについても残しておきたかった所存です。

 

作った scala-steward を使うための GitHub Actions の設定レポジトリは以下です

github.com

scala-steward とは

Scala プロジェクトが依存するライブラリがバージョンアップリリースが存在していると、更新するためのPRを自動生成してくれるシステムです。

対抗というか、類似のツールでは Renovatedependabot などがあります。

 

モチベーション

なぜ scala-steward か

他にもコンペのツールがある中で scala-steward を使ったかというと、大きくは以下の2点です。

  • 他言語での開発している自前レポジトリでは Renovate, dependabot を使っているので scala-steward をつかってみたかった
  • 多くの有名Scalaプロジェクトで使われているので興味があった

 

以下の記事によると、Renovate でも結構いけるらしいのですが、

tarao.hatenablog.com

やっぱり scala-steward を使ってみたかったので自分の環境下で動かせるようにしました。

GitHub Actions で動かす理由

実はわざわざ自分で実行環境を用意しないでも scala-steward を使う方法があります*1

 scala-steward の公式が動作する環境を用意してくれていて、

対象レポジトリ一覧に自分の管理するScalaプロジェクトのリポジトリを追加すれば動かすことが可能です

repos/repos-github.md at main · scala-steward-org/repos · GitHub


この方法のネックとしては「更新リクエストを送ってマージしてもらう必要がある」、「自分の作業用レポジトリを追加してもらうのが恥ずかしい」というのがあります。

なので自分で気兼ねなく使える環境が欲しかったため、GitHub Actions での環境を用意しました。

GitHub Actions を使う場合は以下のテンプレートを使わせてもらいます。

github.com

 

設定方法

前提条件

今回は以下の環境で設定することを前提になっています

  • scala-steward を実行する専用のレポジトリから動作させます
  • GitHub App からコミット、PR生成してもらうようにします

設定に必要なこと

設定に必要な作業は以下

  • GitHub App を生成します
  • GitHub App の秘密鍵を生成します
  • scala-steward 実行する専用のレポジトリを GitHub に作成します
  • レポジトリの設定の secrets に以下の登録します
  • GitHub Actions の workflow を作成します
  • scala-steward の実行対象のレポジトリを決定する設定ファイルの作成
  • GitHub Actions のジョブを有効化します

設定手順

GitHub App を生成

GitHub App の生成するページから「New GitHub App」のボタンをクリックして、

今回使うようの App を作成します。

設定した項目は以下にしてました

  • GitHub App name
    • 好きな名前でいいです。今回は「keyno63-scala-steward」とかにしました。
  • Homepage URL
    • 自分の GitHub アカウントのURLを入れてました
  • Webhook
    • デフォルトでは有効でしたが、今回いらないと思ったのでチェックボックスを外して無効化しました
  • Repository permissions
    • 「Contents」、「Pull Request」を「Read&Write」にします
  • そのほかはデフォルトです。

以上の設定をして、「Create GitHub App」をクリックすると、Appが生成されます。

以下のようになっていれば問題ありません*2

f:id:keyno63:20211128040249p:plain

GitHub App の秘密鍵を生成

App 作成したら、作った App の「Edit」をクリックするか、

https://github.com/settings/apps/<作成したアプリケーション> にアクセスして、

App の編集画面に遷移します。

 

画面下のほうまでスクロールして、「Private Keys」という項目まで移動します。

「Generate a private key」をクリックして秘密鍵を生成します。

秘密鍵を生成出来たら、.pem ファイルが自動でダウンロードされます。

後で使うのでおいておいてください。

 

scala-steward 実行用レポジトリを生成

GitHub から新規レポジトリを作成します。

https://github.com/new

 

ここで作るのは空レポジトリで問題ありません。

必要なファイルは .github/workflows/***.yamlだけです。これはあとで作るので今は何もなしでもよいです。

 

secret の設定

レポジトリの設定から secretを設定します。

先ほど作成したレポジトリの「Settings」、左メニューの「Secrets」をクリックして遷移します。

「New repository secret」ボタンをクリックして Secret生成画面に遷移します。

f:id:keyno63:20211128042815p:plain

もしくはhttps://github.com/<GitHubアカウント名>/<作成したレポジトリ名>/settings/secrets/actions/newにアクセスしてもらっても大丈夫です。

 

Nameに後で使う設定名を、Valueには先ほど設定した GitHub App の秘密鍵の中身をコピーして貼り付けてください

自分は「SS_PRIVATE_KEY」という設定名で作成したので以下のようになりました。

同じように Secretが作成されていれば問題ありません。

f:id:keyno63:20211128043548p:plain

GitHub Workflows の作成

GitHub Workflows を作成します。GitHub Actions 用の yaml ファイルを作成します。

以下のように作成して貰えれば大丈夫です*3

name: CI
on:
schedule:
- cron: '0 0 * * 0'
pull_request:
push:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Generate token
id: generate-token
uses: tibdex/github-app-token@v1
with:
app_id: <作成した app id>
private_key: ${{ secrets.SS_PRIVATE_KEY }}
- name: Launch Scala Steward
uses: scala-steward-org/scala-steward-action@v2
with:
github-token: ${{ steps.generate-token.outputs.token }}
author-name: "<作成した App >[bot]"
author-email: "<作成した App user id>+<作成した App >[bot]@users.noreply.github.com"
repos-file: 'repos.md'

実例は以下

https://github.com/keyno63/scala-steward-mine/blob/2e31af53b972ef50f2393616b855a4e1dddf66ba/.github/workflows/ci.yaml

 

補足:app id について

作成した GitHub App の App ID のことです。

GitHub App の編集画面から確認できます。

f:id:keyno63:20211128044649p:plain

補足:author-email の取得

GitHub App のユーザー情報取得するAPIから、user id を取得できれば、App用の email が取得できます。

https://api.github.com/users/<作成した App 名>%5Bbot%5D

レスポンスの jsonidの値がわかれば、今回作成したApp名はわかるので、email が作れるというわけです。

対象レポジトリの設定ファイルを作成

workflows の yaml で指定した repos-fileのファイルを作成し、実行対象のレポジトリを指定します。

md ファイル形式で列挙して貰えればいいです。

https://github.com/keyno63/scala-steward-mine/blob/2e31af53b972ef50f2393616b855a4e1dddf66ba/repos.md

GitHub Actions を有効化してPR作成

GitHub Actionsからジョブが実行されて、ライブラリの更新があればPRが自動生成されます。

 

実際に作成されたPR

https://github.com/keyno63/heroku-scala-app/pull/5

 

作成した App で修正コミットがされていること、PRが生成されていることがわかります。

f:id:keyno63:20211128050140p:plain

ここまでできていれば完成です。

 

うまくいかなかったこととか、補足とか

補足情報的な項目です。

読まなくても設定は可能なので読み飛ばしてもらっても問題ありません。

うまくいかなかったこと

scala-steward-org/scala-steward-actionの設定に App として動作させるための項目に

github-app-idgithub-app-keyを設定するのがあるのですが、

repos/repos-github.md at main · scala-steward-org/repos · GitHub

これを設定した場合に repos-file による、特定のレポジトリのみに対する更新ができませんでした。

まだ中身をちゃんと確認していないので原因は不明

 

補足

GithubApp を作った理由

GitHub App から自分以外が更新した・PRの生成であることがわかるように作成しています。

「自分の活動履歴が実際のものと異なる」、「自分の作業と区別したい」という理由があったのでこの方法を採用しました。

 

「自分のコミット・PRでも構わない」という人は作成しなくても問題ないかもしれません。

その場合は workflow 中の token 生成は不要です。

代わりにgithub-tokenには自分のアカウントの token を sercret に設定し、

author-nameauthor-emailは自分の GitHub アカウントに紐づいたものを使用して

使ってください。

 

GitHub Action 中で token の生成について

GitHub App からの PR にするために使用します。bot からのPRであることを識別してもらうため、workflow の中で token を生成してもらっています。

uses: tibdex/github-app-token@v1の部分があたります。

 

これをせず、自分の token を secrets に登録、それを利用するとすると、

PRは作成できるのですが、作成者が自分になるという悲しい結果になります。

 

失敗してしまった例

https://github.com/keyno63/sbt-heroku/pull/4

f:id:keyno63:20211128052432p:plain

コミットは App になっていそうだが、PR作成者は自分のアカウントになる。

author-name, author-email について

author-nameauthor-emailはコミットするときのユーザー情報です。

これも自分の実績と分けたかったので、設定しています。

 

参考情報

今回の作業にあたり、以下の情報を参考にさせていただきました。

最後に

ずっと興味のあった scala-steward が自分のレポジトリに適応できるようになったので感無量です。とてもうれしかった。

*1:GitHub Enterprise や private repository を使っている場合はダメだったかもしれません

*2:このAppはアイコン画像を設定している状態です

*3:項目の説明は後述