意外と参考になる資料が見つからなかったので投稿します。
GitHub Actionsのステップの実行結果による分岐についてです。
やりたいこと
- ステップの実行結果によってその先の実行内容を切り替えたい
-
StepA
が成功だった場合、StepB
を実行する -
StepA
が失敗だった場合、StepC
を実行する - ジョブの実行結果に
StepA
の実行結果を反映させない
-
- Ansibleで言うところの
when
のようなことをしたい
やりたいこと(私が詳しく調べたきっかけ)
シェルコマンドの結果によって処理を分岐させたかった。
具体的にcurl http://example.com/list | grep "hoge"
によって"hoge"が見つかった時、途中のステップを実行したくなかった。
やろうとした時に困ったこと
- ステップの実行結果による分岐の資料が意外と見つからなかった
- ジョブの方は見つかった
- 公式ドキュメントのページ内リンクが間違っていて、目的の情報に辿り着きにくかった
- 2021-07-18時点
- 当該記事: GitHub Actions のコンテキストおよび式の構文
- 例えば#steps-contextにアクセスすると
needsコンテキスト
が表示されてしまう
- 例えば#steps-contextにアクセスすると
サンプル
- サンプルリポジトリ(GitHub)
-
check somethingが成功した時のAction実行結果
-
something when command failure
が実行されていないのがポイント
-
-
check somethingが失敗した時のAction実行結果
-
something when command success
が実行されていないのがポイント
-
name: sample-action
on: workflow_dispatch
jobs:
something-job:
runs-on: ubuntu-latest
steps:
- name: check something
id: check_something
run: exit `echo $(($RANDOM % 2))`
continue-on-error: true
- name: output step context
run: echo $CONTEXT
env:
CONTEXT: ${{ toJSON(steps.check_something) }}
- name: something when command success
run: echo "result - success"
if: steps.check_something.outcome == 'success'
- name: something when command failure
run: echo "result - failure"
if: steps.check_something.outcome == 'failure'
解説
ポイントとなる記述を解説します。
id: check_something
ステップの実行結果を後続ステップで参照するためにidを付与します。
run: exit `echo $(($RANDOM % 2))`
終了コードを乱数で決定します(0または1)。
これによって「check something
の結果がランダムで成功したり、失敗したり」となるようにします。
continue-on-error: true
このステップ(check something
)の実行結果がエラーとして扱われないようにします。
CONTEXT: ${{ toJSON(steps.check_something) }}
デバッグ用の記述です。
これによってsteps.check_something
の中身を確認することができます。
if: steps.check_something.outcome == 'success'
check_something
が成功した場合にのみ、このステップが実行されるようにします。
if: steps.check_something.outcome == 'failure'
同上です。
ジョブの実行結果による分岐
ステップでなくジョブによる分岐は参考記事がたくさんあるので、ここでは詳しく扱いません。
ジョブの場合はif: success()
やif: failure()
によって分岐させる点がポイントです。
例えば、以下の記事がわかりやすかったです。
GitHub Actionsでビルドの成功・失敗をSlackに通知する方法(Qiita)
分岐処理が大きい場合は別スクリプト化
GitHubActionsやその他CIに複雑な処理を書くべきではないと思っています。
保守・管理が難しくなってしまうためです。
その場合は専用のスクリプトに分離していくことをオススメしたいです。