3 Implementation Patterns to Maximize Parallel Execution with GitHub Actions Matrix Build¶
Target Audience
- DevOps engineers (intermediate level) who understand GitHub Actions basics
Key Points¶
- Simultaneous testing across multiple environments with Matrix strategy
- Automatic build target determination with dynamic Matrix generation
- Reduced wasted execution time with fail-fast control
Why This Matters Now¶
Current CI/CD times exceed 30 minutes in large projects. By properly utilizing Matrix Build, parallel execution can reduce execution time by over 60%. Effectively utilize GitHub Actions' free tier of 2000 minutes/month.
Solution Steps Overview¶
| Step | Content | Success Metric |
|---|---|---|
| 1 | Basic Matrix setup | 3 environments parallel |
| 2 | Dynamic Matrix generation | Build changed files only |
| 3 | Optimization settings | 60% time reduction |
Step 1: Parallel Testing with Basic Matrix Configuration¶
Run tests simultaneously across multiple Node.js/Python versions and different operating systems.
name: Matrix Build
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20, 22]
exclude:
- os: macos-latest
node: 18
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
This configuration runs 5 combinations (Ubuntu×3 + macOS×2) in parallel.
Step 2: Efficiency with Dynamic Matrix Generation¶
Execute only necessary builds based on changed files.
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- id: set-matrix
run: |
if git diff --name-only HEAD^ | grep -q "frontend/"; then
echo "matrix={\"app\":[\"frontend\"]}" >> $GITHUB_OUTPUT
elif git diff --name-only HEAD^ | grep -q "backend/"; then
echo "matrix={\"app\":[\"backend\"]}" >> $GITHUB_OUTPUT
else
echo "matrix={\"app\":[\"frontend\",\"backend\"]}" >> $GITHUB_OUTPUT
fi
build:
needs: prepare
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
- run: echo "Building ${{ matrix.app }}"
Step 3: Optimization with fail-fast and max-parallel¶
Minimize resource consumption with immediate stop on error and parallel execution control.
strategy:
fail-fast: true # Stop all if one fails
max-parallel: 4 # Limit concurrent executions
matrix:
python: [3.9, 3.10, 3.11, 3.12]
test-group: [unit, integration, e2e]
Common Pitfalls and Solutions¶
| Symptom | Cause | Immediate Solution |
|---|---|---|
| Matrix expansion error | JSON syntax error | Echo check before fromJson() |
| Waiting for parallel limit | max-parallel not set | Set limit to 2-4 |
| Unnecessary combinations run | exclude not used | Explicitly specify exclusions |
Advanced Settings (High-level Optimization)
### Speed Up with Cache Integration- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }}
matrix:
include:
- os: ubuntu-latest
node: 20
run-e2e: true
- os: windows-latest
node: 20
run-e2e: false