👻

【Github】モノレポのブランチ保護ルール設定ではまったこと

2023/08/23に公開

当初はまったこと

  • Githubのブランチ保護ルールでPRをマージする際に、特定のCIの成功を必須化した。
  • しかし、モノレポの構成を取っていたので、他のディレクトリのサービスのPRに対してもCIを回す必要が発生した。
  • 必要のない時はCIを回したくなくないので、Github Actionのpathsフィルター (https://docs.github.com/ja/actions/using-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore)で、特定のディレクトリの変更時のみWorkflowを実行するようにしたが、WorkflowがスキップされるとCIの成功を満たさず、マージがブロックされてしまった。

解決方法

  • pathsフィルターを外して、Workflow自体は実行させるようにした
  • その代わり、jobをCIのjobの前におくことで、必要な時のみCIの本体を実行させ、不必要なときはpath-checkのみを実行する構成にしました。Workflow自体は無駄打ちになりますが、軽いjobなので実行時間はわずかで、気になるレベルではありません。
    以下はサンプルコードです。
jobs:
  path-check:
    runs-on: ubuntu-latest
    outputs:
      message: ${{ steps.check.outputs.message }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - id: check
        name: Check changes in specific path
        run: |
          changes=$(gh pr diff --name-only ${{ github.event.pull_request.number }} | grep $PATH_TO_CHECK || true)
          if [ -z $changes ]; then
            echo 'skip main-job'
          else
            echo 'message=continue' >> $GITHUB_OUTPUT
          fi
        env:
          PATH_TO_CHECK: 'apps/'
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  main-job:
    runs-on: ubuntu-latest
    needs: path-check
    if: needs.path-check.outputs.message == 'continue'
  
  merge-block:
    runs-on: ubuntu-latest
    needs: [path-check, main-job]
    if: always()

   steps:
      - name: Merge Block
        if: contains(needs.*.result, 'failure')
        run: |
          echo "Block Merge"
          exit 1

どのように動作するか

前提: merge-blockStatus checks that are required.に指定している

  1. path-checkjob ubuntu-latest で実行され、特定のパスに変更があるかチェックします。
  2. Check changes in specific pathstepでは、gh pr diffコマンドを使用して、特定のpath(ここでは apps/)に変更があるかどうかを確認します。
  3. 変更がある場合は、message=continueを出力し、次のjobを実行します。
  4. 変更がない場合は、skip main-jobと出力して次のjobをスキップします。path-checkubuntu-latestで実行され、特定のパスに変更があるかチェックします。

最後に

手探りで解決したものなるので、より良い解決策があれば教えていただけると嬉しいです。

Discussion