Pull requestをマージする時、ビルドやテストが通過しないとマージできないようにしてほしいですよね。
GitHubでは required status checks という、指定したチェックが Fail した場合マージをブロックする機能があります。
ただし、required status checks は、モノレポを使用している場合などには使いにくいことがあります。
例えば、以下のようなリポジトリだとします。
📦github-monorepo-test
┣ 📂.github
┃ ┣ 📂workflows
┃ ┃ ┣ 📜service1.yml
┃ ┃ ┗ 📜service2.yml
┣ 📂applications
┃ ┣ 📂service1
┃ ┃ ┣ 📜Dockerfile
┃ ┃ ┣ 📜package-lock.json
┃ ┃ ┗ 📜package.json
┃ ┗ 📂service2
┃ ┣ 📜Dockerfile
┃ ┣ 📜package-lock.json
┃ ┗ 📜package.json
┣ 📜README.md
┗ 📜docker-compose.yml
applicationsディレクトリに2つのサービスがあり、それぞれのGitHubActionsがあります。
このような構成で、service1 のみ更新をしたとき、以下のように必須チェックが Pass していないと判定されマージできません。
また、そもそもチェックが必要ない更新の場合も、完了していないと判断されマージすることができません。
今回は、GitHub Actionsを使用してるモノレポで、必須ステータスチェックを使用する方法を紹介します。
設定
1. ジョブ名をそろえる
同じようなチェック内容でサービスごとに名前が異なる場合はジョブ名をそろえます。
以下はサービスごとにジョブ名が異なっているので、「npm test」と「docker build」にそろえています。
name: service1
on:
pull_request:
paths:
- '**/applications/service1/**'
jobs:
npm_test:
+ name: npm test
- name: npm test service1
runs-on: ubuntu-latest
...
docker_build:
+ name: docker build
- name: docker build service1
runs-on: ubuntu-latest
...
name: service2
on:
pull_request:
paths:
- '**/applications/service2/**'
jobs:
npm_test:
+ name: npm test
- name: npm test service2
runs-on: ubuntu-latest
...
docker_build:
+ name: docker build
- name: docker build service2
runs-on: ubuntu-latest
...
2. ダミーのチェックを作成する
常に実行されるジョブを作成します。ジョブには if: ${{ false }}
を設定して、常に Skip されるようにします。
Skip するとRunnerが起動されず課金を抑えることができます。
name: _always skipped
on:
pull_request:
jobs:
npm_test:
name: npm test
runs-on: ubuntu-latest
if: ${{ false }}
steps:
- name: Pass
run: echo ok
docker_build:
name: docker build
runs-on: ubuntu-latest
if: ${{ false }}
steps:
- name: Pass
run: echo ok
3. GitHubの必須チェック設定を変更
[Settings]タブ → [Branches] → 対象ブランチの[Edit]をクリックします。
Status checks that are required で必須にするチェックを設定します。
この必須チェックは、ジョブ名ごとに指定するため、チェック内容が異なっていてもどちらかのチェックが動けばマージできます(もちろん動いたチェックは全て Pass しないとマージできません)
確認
1. 1つのサービスを更新したPull request
service1 を更新した場合です。
required status checks に service1 が含まれ、Pass するとマージできます。
2. 複数のサービスを更新したPull request
複数のサービスのチェックが Required で実行されています。
3. チェックが必要ないPull request
ダミーで作成したチェックが実行されマージできます。
required status checks は Skip しただけでもマージの条件を満たすことができます。
終わり
以上で必須チェックの設定ができました。
むちゃな方法ですが、テストが通っていないマージをブロックでき、不具合の混入を防ぐことができます。
修正内容により必要チェックが変わる場合、現状この方法を取るしかないと思われます。
しかし、GitHubは機能の追加が頻繁にあるため、他にいい解決方法ができているかもしれません。
他の解決方法をご存じの方がいればご連絡お待ちしております!