title | emoji | type | topics | published | ||
---|---|---|---|---|---|---|
GitHub Actionsで差分に応じたジョブの選択実行とPRマージにおける必須ジョブ設定を両立させる |
🎯 |
tech |
|
true |
:::message この記事は GitHub Actions Advent Calendar 2023 の 7 日目の記事です 🎄 :::
本記事では、GitHub Actions 利用時における、PR の差分に基づくジョブの選択実行と、PR マージ時の必須ジョブ設定を両立させる方法について紹介します。
通常、PR の差分に基づいてジョブを選択実行する際は、paths
や paths-ignore
フィルターが利用されます。
一方でこの方法では、PR マージ時の必須ジョブ設定と競合を起こしてしまうことがあります。
以下では、この問題の回避策を紹介します。
paths
や paths-ignore
フィルターの代わりに、Changed Files アクションを利用します。
https://github.com/marketplace/actions/changed-files
Changed Files アクションにてファイル差分を確認し、チェックジョブの影響範囲内のファイルが含まれていた場合は、if
構文によりチェックジョブを実行します。
一方で、チェックジョブの影響範囲内のファイルが含まれていなかった場合は、同じく if
構文により何もしないというジョブを実行します。
さらに、PR マージ時の必須ジョブ設定では、上記のチェックジョブと何もしないジョブを両方とも必須として設定します。
これにより、不要なチェック実行を避けつつ、必要なステータスチェックを確実に行うことが可能になります。
:::message 以下では背景となる課題をより詳細に記載します。回避策を確認したい場合は、次の章まで読み飛ばしてください。 :::
GitHub Actions では、paths
や paths-ignore
フィルターを使って、PR の差分に応じてワークフローを実行するかどうかを選択できます。
この機能により、影響を受けないワークフローやジョブをスキップし、GitHub Actions の実行時間とコストを削減できます。
また、「ステータスチェック必須」設定を用いて、特定のワークフローやジョブの完了を PR のマージ条件に設定できます。
この機能により、安全な開発プロセスを確保できます。
しかし、paths
フィルターや paths-ignore
フィルターを利用すると、スキップされたチェックジョブが「待機状態」となり、GitHub が「マージ不可」と判断する問題が生じます。
例えば、以下のように Test API
というジョブを PR のマージ条件に設定します。
この状況下で、paths
フィルターや paths-ignore
フィルターにより Test API
ジョブがスキップされると、必要なチェックステータスが待機状態のままとなりマージがブロックされます。
以下では具体的な回避策を紹介します。
たとえば、以下のような Python のテスト実行 CI が設定されているとします。
name: CI / API
on:
pull_request:
branches:
- "main"
paths:
- "functions/**"
jobs:
test:
name: Test API
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Test
run: pytest
ここで、paths
フィルターを削除し、変更があるかどうかを判定する check-impact
ジョブを追加します。
on:
pull_request:
branches:
- "main"
- paths:
- - "functions/**"
jobs:
+ check-impact:
+ name: Check impact
+ runs-on: ubuntu-latest
+ outputs:
+ has-changed-related-files: ${{ steps.check-related-files.outputs.any_changed == 'true' }}
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Check related files
+ id: check-related-files
+ uses: tj-actions/changed-files@v40
+ with:
+ files: "functions/**"
# ...
if
構文を用いて、関連ファイルに変更がある場合のみテストジョブを実行し、そうでない場合は何もしない Test API (no need)
ジョブを実行します。
test:
# ...
name: Test API
+ needs: check-impact
+ if: needs.check-impact.outputs.has-changed-related-files == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Test
run: pytest
+ test-no-need:
+ name: Test API (no need)
+ needs: check-impact
+ if: needs.check-impact.outputs.has-changed-related-files == 'false'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Skip
+ run: echo "No changes in files related to API, skipping."
リポジトリの設定で、2 つのジョブを両方必須として設定します。
以上の設定により、functions/**
の差分に関わらず、必要なチェックが適切に記録され、PR のマージが安全に行えるようになります。