👻
【Github】モノレポのブランチ保護ルール設定ではまったこと
当初はまったこと
- 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-block
をStatus checks that are required.
に指定している
-
path-check
job ubuntu-latest で実行され、特定のパスに変更があるかチェックします。 -
Check changes in specific path
stepでは、gh pr diff
コマンドを使用して、特定のpath(ここでは apps/)に変更があるかどうかを確認します。 - 変更がある場合は、
message=continue
を出力し、次のjobを実行します。 - 変更がない場合は、
skip main-job
と出力して次のjobをスキップします。path-check
がubuntu-latest
で実行され、特定のパスに変更があるかチェックします。
最後に
手探りで解決したものなるので、より良い解決策があれば教えていただけると嬉しいです。
Discussion