GitHub Actions Matrix Build で並列実行を最大化する3つの実装パターン¶
この記事の対象者
- GitHub Actionsの基本を理解しているDevOpsエンジニア(中級者)
この記事のポイント¶
- Matrix strategyで複数環境を同時テスト
- 動的Matrix生成でビルド対象を自動決定
- fail-fast制御で無駄な実行時間を削減
なぜこの問題が今重要か¶
大規模プロジェクトでCI/CD時間が30分を超える現状。Matrix Buildを適切に活用することで、並列実行により実行時間を60%以上短縮可能。GitHub Actionsの無料枠2000分/月を有効活用。
解決ステップ概要¶
| ステップ | 内容 | 到達指標 |
|---|---|---|
| 1 | 基本Matrix設定 | 3環境並列実行 |
| 2 | 動的Matrix生成 | 変更ファイルのみビルド |
| 3 | 最適化設定 | 実行時間60%短縮 |
ステップ1: 基本Matrix設定による並列テスト¶
複数のNode.js/Pythonバージョンや異なるOSで同時にテストを実行します。
name: Matrix Build
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20, 22]
exclude:
- os: macos-latest
node: 18
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
この設定により、5つの組み合わせ(Ubuntu×3 + macOS×2)が並列実行されます。
ステップ2: 動的Matrix生成で効率化¶
変更されたファイルに基づいて、必要なビルドのみを実行します。
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- id: set-matrix
run: |
if git diff --name-only HEAD^ | grep -q "frontend/"; then
echo "matrix={\"app\":[\"frontend\"]}" >> $GITHUB_OUTPUT
elif git diff --name-only HEAD^ | grep -q "backend/"; then
echo "matrix={\"app\":[\"backend\"]}" >> $GITHUB_OUTPUT
else
echo "matrix={\"app\":[\"frontend\",\"backend\"]}" >> $GITHUB_OUTPUT
fi
build:
needs: prepare
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
- run: echo "Building ${{ matrix.app }}"
ステップ3: fail-fast と max-parallel で最適化¶
エラー時の即座停止と並列数制御により、リソース消費を最小化します。
strategy:
fail-fast: true # 1つでも失敗したら全て停止
max-parallel: 4 # 同時実行数を制限
matrix:
python: [3.9, 3.10, 3.11, 3.12]
test-group: [unit, integration, e2e]
よくある落とし穴と対処¶
| 症状 | 原因 | 即時対処 |
|---|---|---|
| Matrix展開エラー | JSON構文エラー | fromJson()前にecho確認 |
| 並列数超過で待機 | max-parallel未設定 | 上限を2-4に設定 |
| 不要な組み合わせ実行 | exclude未使用 | 明示的に除外指定 |
詳細設定(高度最適化)
### キャッシュと組み合わせた高速化- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }}
matrix:
include:
- os: ubuntu-latest
node: 20
run-e2e: true
- os: windows-latest
node: 20
run-e2e: false