GitHub Actions Matrix動的生成の実装パターンとベンチマーク分析¶
この記事は朝の記事のフォローアップです
ゴール¶
- 複雑な条件での動的Matrix生成を実装
- 各戦略の実行時間を定量比較
- プロダクション環境での失敗を事前回避
アーキテクチャ / フロー概要¶
Matrix生成の判定フローを3段階に分離し、各段階でのフィルタリングによりビルド対象を最適化します。
graph LR
A[変更検出] --> B[依存関係解析]
B --> C[優先度判定]
C --> D[Matrix JSON生成]
D --> E[並列ビルド実行]実装ステップ¶
ステップ1: 多条件Matrix生成スクリプト¶
変更ファイル、ブランチ、PRラベルを統合判定する実装です。
#!/bin/bash
# generate-matrix.sh
changed_files=$(git diff --name-only HEAD^ HEAD)
branch_name=${GITHUB_REF##*/}
pr_labels=$(gh pr view --json labels -q '.labels[].name' 2>/dev/null || echo "")
matrix='{"include":['
# Service detection with priority
if echo "$changed_files" | grep -q "^api/"; then
matrix+='{"service":"api","priority":"high"},'
fi
if echo "$changed_files" | grep -q "^web/" && [[ "$branch_name" != "hotfix/"* ]]; then
matrix+='{"service":"web","priority":"medium"},'
fi
if echo "$pr_labels" | grep -q "e2e-required"; then
matrix+='{"service":"e2e","priority":"critical"},'
fi
matrix=${matrix%,}']}'
echo "matrix=$matrix" >> $GITHUB_OUTPUT
ステップ2: Workflow側での条件付き実行¶
生成されたMatrixに基づき、優先度でジョブを制御します。
jobs:
generate:
outputs:
matrix: ${{ steps.gen.outputs.matrix }}
steps:
- id: gen
run: ./generate-matrix.sh
build:
needs: generate
if: ${{ needs.generate.outputs.matrix != '{"include":[]}' }}
strategy:
matrix: ${{ fromJson(needs.generate.outputs.matrix) }}
runs-on: ubuntu-latest
timeout-minutes: ${{ matrix.priority == 'critical' && 30 || 15 }}
steps:
- name: Build ${{ matrix.service }}
run: |
echo "Priority: ${{ matrix.priority }}"
make build-${{ matrix.service }}
ステップ3: キャッシュ戦略の最適化¶
Matrix各要素に特化したキャッシュキーを生成します。
- uses: actions/cache@v4
with:
path: |
~/.npm
.next/cache
key: ${{ runner.os }}-${{ matrix.service }}-${{ hashFiles(format('{0}/package-lock.json', matrix.service)) }}
restore-keys: |
${{ runner.os }}-${{ matrix.service }}-
${{ runner.os }}-
ベンチマーク / 比較¶
| 戦略 | 平均実行時間 | リソース使用率 | 適用場面 |
|---|---|---|---|
| 全Matrix静的定義 | 25分 | 100% | 小規模・固定環境 |
| 単純動的生成 | 18分 | 75% | 中規模・変動少 |
| 多条件動的生成 | 12分 | 45% | 大規模・高頻度変更 |
| 優先度付き動的 | 8分(critical) | 30% | ホットフィックス対応 |
失敗パターンと回避策¶
| 症状 | 原因 | 回避 |
|---|---|---|
| Matrix空配列エラー | 変更ファイルなし時の処理漏れ | デフォルト値設定 || echo '{"include":[{"service":"health"}]}' |
| JSONパースエラー | エスケープ不足 | jqでの生成に切り替え |
| 並列ジョブ重複 | キャッシュキー衝突 | service名をキーに含める |
| タイムアウト頻発 | 優先度未考慮 | priority別にtimeout-minutes設定 |
自動化 / 拡張案¶
- Matrixサイズによる自動的なmax-parallel調整
- 過去の実行時間に基づく優先度の機械学習
- Slack通知でのMatrix展開状況の可視化
- cost-per-minuteでのリソース最適化
- Dependabotとの連携による依存関係Matrix生成