MENU

[Github Actions]Status check functions まとめ

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 always 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() }}

引用元:https://docs.github.com/en/actions/learn-github-actions/expressions#always

これについては、最後に改めて確認する。

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 always 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() }}

引用元:https://docs.github.com/en/actions/learn-github-actions/expressions#always

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

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次