この記事は、GitHub Actionsでjobやworkflow同士を連鎖させる方法を記録、共有するためのものです。
この記事は、2021/11/12時点でのGitHubを前提に書かれています。GitHubが更新されると、記事の内容をそのまま適用できないことがあります。ご注意ください。
この記事ではgitの使い方やGitHubの導入方法などは取り扱いません。ご承知ください。
GitHub Actionsとは、GitHubが提供するCI/CD環境です。リポジトリへのPushやPull requestの作成、Issueへのコメントなどさまざまなイベントを引き金としてコンテナーが立ち上がり、指定された命令を処理します。
利用ケースとして
などがあります。
GitHub Actionsのアクションは、以下のような粒度で管理されています。(公式ドキュメント)
アクションの最小単位です。シェルコマンド1行に相当します。
複数のステップで構成された処理です。ジョブ同士は並列処理されます。
複数のジョブで構成され、イベントを引き金として実行される処理の塊です。1つのワークフローは1つのYAMLファイルに記述されます。
ワークフローファイルは.github/workflows
というディレクトリに保存され、このファイル自体もgitでバージョン管理されます。
複雑なワークフローを構成すると、ワークフローファイルが肥大化して管理が難しくなっていきます。そのためジョブを分割したり、相互に関連しないジョブを別々のワークフローに切り分けなければいけません。
GitHub Actionsには、ワークフローやジョブの分割のための連鎖機能があります。この連鎖機能を使えば「テストが成功し、デフォルトブランチにマージされたら、APIドキュメントを更新してGitHub Pagesで公開し、npmでパッケージを公開する」といった複雑な処理を管理しやすくなります。
GitHub Actionsでは、依存ジョブとworkflow_runトリガーの2種類の連鎖機能が提供されています。
GitHub Actionsのジョブはデフォルトでは並列で実行されます。依存ジョブにneedsフィールドを設定すると、指定した他ジョブの完了を待ちます。
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: ./build_server.sh
test:
needs: build
^^^^^^^^^^^^ ここが依存ジョブの設定
runs-on: ubuntu-latest
steps:
- run: ./test_server.sh
上記の例ではbuildジョブが成功したら、testジョブが実行されます。buildジョブが失敗したらtestジョブは実行されずに中断されます。
依存ジョブは並列実行されないため、ワークフロー全体の処理時間は長くなります。後続の処理が中断される利点と、処理時間が長くなる欠点を比べて設定してください。
workflow_runトリガーを使うと、前ワークフローの完了を引き金に次のワークフローが開始されます。
on:
workflow_run:
workflows: ["Run Tests"]
branches: [main]
types:
- completed
上記の例ではRun Tests
という名前のワークフローが、mainブランチで完了したときに処理が始まります。
なお、workflow_runトリガー単体では、前ワークフローの処理が成功したか失敗したかをチェックできません。前ワークフローが成功したか否かを確認するにはコンテキストgithub.event.workflow_run
を確認します。このコンテキストには前ワークフローの情報が格納されています。
on:
workflow_run:
workflows: ["Build"]
types: [completed]
jobs:
on-success:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
...
たとえばgithub.event.workflow_run.conclusion
には前ワークフローの成否が格納されています。
処理を分割することで、再利用しやすく可読性の高いワークフローを作れます。お手元の環境で複雑すぎるワークフローがある場合、ぜひ分割を検討してみてください。 以上、ありがとうございました。