Github Actionsには、Status check functions
という仕組みがあり、
これを使うことで、job・stepの実行を制御できる。
Status check functions
は、以下の4種類存在する。
- success()
- failure()
- always()
- cancelled()
これらについて、いまいち理解できていない部分もあるので、
改めて一通り確認してみる。
Status check functionsについて
success()
前に実行されたstepsが成功した場合にtrue
になる。
jobs:
# success:true
success-job:
runs-on: ubuntu-latest
steps:
- name: success
run: exit 0
- name: if success execute
# 前のjobが成功(exit 0)しているので、以下jobは実行される
if: success()
run: echo 'in success'
# success:false
failure-job:
runs-on: ubuntu-latest
steps:
- name: failure
run: exit 1
- name: if success execute
# 前のjobが失敗(exit 1)しているので、以下jobも実行されない
if: success()
run: echo 'in success'
実は、デフォルトでsuccess()
は適用されているので、
if: success()
は無くても同じ。
failure()
前に実行されたstepsが失敗した場合にtrue
になる。
jobs:
# failure:true
failure-job:
runs-on: ubuntu-latest
steps:
- name: failure
run: exit 1
- name: if failure execute
# 前のjobが失敗(exit 1)しているので、以下jobも実行される
if: failure()
run: echo 'in failure'
# failure:false
success-job:
runs-on: ubuntu-latest
steps:
- name: success
run: exit 0
- name: if failure execute
# 前のjobが成功(exit 0)しているので、以下jobは実行されない
if: failure()
run: echo 'in failure'
always()
前jobの成否に関わらずtrueとなる。
jobs:
# always
success-job-for-always:
runs-on: ubuntu-latest
steps:
- name: success
run: exit 0
- name: always execute
# 前jobの成否に関係無いので、実行される
if: always()
run: echo 'in always'
# always
failure-job-for-always:
runs-on: ubuntu-latest
steps:
- name: failure
run: exit 1
- name: always execute
# 前jobの成否に関係無いので、実行される
if: always()
run: echo 'in always'
なので、前jobが失敗していても実行したい場合に使う。
しかし、以下の通り場合によっては代わりにif: ${{ !cancelled() }}
を使うことが推奨される。
Warning: Avoid using
引用元:https://docs.github.com/en/actions/learn-github-actions/expressions#alwaysalways
for any task that could suffer from a critical failure, for example: getting sources, otherwise the workflow may hang until it times out. If you want to run a job or step regardless of its success or failure, use the recommended alternative:if: ${{ !cancelled() }}
これについては、最後に改めて確認する。
cancelled()
workflowがキャンセルされた時にtrueとなる
jobs:
# cancelled
for-canceled:
runs-on: ubuntu-latest
steps:
# テスト用に10秒sleepしている
- name: Wait for 10 seconds
run: sleep 10
# workflowがキャンセルされても、以下は実行される
- name: canceled execute
if: cancelled()
run: echo 'in canceled'
補足)alwaysと${{ !cancelled() }} について
公式documentのalwaysの章で記載されていた以下注意書きについて、
Warning: Avoid using
引用元:https://docs.github.com/en/actions/learn-github-actions/expressions#alwaysalways
for any task that could suffer from a critical failure, for example: getting sources, otherwise the workflow may hang until it times out. If you want to run a job or step regardless of its success or failure, use the recommended alternative:if: ${{ !cancelled() }}
「always
はクリティカルなエラーが生じる可能性のあるタスクには使わないでください。さもないと、ワークフロー自体がタイムアウトするまで実行されます。
job もしくはstepの成否に関わらず実行したい場合には、代わりに if: ${{ !cancelled() }}
を使うことを推奨します。」
みたいなことが書かれています。
実際に動作を確認してみます。
- workflow(必要なところだけ抜粋)
jobs:
for-canceled-1:
runs-on: ubuntu-latest
steps:
- name: canceled execute
if: ${{ !cancelled() }}
run: |
sleep 300
echo 'in not canceled'
for-canceled-2:
runs-on: ubuntu-latest
steps:
- name: canceled execute
if: ${{ always() }}
run: |
sleep 300
echo 'in not canceled'
テスト用のworflowを作成しました。
- for-canceled-1:
${{ !cancelled() }}
を使っています。- worlflow自体がキャンセルされた場合に、jobの実行が停止することを期待しています。
- for-canceled-2:
${{ always() }}
を使っています。- worlflow自体がキャンセルされた場合にも、jobの実行が停止しないことを期待しています。
実行した結果は以下の通りです。
(余計なものも混じっていますが)
workflow開始から30s程でworkflow自体をキャンセルしましたが、以下の通り期待通りの動作となりました。
for-canceled-1
のjob は停止しています。${{ !cancelled() }}
を使っているので、workflowのキャンセル時点でjobが停止しました。
for-canceled-2
のjobは停止していません。${{ always() }}
を使っているので、worflowがキャンセルされてもjobは停止しませんでした。
documentを読んだだけでは、いまいち意味のとりにくいところがありましたが、
実際に動かしてみると理解できました。
まとめ
Status check functions の基本的な所は抑えられました。
このような基本的なところで躓くことは結構あるので、確認できてよかったです。
参考
https://zenn.dev/hsaki/articles/github-actions-componenthttps://docs.github.com/en/actions/learn-github-actions/expressions
https://docs.github.com/en/actions/using-jobs/using-jobs-in-a-workflow
https://qiita.com/abetomo/items/d9ede7dbeeb24f723fc5
https://nju33.com/notes/github-actions/articles/ステータスによるステップの制御#failure
コメント