Github Actionsを使ってプルリクエストを自動でマージしたい

Scalaを利用したプロジェクトだとScala Stewardを導入しているところも多いのではないでしょうか?

Stewardは便利なんですがPRをいちいち手動でマージするのが面倒なので、それを自動化するのが本ブログの趣旨です。

Scala Stewardとは?

github.com

Scala Stewardはプロジェクトで使われているScalaのライブラリの依存関係、sbtプラグイン、Scalaとsbtのバージョンを最新に保つためのボットです。

簡単に言うと、ライブラリのバージョンアップがあったら自動でPR作ってくれる便利なやつ。

似たようなボットでいうとDependabotとかですかね。

github.com

前提

プロジェクトによってGithubのリポジトリの設定は違うと思いますが、ある程度前提を揃えておきましょう。

ブランチ保護設定

  • Protect matching branches
    • ✅ Require a pull request before merging
      • ✅ Require approvals: 1
  • ✅ 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

zenn.dev

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必須は突破できます。

cli.github.com

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の使用料金が掛かってしまうため難しいところです。

最後に

この記事が誰かの役に立てば幸いです。

以上。