Working with Matrix Jobs
1. Understanding Matrix Jobs
Matrix jobs in CircleCI allow you to run multiple variations of a workflow in parallel, typically to test your code across different environments or configurations.
| Property | Description | Example |
|---|---|---|
| matrix | Defines the matrix configuration to run jobs with different parameters. | { version: 2.1 jobs: test: parameters: os: - linux - macos environment: - name: "OS" - value: <<parameters.os>> steps: - run: echo "Running on <<parameters.os>>"} |
| matrix.expand | Used to expand a matrix job with multiple parameters. | { version: 2.1 jobs: build: parameters: os: - linux - macos node_version: - "12" - "14" steps: - run: echo "Running on <<parameters.os>> with Node <<parameters.node_version>>"} |
Example: Matrix Job Configuration
version: 2.1
jobs:
test:
matrix:
parameters:
os:
- linux
- macos
node_version:
- "12"
- "14"
steps:
- run: echo "Running on <<parameters.os>> with Node <<parameters.node_version>>"
Note: Matrix jobs are particularly useful for testing across multiple operating systems or Node.js versions.
Key Points
- Matrix jobs allow you to run multiple variations of a job in parallel.
- Each variation is defined by a set of parameters (e.g., OS, Node version).
- Matrix jobs can be configured using the
matrixkey in your CircleCI configuration.
2. Defining Matrix Parameters
| Parameter | Description | Values | Notes |
|---|---|---|---|
| matrix | Defines the matrix configuration | { values: [1, 2, 3]} |
Used to define a set of values for parallel execution |
| matrix.values | Array of values to iterate over | [1, 2, 3] |
Each value creates a new job instance |
| matrix.include | Additional job configurations to include in the matrix | [{name: "job1", value: 4}] |
Allows customizing specific jobs in the matrix |
Example: Defining a Matrix with Values
jobs:
test:
matrix:
values: [1, 2, 3]
include:
- name: "job1"
value: 4
3. Specifying Parameter Values
| Parameter | Description | Values | Notes |
|---|---|---|---|
| matrix | Defines the matrix of parameter values to run jobs with | { version: [ '14', '16', '18' ], arch: [ 'x64', 'arm64' ] } |
Each key in the matrix represents a parameter name, and each value is an array of possible values |
| matrix.include | Allows adding additional parameter combinations to the matrix | { version: '20', arch: 'x64', os: 'linux' } |
Useful for adding special cases or specific configurations not covered by the base matrix |
| matrix.exclude | Allows excluding specific parameter combinations from the matrix | { version: '14', arch: 'arm64' } |
Useful for excluding unsupported or problematic combinations |
Example: Matrix job configuration with parameters
jobs:
test:
parameters:
version:
type: string
default: '18'
arch:
type: string
default: 'x64'
machine:
image: ubuntu-2004:2023.07.1
steps:
- run:
command: |
echo "Testing with Node.js version ${{ parameters.version }} on ${{ parameters.arch }} architecture"
Example: Using matrix to run tests across multiple versions
jobs:
test:
machine:
image: ubuntu-2004:2023.07.1
parameters:
version:
type: string
default: '18'
arch:
type: string
default: 'x64'
steps:
- run:
command: |
echo "Running tests with Node.js version ${{ parameters.version }} on ${{ parameters.arch }} architecture"
node --version
workflows:
matrix-test:
jobs:
- test:
matrix:
parameters:
version: [ '14', '16', '18' ]
arch: [ 'x64', 'arm64' ]
4. Expanding Matrix Combinations
| Property | Description | Values | Notes |
|---|---|---|---|
| matrix | Defines the matrix dimensions and values | { version: ['14', '16', '18'], os: ['linux', 'macos'] } |
Each key represents a dimension; values are the combinations |
| expand | Expands a matrix to include additional combinations | { node_version: ['14', '16', '18'], os: ['linux', 'macos'], arch: ['x64', 'arm64'] } |
Allows adding new dimensions to existing matrix jobs |
Example: Expanding Matrix Combinations
jobs:
test:
matrix:
version: ['14', '16', '18']
os: ['linux', 'macos']
expand:
arch: ['x64', 'arm64']
Note: The
expand key allows you to add new dimensions to an existing matrix without redefining all combinations.
5. Using Matrix with Workflows
Example: Matrix Job in Workflow
workflows:
build-and-test:
jobs:
- build
- test:
matrix:
parameters:
node-version: [14, 16, 18]
os: [linux, macos]
| Property | Description | Values |
|---|---|---|
| matrix | Defines the matrix configuration for job execution | parameters, exclude, include |
| parameters | Defines the matrix dimensions and their values | Object with key-value pairs |
| exclude | Excludes specific combinations from the matrix | Array of parameter objects |
| include | Adds additional combinations to the matrix | Array of parameter objects |
Note: Matrix jobs run in parallel, and each combination is executed as a separate job.
Example: Matrix with Exclude
test:
matrix:
parameters:
node-version: [14, 16, 18]
os: [linux, macos]
exclude:
- node-version: 14
os: macos
Example: Matrix with Include
test:
matrix:
parameters:
node-version: [14, 16]
os: [linux]
include:
- node-version: 18
os: linux
environment:
TEST_ENV: production
6. Excluding Combinations
| Option | Values | Notes |
|---|---|---|
| matrix.exclude | object[] |
Array of objects specifying combinations to exclude |
Example: Excluding a specific combination
jobs:
test:
matrix:
exclude:
- node-version: "14.0"
os: "linux"
Note: The
exclude key is used to remove specific combinations from the matrix job. It accepts an array of objects, where each object specifies a combination to exclude.7. Testing Multiple Versions
| Version | Supported | Notes |
|---|---|---|
| node | 14, 16, 18, 20 |
Test against multiple Node.js versions |
| python | 3.8, 3.9, 3.10, 3.11 |
Test against multiple Python versions |
| java | 8, 11, 17, 21 |
Test against multiple Java versions |
Example: Matrix Job Configuration
jobs:
test:
parallelism: 4
matrix:
version:
- node: "14"
- node: "16"
- node: "18"
- node: "20"
steps:
- run:
name: "Run tests"
command: "npm test"
Note: Matrix jobs allow you to run the same set of steps across multiple configurations, such as different versions of Node.js or Python.
8. Testing Multiple Platforms
| Platform | Configuration | Notes |
|---|---|---|
| Linux | linux |
Default platform for most builds |
| macOS | macos |
For builds requiring macOS environment |
| Windows | windows |
For builds requiring Windows environment |
Example: Matrix Job Configuration for Platforms
jobs:
test:
parallelism: 4
matrix:
platform: [linux, macos, windows]
steps:
- checkout
- run: echo "Running on $PLATFORM"
Note: Matrix jobs allow you to run the same job across multiple platforms simultaneously.
9. Parameterizing Executors
| Property | Description | Values | Notes |
|---|---|---|---|
| executor | Specifies the executor to use for the job | executor-name |
Must match an executor defined in the config |
| parameters | Defines parameters that can be passed to the executor | {param-name: {type: string, default: value}} |
Used to customize executor behavior |
Example: Parameterized Executor
executors:
node-executor:
parameters:
node-version:
type: string
default: "18.0.0"
docker:
- image: cimg/node:<parameters.node-version>
Example: Using Parameterized Executor
jobs:
test:
executor:
name: node-executor
params:
node-version: "20.0.0"
10. Debugging Matrix Issues
Example: Matrix Job Debug Output
jobs:
test:
parallelism: 4
steps:
- run:
name: "Debug Matrix Variables"
command: |
echo "Matrix var: $CIRCLE_JOB"
echo "Parallelism: $CIRCLE_PARALLELISM"
| Issue | Description | Solution |
|---|---|---|
| Matrix job fails silently | Job completes with no error logs | Enable debug mode with CIRCLE_DEBUG=1 |
| Incorrect matrix expansion | Wrong number of jobs created | Validate matrix configuration in circle.yml |
| Resource limits exceeded | Jobs timeout or get killed | Reduce parallelism or increase resource class |
Note: Use
circleci debug CLI command to inspect matrix job execution.
Warning: Avoid nested
matrix definitions as they can cause unexpected behavior.