Skip to content

Matrix Builds

GitHub Actions matrix builds enable you to run the same job across multiple configurations—such as different operating systems, Node.js versions, or architectures—simultaneously. This parallel execution accelerates testing and validation, ensuring compatibility across diverse environments. By leveraging matrix strategies, you can efficiently test code against all required configurations without duplicating workflows.

Configuring Matrix Strategies

Matrix builds are defined using the matrix key within a job’s strategy block. Each combination of parameters in the matrix spawns a separate job, which runs in parallel by default.

Basic Syntax

jobs:
  test-suite:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node: [14, 16]
    steps:
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - run: npm install && npm test

In this example, four jobs are created:
- Ubuntu with Node.js 14
- Ubuntu with Node.js 16
- Windows with Node.js 14
- Windows with Node 16

Each job runs independently, and results are aggregated in the workflow run.

Advanced Configuration

You can nest matrix parameters for more complex scenarios. For example, combining OS, Node.js, and database versions:

strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node: [14, 16]
    db: [postgres, mysql]
This creates 12 distinct jobs (2 OS × 2 Node × 2 DB). Use matrix.os, matrix.node, etc., in steps to access current configuration values.

Use Cases and Examples

1. Cross-Platform Testing

jobs:
  cross-platform-test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
      - run: echo "Running tests on ${{ matrix.os }}"
      - run: ./run-tests.sh

2. Architecture-Specific Builds

For ARM64 or x86_64 builds, use self-hosted runners or GitHub’s ARM64 runners:

strategy:
  matrix:
    architecture: [x86_64, arm64]
    os: [ubuntu-latest]
In steps, detect architecture:
if [[ "$ARCH" == "arm64" ]]; then
  echo "Building for ARM64"
fi

3. Conditional Matrix Builds

Filter configurations using if conditions:

strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node: [14, 16]
    env: ${{ matrix.os == 'ubuntu-latest' ? 'prod' : 'dev' }}

Best Practices

  • Keep configurations manageable: Avoid overly complex matrices that exceed GitHub’s parallel job limits.
  • Leverage caching: Use actions/cache to speed up dependency installs across matrix jobs.
  • Monitor resource usage: Parallel jobs consume CI minutes and runner resources; optimize with max-parallel or timeout-minutes.
  • Use needs for dependencies: Ensure jobs depend on earlier stages if required.

Key takeaways

  • Matrix builds enable parallel execution across OS, Node.js, or architecture configurations.
  • Define matrices using the matrix key in the strategy block, with parameters like os, node, or db.
  • Combine matrix strategies with conditions, caching, and self-hosted runners for advanced use cases.
  • Balance complexity and resource usage to maintain efficient CI/CD pipelines.