GitHub Actions matrix build (2026)

2026-06-29 · 5 min read

SHORT ANSWER Add a strategy.matrix to your job listing the versions you want, set fail-fast: false so one failing leg doesn't cancel the rest, and interpolate ${{ matrix.version }} into your setup step. GitHub runs every combination in parallel. Copy-paste workflow below.

The workflow

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        node: ["20", "22", "24"]

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm

      - run: npm ci
      - run: npm run lint --if-present
      - run: npm test

Why each part matters

strategy.matrix

The matrix turns one job definition into one run per value — here three jobs, on Node 20, 22 and 24, all in parallel. Add a second key (e.g. os: [ubuntu-latest, windows-latest]) and GitHub expands the cross-product automatically: 3 versions × 2 OSes = 6 jobs, no extra YAML.

fail-fast: false

By default GitHub cancels every other matrix leg the moment one fails. That hides whether a bug is version-specific. Setting fail-fast: false lets all legs finish, so you see at a glance that, say, only Node 24 is broken — not that "CI is red".

matrix value in the setup step

node-version: ${{ matrix.node }} is the whole point — each leg installs its own version. Forget this interpolation and all three legs run on the same default version, so the matrix tests nothing.

cache: npm

The official setup actions cache dependencies for you — cache: npm on setup-node (or cache: pip on setup-python) keys on your lockfile and restores node_modules's download cache across runs. No separate actions/cache step needed.

Python and Go

The shape is identical — swap the setup action and the matrix key:

    strategy:
      fail-fast: false
      matrix:
        python: ["3.11", "3.12", "3.13"]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
          cache: pip
      - run: pip install -e ".[test]"
      - run: pytest

For Go, use actions/setup-go@v5 with go-version: ${{ matrix.go }} (caching is on by default).

Common mistakes

Generate your CI workflow → SysBuild's free GitHub Actions generator builds a lint/test/build workflow for Node, Python or Go — in your browser, no signup. Add the matrix above on top.

Going further

For a complete, ready-to-run project — app, Dockerfile, docker-compose with Postgres, and a CI workflow already wired and green — the SysBuild Pro Pack ships six production stacks (FastAPI, Django, Node/Express, Next.js, Go and Rust), each with a working GitHub Actions pipeline you can extend into a matrix, for $29 one-time.

More articles