LESSON 30分

マトリクスビルドと並列実行

ストーリー

「うちのアプリはNode.js 18と20の両方をサポートしている。 テストも両方のバージョンで走らせたい」

木村先輩がワークフローファイルを開いた。

「普通に書くと、Node 18用とNode 20用で2つのジョブを コピペすることになる。でもGitHub Actionsにはmatrix戦略がある。 これを使えば、1つのジョブ定義で複数の組み合わせを自動生成できる」

「組み合わせ......ですか?」

「Node.jsバージョン × OS × データベースの組み合わせを マトリクスで定義して、全パターンを並列実行できるんだ」


マトリクス戦略とは

マトリクス戦略(matrix strategy)は、1つのジョブ定義から複数のバリエーションを自動生成して並列実行する機能です。

マトリクス戦略のイメージ

ジョブ定義 × マトリクス → 複数ジョブを自動生成

matrix:
  node: [18, 20]
  os: [ubuntu, macos]

→ 4つのジョブが自動生成:
  ┌─────────────┬────────────┐
  │             │ Node 18    │ Node 20    │
  ├─────────────┼────────────┤
  │ ubuntu      │ Job 1      │ Job 2      │
  │ macos       │ Job 3      │ Job 4      │
  └─────────────┴────────────┘

  全て並列実行!

基本的なマトリクス定義

Node.jsバージョンのマトリクス

yaml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test

この定義から3つのジョブが並列実行されます:

  • Node.js 18 でテスト
  • Node.js 20 でテスト
  • Node.js 22 でテスト

OS × Node.js のマトリクス

yaml
jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [18, 20]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

これで 3 OS x 2 Node.js = 6 ジョブが並列実行されます。


マトリクスの詳細設定

include: 追加の組み合わせ

yaml
strategy:
  matrix:
    node-version: [18, 20]
    os: [ubuntu-latest]
    include:
      # 特定の組み合わせを追加
      - node-version: 20
        os: macos-latest
        experimental: true

exclude: 除外する組み合わせ

yaml
strategy:
  matrix:
    os: [ubuntu-latest, macos-latest, windows-latest]
    node-version: [18, 20]
    exclude:
      # Windows + Node 18 の組み合わせは除外
      - os: windows-latest
        node-version: 18

fail-fast: 失敗時の挙動

yaml
strategy:
  fail-fast: false        # 1つ失敗しても他を止めない(デフォルトはtrue)
  matrix:
    node-version: [18, 20, 22]
設定挙動
fail-fast: true(デフォルト)1つのジョブが失敗したら他も全てキャンセル
fail-fast: false失敗しても他のジョブは最後まで実行

max-parallel: 並列数の制限

yaml
strategy:
  max-parallel: 2         # 同時実行数を2に制限
  matrix:
    node-version: [18, 20, 22]

実践的なマトリクスパターン

パターン1: マルチDB対応テスト

yaml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        database: [postgres, mysql]
        include:
          - database: postgres
            db_image: postgres:16
            db_port: 5432
            db_url: postgresql://test:test@localhost:5432/test
          - database: mysql
            db_image: mysql:8
            db_port: 3306
            db_url: mysql://test:test@localhost:3306/test

    services:
      db:
        image: ${{ matrix.db_image }}
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: test
          MYSQL_ROOT_PASSWORD: test
          MYSQL_DATABASE: test
          MYSQL_USER: test
          MYSQL_PASSWORD: test
        ports:
          - ${{ matrix.db_port }}:${{ matrix.db_port }}

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - name: Run tests against ${{ matrix.database }}
        env:
          DATABASE_URL: ${{ matrix.db_url }}
        run: npm test

パターン2: テストの分割並列実行

大量のテストを分割して並列実行するパターンです。

yaml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - name: Run test shard ${{ matrix.shard }}/4
        run: npx jest --shard=${{ matrix.shard }}/4
テスト分割のイメージ

100個のテスト → 4つのシャードに分割

Shard 1: テスト 1〜25   ← 並列実行
Shard 2: テスト 26〜50  ← 並列実行
Shard 3: テスト 51〜75  ← 並列実行
Shard 4: テスト 76〜100 ← 並列実行

結果: テスト実行時間が約1/4に短縮

パターン3: 動的マトリクス

前のジョブの結果からマトリクスを動的に生成するパターンです。

yaml
jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v4
      - id: set-matrix
        run: |
          # 変更があったパッケージを検出
          PACKAGES=$(ls packages/ | jq -R -s -c 'split("\n") | map(select(length > 0))')
          echo "matrix={\"package\":$PACKAGES}" >> $GITHUB_OUTPUT

  test:
    needs: detect-changes
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{ fromJson(needs.detect-changes.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v4
      - run: npm test --workspace=packages/${{ matrix.package }}

マトリクス実行の結果確認

GitHub Actions UI でのマトリクス表示

test (ubuntu-latest, 18)  ✅  2m 34s
test (ubuntu-latest, 20)  ✅  2m 12s
test (ubuntu-latest, 22)  ❌  Fail
test (macos-latest, 18)   ✅  3m 05s
test (macos-latest, 20)   ✅  2m 58s
test (macos-latest, 22)   ✅  3m 22s

→ Node.js 22 + ubuntu の組み合わせで問題があることが一目でわかる

まとめ

ポイント内容
マトリクス戦略1つのジョブ定義から複数バリエーションを自動生成
並列実行全組み合わせが同時に実行され、テスト時間を短縮
include/exclude組み合わせの追加・除外が可能
fail-fastfalseで全パターンを最後まで実行

チェックリスト

  • マトリクス戦略の基本構文を書ける
  • include/exclude で組み合わせを調整できる
  • fail-fast と max-parallel の設定を理解した
  • テスト分割(shard)による並列化パターンを把握した

次のステップへ

次のセクションでは、CI/CDパイプラインにおけるシークレット管理を学びます。 APIキーやパスワードを安全に扱う方法をマスターしましょう。


推定読了時間: 30分