Skip to main content

Implementing Matrix Strategies

1. Defining Matrix Strategy

Property Description Values Notes
strategy.matrix Defines the matrix strategy for job execution {} Used to run a job multiple times with different variable combinations
strategy.matrix.include Additional configurations to include in the matrix [] Allows adding extra job configurations beyond the defined matrix
strategy.matrix.exclude Configurations to exclude from the matrix [] Allows filtering out specific job configurations from the matrix
strategy.max-parallel Maximum number of jobs to run in parallel number Defaults to 4; can be set to any positive integer
strategy.fail-fast Whether to fail the job if any matrix job fails true or false Defaults to true; set to false to continue running other matrix jobs even if one fails

Example: Basic Matrix Strategy

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [12, 14, 16]
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci

Example: Matrix Strategy with Include

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [12, 14, 16]
        include:
          - os: macos-latest
            node-version: 16
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci

2. Using Matrix Variables

Variable Description Usage
matrix.os Operating system for the job runs-on: ${{ matrix.os }}
matrix.node-version Node.js version to use node-version: ${{ matrix.node-version }}
matrix.include Additional configurations to include include: ${{ matrix.include }}
matrix.exclude Configurations to exclude exclude: ${{ matrix.exclude }}

Example: Using Matrix Variables in a Workflow

name: Matrix Example
on: [push]
jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [14, 16, 18]
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
Note: Matrix variables can be used to run jobs in parallel across different configurations, optimizing build and test times.

3. Including Matrix Combinations

Option Values Description
matrix os: [ubuntu-latest, macos-latest] Defines the matrix strategy for jobs
include os: [windows-latest], node-version: [18.x] Additional combinations to include in the matrix

Example: Matrix with Include

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        node-version: [12.x, 14.x]
        include:
          - os: windows-latest
            node-version: 18.x
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

4. Excluding Matrix Combinations

Option Values Notes
exclude object Defines combinations to exclude from the matrix

Example: Using exclude to filter matrix combinations

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [14, 16, 18]
        exclude:
          - os: windows-latest
            node-version: 14
    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 }}
Note: The exclude option allows you to remove specific combinations from the matrix, which is useful for avoiding incompatible configurations.

5. Setting Fail-Fast Behavior

Fail-fast behavior in GitHub Actions determines whether a workflow should stop executing when a job fails. By default, workflows continue running jobs even if one job in a matrix fails.

Option Values Description
fail-fast true or false Determines if the workflow stops when a job in the matrix fails. Default is true.

Example: Configuring fail-fast in a matrix job

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [14, 16, 18]
      fail-fast: false
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
Note: Setting fail-fast: false allows all matrix jobs to complete even if one fails, which is useful for debugging or collecting all test results before failing the workflow.

6. Setting Max Parallel Jobs

Property Values Description
jobs.<job_id>.strategy.max-parallel number Maximum number of jobs to run in parallel. Defaults to 4.

Example: Configuring max-parallel

jobs:
  build:
    strategy:
      max-parallel: 2
    steps:
      - name: Build
        run: echo "Building..."
Note: Setting max-parallel to null or omitting it will use the default of 4 parallel jobs.

7. Using Dynamic Matrix

Example: Dynamic matrix with environment variables

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14, 16, 18]
        os: [ubuntu-latest, windows-latest]
    steps:
      - name: Set up Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install dependencies
        run: npm install
      - name: Run tests
        run: npm test
        env:
          OS_TYPE: ${{ matrix.os }}
Property Description Values
strategy.matrix Defines the matrix strategy for jobs object
strategy.matrix.include Additional matrix configurations to include array
strategy.matrix.exclude Matrix configurations to exclude array
Note: The include and exclude keys allow for more granular control over matrix builds.

Example: Using include to add a specific configuration

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14, 16, 18]
        os: [ubuntu-latest, windows-latest]
        include:
          - node-version: 20
            os: macos-latest
            test-env: production

Example: Using exclude to skip a configuration

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14, 16, 18]
        os: [ubuntu-latest, windows-latest]
        exclude:
          - node-version: 14
            os: windows-latest

8. Accessing Matrix Values

Property Description Usage
matrix.foo Accesses the value of the matrix axis foo
env:
  FOO_VALUE: ${{ matrix.foo }}
matrix.* Accesses all matrix values as a JSON object
env:
  MATRIX_JSON: ${{ matrix }}

Example: Using matrix values in a job

jobs:
  build:
    strategy:
      matrix:
        node-version: [12, 14, 16]
    steps:
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

9. Naming Matrix Jobs

Property Description Example
job.name Name of the job, can include matrix variables build-${{ matrix.os }}-${{ matrix.node-version }}
matrix Defines the matrix configuration { os: ['ubuntu-latest', 'windows-latest'], node-version: ['14', '16'] }

Example: Naming Matrix Jobs

jobs:
  build:
    name: Build on ${{ matrix.os }} with Node ${{ matrix.node-version }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [14, 16]
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

10. Combining Multiple Matrices

Matrix Values Description
os ubuntu-latest, macOS-latest, windows-latest Operating systems to run jobs on
node-version 18.x, 20.x, 22.x Node.js versions to test against
architecture x64, arm64 Processor architectures to test on

Example: Combining Multiple Matrices

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macOS-latest, windows-latest]
        node-version: [18.x, 20.x, 22.x]
        architecture: [x64, arm64]
    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 }}
          architecture: ${{ matrix.architecture }}
Note: The total number of jobs will be the product of all matrix dimensions (e.g., 3 OS × 3 Node versions × 2 architectures = 18 jobs).

11. Using Matrix with Outputs

Property Description Values
matrix Defines the matrix strategy for jobs { version: ['14', '16', '18'], os: ['ubuntu-latest', 'windows-latest'] }
outputs Defines outputs to pass between jobs or steps { matrix-version: ${{ matrix.version }} }

Example: Matrix with Outputs

jobs:
  build:
    strategy:
      matrix:
        version: [14, 16, 18]
        os: [ubuntu-latest, windows-latest]
    outputs:
      matrix-version: ${{ matrix.version }}
      matrix-os: ${{ matrix.os }}
    steps:
      - name: Build
        run: echo "Building with Node.js ${{ matrix.version }} on ${{ matrix.os }}"

12. Testing Across OS and Versions

Operating System Version Notes
ubuntu-latest 22.04 Latest Ubuntu LTS version
ubuntu-20.04 20.04 Ubuntu 20.04 LTS
ubuntu-18.04 18.04 Ubuntu 18.04 LTS (deprecated)
macOS-latest 13 Latest macOS version
macOS-12 12 macOS 12 (Monterey)
windows-latest 2022 Latest Windows Server version
windows-2019 2019 Windows Server 2019

Example: Matrix Strategy for OS and Node.js Versions

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [18.x, 20.x, 22.x]
    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 test
Note: Matrix strategies can significantly increase job runtime. Consider using fail-fast: false to allow all jobs in the matrix to complete even if one fails.

Was this article helpful?