
GitHub Actionsで自動的にPull Requestをマージする
なぜPull Requestを自動的にマージさせたいのかというと、トランクベース開発をやりたいから です。
継続的デリバリーをきちんと実践し、1日に何回もデプロイできる状況を実現したい場合、トランクベース開発を実践できた方が良いでしょう。 「トランクベース開発ってmainに直接コミットするやり方じゃないの?」と思ったあなたは鋭いです。 真のトランクベース開発は、mainブランチに直接コミットするスタイルです。
しかし、GitHubにはPull Requestという強力な機能があります。 そしてGitHubにはルールセットや必須ステータスチェックといった継続的インテグレーションにうってつけの機能もあります。 また、サードパーティもPull Requestを前提とした機能が多いため、これを使わないのはもったいないです。
そこで、Pull Requestを使いつつも、トランクベース開発のエッセンスを取り込みます。 Pull Requestを作るけどすぐに自動的にマージさせ、擬似的なトランクベース開発を実現します。
ルールセットで必須ステータスチェックを有効にする
ルールセット を作成すると、Pull Requestがマージできる条件を作れます。
使用できるルールは多岐に渡りますが、マージ前のPull Requestを必須にする は必須ルールの1つでしょう。1人で開発している人(私とか)でも、有効にしておくべきかなと思います。自然とセルフレビューをするクセがつきますし、Pull Requestの本文をきちんと書いておけば、後々振り返りやすいです。
ルールセットで指定できるルールの1つに、「必須ステータスチェック」があります。 必須ステータスチェックとは、GitHub ActionsのジョブやGitHub Appsのジョブ(Vercelのデプロイとか)を指定し、それらがパスしていないとマージを許可しない という機能です。 人間がPull Requestをマージする場合は、自然とジョブが成功するのを待つと思いますが、GitHub Actionsで自動マージさせる場合はこの仕組みを使ってやらないと、テストが終わっていないうちにガンガンマージしてしまいます。なので必須ステータスチェックが 必須 です。
必須ステータスチェックは Require status checks to pass をオンにすると有効になります。 Require status checks to pass を有効にすると、追加設定が出現します。
追加設定では、 Require branches to be up to date before merging も有効にし、トピックブランチを切った時からベースブランチが更新されていた場合はマージできないようにしましょう。これで、「先に進んだベースブランチにマージすると実はテストに失敗する状態だった」という状況を回避でき、CI によるテストなどが確実にパスしていることを保証できます。
そして、 Status checks that are required にパスすることを必須としたいワークフロー(チェック)を追加します。このサイトのリポジトリ では、AWS Amplifyのビルド・デプロイのジョブを指定し、これらが成功していることをチェックしています。
Pull Requestを自動的にマージする
必須ステータスチェックを有効にしたら、必須となったステータスチェックをパスし次第マージさせるような仕組みを導入します。 具体的には、GitHub ActionsにPull RequestをApproveさせ、さらにマージもさせます。
そのためには、まず以下のような設定変更が必要です。
- Allow auto-merge(自動マージを許可する) をオンにする(Settings > General > Pull Requests)
- Allow GitHub Actions to create and approve pull requests(GitHub ActionsにPull Requestの作成と承認を許可する) をオンにする(Settings > Actions > General > Workflow permissions)
これで、GitHub ActionsがPull Requestを承認して、さらに必須ステータスチェックがパスし次第マージするスイッチをオンにできるようになります。
次に、以下のようなワークフローを作成します。
# .github/workflows/auto-merge-pr
name: auto-merge-pr
on:
pull_request:
defaults:
run:
shell: bash
jobs:
auto-merge:
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
pull-requests: write
steps:
- name: checkout
uses: actions/checkout@v4
- name: auto-merge
run: |
gh pr review "${GITHUB_HEAD_REF}" --approve
gh pr merge "${GITHUB_HEAD_REF}" --merge --auto
env:
GH_TOKEN: ${{ github.token }}
このワークフローでは、GitHub Actionsで GitHub CLI を使って、レビューとマージを行っています。
ちなみに、自動マージワークフローを追加するためのPull Requestを作ると、そのPull Requestで早速このワークフローが動作し、必須ステータスチェックをパスすれば自動的にマージされるはずです。
まとめ
GitHubでPull Requestにまつわる各種機能を活かしつつ、トランクベースに近い開発スタイルを実現するため、Pull Requestを自動的にマージする方法を紹介しました。しかし、無条件で自動マージすることは危険です(当然ですね)。適切なチェック(ビルドの成功、ユニットテストや自動受け入れテスト、ステージングへのデプロイなど)をパスしたことを証明するための手段として必須ステータスチェックも併用すべきです。
お気付きかもしれませんが、この自動マージを実践する場合には、 GitHub Actionsによる自動テストなどへの信頼性 を高めておく必要があります。「ビルドはできてるし、(一応書いてある)自動テストも通って、デプロイもできてるけど、本当にバグがないか不安だ」と思っているのであれば、自動マージは時期尚早です。まずは 自動テストが通っていれば本番にデプロイしても問題ない と自信を持って言えるぐらいにしましょう。