GitHubActions で複数の Job で構成される Workflow はよくあるパターンかと思いますが、途中で並列しており、その全ての Job が成功しているか否かの評価を Workflow の一番最後でしたいユースケースがあり、そのときのサンプルを記事として残しておきます。
このときは Pull Request のステータスチェックの対象 Job として設定するために作成しました。他にもユースケースはありそうですね。
name: Result check sample
on:
push:
branches:
- "test/**"
jobs:
initial:
runs-on: ubuntu-latest
steps:
- run: echo "initial done!"
parallel1:
needs: [initial]
runs-on: ubuntu-latest
steps:
- run: echo "parallel1 done!"
parallel2:
needs: [initial]
runs-on: ubuntu-latest
steps:
- run: echo "parallel2 done!"
result-check:
needs: [parallel1, parallel2]
runs-on: ubuntu-latest
if: always()
steps:
- name: Failure
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: |
echo "Failure"
exit 1
- name: Success
run: echo "Success"
評価を行う Job
一番最後の result-check の Job が評価を行います。
核心部は if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
です。
Workflow を構成する Job である initial, parallel1, parallel2 のどこかでエラーまたはキャンセル操作が発生した場合、結果は Failure
となりエラー終了、全てが成功していると Success
となり正常終了となります。
この Job は前の Job の成否に関わらず、この Job が必ず実行されるようになっています。
needs.*.result の評価
needs.*.result
は、すべての依存しているステップの result プロパティを一覧として取得します。
上記のサンプルでは、needs.*.result
は [ initialの結果, parallel1の結果, parallel2の結果 ] というリストになります。
contains(needs.*.result, 'failure') の評価
contains(needs.*.result, 'failure')
は、リスト needs.*.result
の中に failure
が含まれているかどうかを確認します。
依存するステップのうち1つでも failure
になっていれば、 contains 関数は true
を返します。
もし、依存ステップのすべてが success
ならば、この式は false
になります。