GitHub Actions Cheatsheet
Matrix Builds
Use this GitHub Actions reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Basic Matrix
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm testEach matrix value becomes a separate job. Three node values = three parallel jobs.
Multi-Dimensional Matrix
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20]
# 3 × 2 = 6 parallel jobsAccess in steps:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}Including Extra Combinations
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20]
include:
# Add extra key to an existing combo
- os: ubuntu-latest
node: 20
experimental: true
# Add a brand-new combo not in the base product
- os: macos-latest
node: 22
experimental: trueExcluding Combinations
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20]
exclude:
- os: macos-latest
node: 18 # skip this specific combofail-fast and max-parallel
strategy: fail-fast: false # default: true — cancel remaining jobs on first failure max-parallel: 3 # run at most 3 matrix jobs at once (default: unlimited) matrix: os: [ubuntu-latest, windows-latest, macos-latest] node: [18, 20, 22]
Using Matrix Values in Expressions
steps:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.os }}-node${{ matrix.node }}
path: dist/
- name: Set platform flag
run: |
if [ "${{ matrix.os }}" = "windows-latest" ]; then
echo "EXT=.exe" >> $GITHUB_ENV
else
echo "EXT=" >> $GITHUB_ENV
fi
shell: bashDynamic Matrix (from JSON)
Generate the matrix at runtime from a prior job:
jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: |
# Could be generated from a script, API call, or file
echo 'matrix={"include":[{"env":"dev"},{"env":"staging"}]}' >> $GITHUB_OUTPUT
deploy:
needs: setup
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
steps:
- run: ./deploy.sh ${{ matrix.env }}Matrix with Secrets / Env per Entry
strategy:
matrix:
include:
- environment: staging
url: https://staging.example.com
- environment: production
url: https://example.com
steps:
- run: curl ${{ matrix.url }}/healthCross-Platform Shell Scripts
# Avoid shell differences — use actions/github-script or explicit shell: - name: Create dir shell: bash # works on Windows too (Git Bash) run: mkdir -p dist # Or branch on OS - if: runner.os == 'Windows' run: New-Item -ItemType Directory -Path dist shell: pwsh - if: runner.os != 'Windows' run: mkdir -p dist
Testing Against Multiple Language Versions
Node.js
strategy:
matrix:
node-version: ['18.x', '20.x', '22.x']
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}Python
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}Go
strategy:
matrix:
go-version: ['1.21', '1.22', '1.23']
steps:
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}Referencing Matrix in Job Name
jobs:
test:
name: Test (${{ matrix.os }}, Node ${{ matrix.node }})
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20]Produces readable names in the Actions UI like "Test (ubuntu-latest, Node 20)".
Matrix Limits
| Limit | Value |
|---|---|
| Max matrix entries per workflow run | 256 |
Max include entries | 256 |
| Combined (base × dims + include) | 256 total |