🦾
GitHub Actionsを整理するためのパターンを考える
GitHub Actionsはひとつのyamlファイルから書き始めることができますが, 複数のWorkflowやJobを書こうとすると途端に重複部分が増えてきます.
例えば
- マージ時とプッシュ時でビルドとテストをするところはまでは同じだが, マージ時にはリリース処理をしたい
- Jobを分けたいが毎回同じようなセットアップをする必要がある
- 並列して確認できる部分(例えばtest実行とlint実行)はなるべく並列にしたい. 直列だと片方が失敗したときにもう片方が実行されず結果が出ない
こうした要求を実現しつつ, コードの重複を減らして整理するための自分なりの書き方パターンがあるので, ここではその方法をまとめておきます.
まとめ
- 単一Workflowと複合Workflowとの2つに役割を分ける
- 単一Workflowの役割
- workflow_callからのみ呼び出される
- ビルドやテスト, リリース処理などの単位でひとつ作成する
- 複合Workflowの役割
- on pushやon scheduleなどの外部からのトリガーによって呼び出される
- 複数の単一WorkflowをJobとして組み合わせて並べる
- 例: プッシュ時テストではビルド→テスト
- 例: マージ時リリースではビルド→テスト→リリース
- 単一Workflowの役割
- キャッシュを利用して成果物を複数のJob間でやり取りする
- composite action を活用する
サンプル
composite action
共通のセットアップを行うアクションの例
name: common-setup
description: |
action for common setup of node/pnpm/bun
inputs:
NODE_VERSION:
description: ''
required: false
default: '20'
PNPM_VERSION:
description: ''
required: false
default: '8'
BUN_VERSION:
description: ''
required: false
default: '1'
REQUIRE_BUN:
description: ''
required: false
default: 'true'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.NODE_VERSION }}
- uses: pnpm/action-setup@v3
with:
version: ${{ inputs.PNPM_VERSION }}
run_install: false
- uses: oven-sh/setup-bun@v1
if: inputs.REQUIRE_BUN == 'true'
with:
bun-version: ${{ inputs.BUN_VERSION }}
単一Workflow
name: _install-pnpm-deps
on:
workflow_call:
inputs:
use-pnpm-store-cache:
type: boolean
required: false
default: true
jobs:
cache-and-install:
runs-on: ubuntu-latest
timeout-minutes: 1
env:
PNPM_STORE_PATH: ''
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/common-setup
with:
REQUIRE_BUN: 'false'
- uses: ./.github/actions/restore-pnpm-store-cache
id: restore-pnpm-store-cache
if: inputs.use-pnpm-store-cache == true
- run: pnpm install
if: steps.restore-pnpm-store-cache.outputs.cache-hit != 'true'
- name: Get pnpm store directory
run: echo "PNPM_STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Save pnpm-store cache
uses: actions/cache/save@v4
if: steps.restore-pnpm-store-cache.outputs.cache-hit != 'true'
with:
path: ${{ env.PNPM_STORE_PATH }}
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
複合Workflow
name: Build🔨, Verify🧪 on push
on:
push:
jobs:
install-pnpm-deps:
uses: ./.github/workflows/_install-pnpm-deps.yaml
build-uniproc:
needs: install-pnpm-deps
uses: ./.github/workflows/_build-uniproc.yaml
build-sveltecf:
needs:
- install-pnpm-deps
- build-uniproc
uses: ./.github/workflows/_build-sveltecf.yaml
verify-uniproc:
needs: build-uniproc
uses: ./.github/workflows/_verify-uniproc.yaml
verify-sveltecf:
needs: build-sveltecf
uses: ./.github/workflows/_verify-sveltecf.yaml
実行結果
失敗を含む場合
全件成功の場合
ディレクトリ構成
補足
上記のまとめとサンプルを読んでいただければ大体の雰囲気は把握できるかと思います.
いくつか補足をしておきます.
- 単一Workflow→複合Workflowの順番で書く. 書き進めていって共通部分が気になってきたらcomposite actionに切り出す
- composite actionの構文: Metadata syntax for GitHub Actions - GitHub Docs
-
キャッシュを頻繁に使っているためprivate repository等ではGitHub Storageの使用量に注意
- 1GB/月までは無料で使えるが, 思いのほかキャッシュの容量が大きくなることがある
- 単一Workflowのファイル名を
_
で始めることで, 複合Workflowと区別しやすくしている
References
-
GitHub ActionsにおけるStep/Job/Workflow設計論
- Step/Job/Workflowのそれぞれの仕様, 特徴, 使い分けについて
-
ジョブを細かく分けてGitHub Actionsのテストを効率化する
- キャッシュを用いたテスト効率化について
- Creating a composite action - GitHub Docs
Discussion