2025年02月05日 更新

Github Actionsでステップ実行失敗時のエラーハンドリングをする方法

どうも、クラゲジュニアです。

FTPサーバーなどへのファイルのデプロイなど、状況によってGithub Actionsでステップの実行が失敗してしまう場合に復旧処理などを走らせたいときがありますよね。

今回はGithub Actions上でプログラミングでいうtry~catchのようにエラー発生時に処理を実行する方法を試してみます。

環境

クラゲジュニアは下記のローカル環境で実施しました。

  • Windows 11 pro 24H2
  • act version 0.2.63

actとはGithub Actionsをローカル実行できるものです。詳細はこちらを参照してください。

https://github.com/nektos/act

方法

下記のyamlファイルを用意しました。10行目のexit 1によって意図的にfail-stepステップでエラーを引き起こしています。

on: push
name: check failure run
jobs:
  failure-test:
    name: check-failure
    runs-on: ubuntu-latest
    steps:
    - name: fail-step
      id: fail_step
      run: exit 1

    - name: failure-notification
      if: failure() && steps.fail_step.outcome == 'failure'
      run: echo "Oops, something went wrong!"

ポイントはfailure-notificationステップの13行目で、下記のようにidを書き換えれば任意のステップのエラーハンドリングが可能です。

if: failure() && steps.<エラーハンドリングするステップのid>.outcome

実行

act -W test.ymlを実行すると、Oops, something went wrong!が表示されていることがわかります。

act -W test.yml
time="2025-01-07T10:21:34+09:00" level=info msg="Using docker host 'npipe:////./pipe/docker_engine', and daemon socket 'npipe:////./pipe/docker_engine'"
[check failure run/check-failure] 🚀  Start image=catthehacker/ubuntu:act-latest
[check failure run/check-failure]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
[check failure run/check-failure]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[check failure run/check-failure]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[check failure run/check-failure] ⭐ Run Main fail-step
[check failure run/check-failure]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/fail_step] user= workdir=
[check failure run/check-failure]   ❌  Failure - Main fail-step
[check failure run/check-failure] exitcode '1': failure
[check failure run/check-failure] ⭐ Run Main failure-notification
[check failure run/check-failure]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/1] user= workdir=
| Oops, something went wrong!
[check failure run/check-failure]   ✅  Success - Main failure-notification
[check failure run/check-failure] 🏁  Job failed
Error: Job 'check-failure' failed

また、exit 0に書き換えて正常終了させるとOops, something went wrong!が表示されておらず、あくまでもエラー発生時のみ実行されていることがわかります。

act -W test.yml
time="2025-01-07T10:23:52+09:00" level=info msg="Using docker host 'npipe:////./pipe/docker_engine', and daemon socket 'npipe:////./pipe/docker_engine'"
[check failure run/check-failure] 🚀  Start image=catthehacker/ubuntu:act-latest
[check failure run/check-failure]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
[check failure run/check-failure]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[check failure run/check-failure]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[check failure run/check-failure] ⭐ Run Main fail-step
[check failure run/check-failure]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/fail_step] user= workdir=
[check failure run/check-failure]   ✅  Success - Main fail-step
[check failure run/check-failure] Cleaning up container for job check-failure
[check failure run/check-failure] 🏁  Job succeeded

以上です。