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 |
|
| matrix.* | Accesses all matrix values as a JSON object | |
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.