GitHubのモノレポ運用でも必須ステータスチェックを設定する

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ディレクトリに２つのサービスがあり、それぞれのGitHubActionsがあります。

このような構成で、service1 のみ更新をしたとき、以下のように必須チェックが Pass していないと判定されマージできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/9f882e9d-eee4-bbb9-fd6d-ecf6ead08ba0.png)

また、そもそもチェックが必要ない更新の場合も、完了していないと判断されマージすることができません。

今回は、GitHub Actionsを使用してるモノレポで、必須ステータスチェックを使用する方法を紹介します。

## 設定

### 1. ジョブ名をそろえる
同じようなチェック内容でサービスごとに名前が異なる場合はジョブ名をそろえます。

以下はサービスごとにジョブ名が異なっているので、「npm test」と「docker build」にそろえています。

```diff_yaml:.github/workflows/service1.yml
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

...

```

```diff_yaml:.github/workflows/service2.yml
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が起動されず課金を抑えることができます。

```yaml:.github/workflows/dummy.yml
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]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/144545ac-5b23-00a3-f545-91358d48dce0.png)

Status checks that are required で必須にするチェックを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/348b1587-5a8b-815e-404f-b6a5cfad968e.png)

この必須チェックは、ジョブ名ごとに指定するため、チェック内容が異なっていてもどちらかのチェックが動けばマージできます（もちろん動いたチェックは全て Pass しないとマージできません）

## 確認
### 1. １つのサービスを更新したPull request

service1 を更新した場合です。
required status checks に service1 が含まれ、Pass するとマージできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/f4a4759f-0e38-b3e5-d22d-e991e9b98daf.png)

チェックが Fail した場合はマージをブロックできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/cc1d837c-ccb4-0424-8c95-0514e7961bf1.png)

### 2. 複数のサービスを更新したPull request

複数のサービスのチェックが Required で実行されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/c070a64f-91dd-d045-99d0-e737705c5ce9.png)


### 3. チェックが必要ないPull request

ダミーで作成したチェックが実行されマージできます。
required status checks は Skip しただけでもマージの条件を満たすことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/2c056f1e-555a-8271-a08e-0de9b0723268.png)

## 終わり
以上で必須チェックの設定ができました。
むちゃな方法ですが、テストが通っていないマージをブロックでき、不具合の混入を防ぐことができます。

修正内容により必要チェックが変わる場合、現状この方法を取るしかないと思われます。
しかし、GitHubは機能の追加が頻繁にあるため、他にいい解決方法ができているかもしれません。
他の解決方法をご存じの方がいればご連絡お待ちしております！