GitHub Actions ワークフロー依存関係の効率的管理術¶
この記事の対象者
- 中級者: GitHub Actions基本を理解し、より複雑なワークフローを構築したい開発者
この記事のポイント¶
needsを使った並列ジョブの依存関係制御workflow_callによる再利用可能ワークフローの設計- 条件付き依存関係による効率的なCI/CDパイプライン構築
なぜこの問題が今重要か¶
複雑化するCI/CDパイプラインで、ビルド時間の増大とワークフローの重複が深刻化。適切な依存関係管理により、実行時間を40-60%短縮可能で、メンテナンスコストも大幅削減。
解決ステップ概要¶
| ステップ | 内容 | 到達指標 |
|---|---|---|
| 1 | needsで順次実行制御 | ジョブが正しい順序で実行 |
| 2 | workflow_callで共通処理分離 | 重複コード削減50%以上 |
| 3 | 条件付き依存で並列化最適化 | 実行時間20-40%短縮 |
ステップ1: needsによる基本的な依存関係制御¶
複数ジョブの実行順序を明確に定義。テスト→ビルド→デプロイの流れを確実に制御します。
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
build:
needs: test
runs-on: ubuntu-latest
steps:
- run: npm run build
deploy:
needs: [test, build]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: npm run deploy
ステップ2: workflow_callで再利用可能ワークフロー構築¶
共通のビルド処理を別ファイルに分離し、複数のワークフローから呼び出し可能に。
.github/workflows/reusable-build.yml:
on:
workflow_call:
inputs:
node-version:
type: string
default: '20'
secrets:
npm-token:
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- run: npm ci
- run: npm run build
メインワークフローから呼び出し:
jobs:
call-build:
uses: ./.github/workflows/reusable-build.yml
with:
node-version: '20'
secrets:
npm-token: ${{ secrets.NPM_TOKEN }}
ステップ3: 条件付き依存関係で並列化最適化¶
if条件とneedsを組み合わせ、不要なジョブをスキップして並列実行を最大化。
jobs:
changes:
runs-on: ubuntu-latest
outputs:
frontend: ${{ steps.filter.outputs.frontend }}
backend: ${{ steps.filter.outputs.backend }}
steps:
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
frontend: 'frontend/**'
backend: 'backend/**'
frontend-test:
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
steps:
- run: cd frontend && npm test
よくある落とし穴と対処¶
| 症状 | 原因 | 即時対処 |
|---|---|---|
| ジョブが開始しない | needsの循環参照 | 依存関係グラフを図式化して確認 |
| 秘密情報エラー | secretsの継承忘れ | secrets: inheritを明示的に指定 |
| 並列実行されない | 不要なneeds指定 | 独立ジョブのneedsを削除 |
詳細設定(高度最適化)
### マトリックス戦略との組み合わせstrategy:
matrix:
node: [18, 20]
jobs:
test:
needs: lint
strategy:
matrix: ${{ fromJson(needs.lint.outputs.matrix) }}