Building different versions using a matrix
In this recipe, we are going to build and test our software for different versions, in our case, of the NodeJS environment.
Getting ready
Make sure you have cloned the repository from the previous recipe. Create a new branch to modify the workflow:
$ git switch -c build-matrix
Open the .github/workflows/ci.yml
file in an editor.
How to do it…
- Add the following code to the workflow file:
strategy: matrix: node-version: ["21.x", "20.x"]
Adjust the versions if needed.
- In the
actions/setup-node
action, set the node version to the corresponding value from the matrix context:- uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} check-latest: true
- Commit and push your changes and create a pull request:
$ git add . $ git commit $ git push -u origin build-matrix $ gh pr create --fill
- Check the output of the workflow. It will run a separate job for each entry in the matrix array (see Figure 6.3):

Figure 6.3 – The matrix runs a different job for each entry
- Wait until the workflow has completed. Merge your pull request and clean up your repository:
$ gh pr merge -m
How it works…
The matrix is a convenient way to use the same workflow jobs with different combinations. It can contain one or multiple arrays that can contain many values. The matrix will run all combinations of all values in all arrays. You can think of the matrix as nested for
loops. A good example is running and testing different versions on different platforms:
jobs: example_matrix: strategy: matrix: os: [ubuntu-22.04, ubuntu-20.04] version: [10, 12, 14] runs-on: ${{ matrix.os }} steps: - uses: actions/setup-node@v3 with: node-version: ${{ matrix.version }}
This way, you can reuse the same workflow logic to test many different combinations of values at the same time.
There’s more…
The matrix has some additional features. You can set fail-fast
to indicate if it will cancel the workflow if one job in the matrix fails or if it should continue. You can define the number of parallel jobs with max-parallel
, and you can include and exclude values for certain elements. Here is a more complex example:
jobs: test: runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental }} strategy: fail-fast: true max-parallel: 2 matrix: version: [5, 6, 7, 8] experimental: [false] include: - version: 9 experimental: true
To learn more about the matrix strategy, see https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs.