Scalaを利用したプロジェクトだとScala Stewardを導入しているところも多いのではないでしょうか?
Stewardは便利なんですがPRをいちいち手動でマージするのが面倒なので、それを自動化するのが本ブログの趣旨です。
Scala Stewardとは?
Scala Stewardはプロジェクトで使われているScalaのライブラリの依存関係、sbtプラグイン、Scalaとsbtのバージョンを最新に保つためのボットです。
簡単に言うと、ライブラリのバージョンアップがあったら自動でPR作ってくれる便利なやつ。
似たようなボットでいうとDependabotとかですかね。
前提
プロジェクトによってGithubのリポジトリの設定は違うと思いますが、ある程度前提を揃えておきましょう。
ブランチ保護設定
- Protect matching branches
- ✅ Require a pull request before merging
- ✅ Require approvals: 1
- ✅ Require a pull request before merging
- ✅ Require status checks to pass before merging
- 他のワークフローでUnitTestやIntegrationTestが実行されているイメージ
やりたいこと
StewardがPRを作成したらユニットテストやインテグレーションテストがCIで実行され、それらが完了して成功していれば自動でマージを行いたい。
対応方法
以下のようなGithub Actionsのワークフローを記載します。
name: Steward Auto Merge on: pull_request: branches: - main permissions: pull-requests: write contents: write jobs: auto-merge: runs-on: ubuntu-latest if: startsWith(github.head_ref, 'update/') env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Approve PR run: gh pr review "$PR_URL" --approve - name: Enable auto-merge for Steward PRs run: gh pr merge --merge --auto "$PR_URL"
解説
on.pull_request.branches
まず、on.pull_request.branches
には main
を指定しています。
ここでよく間違えるのが、botが作成するブランチ名を指定してしまう点です。
branches
にはPRが作成されてマージされるブランチ対象の名前を指定する必要があります。
自分は認識を間違えていてワークフローが起動されずに時間を溶かしてしまいました。
Github Actions Workflow Trigger#Pull Request
jobs.*.if
job.*.if
を使うことでジョブの実行条件を書くことができます。
ここでは、PRのブランチ名のプレフィックスがupdate/
であればジョブを実行するように定義しています。
もし特定のアクターがPRを作成しているのであれば、以下のように定義しても良いかもしれません。
if: ${{ github.actor == 'my-dependabot' }}
gh pr review --approve
Githubのgh pr review --apprve
コマンドを使用して、PRをapproveしています。
これでブランチ保護の1人以上のApprove必須は突破できます。
gh pr merge --merge --auto
Githubのgh pr merge --auto
コマンドを使用して、PRをマージします。
正確にいうと、上記のコマンドを実行することで一旦マージキューに入れて、自動マージを有効にします。
ブランチ保護の設定内容は有効なので、その他のワークフローのchecksがすべて成功していれば自動でマージされますし、もしユニットテスト等のワークフローが失敗した場合は自動マージされないので安心です。
ここで注意点なのが、リポジトリのAllow auto-merge
設定は必ず有効にしておきましょう。
この設定が有効でないと、自動マージを有効にしようとするとワークフローでエラーが発生してしまいます。
余談
Github Appを作成してadmin権限で gh pr merge --merge --admin
を実行するとPRのapprovalの必須設定を避けてマージすることはできます。
しかし、他のワークフローのchecksの成功を待たず、マージキューにも追加せずに対象ブランチに直接マージするため、ユニットテスト等が失敗していてもマージされてしまいます。
そのため、もしadmin権限でマージしたい場合は、マージを実行するステップの前に他のワークフローがすべて完了して成功しているかをチェックするステップを挟んだほうが良いかもしれません。
ただ、その場合は待っている間はスリープしたりする必要があると思うのでその間余計なGithub Actionsの使用料金が掛かってしまうため難しいところです。
最後に
この記事が誰かの役に立てば幸いです。
以上。