Matrices, caches and artifacts make pipelines broader and faster. In this lesson you will run tests across browsers and operating systems in parallel, cache dependencies correctly, and keep and share reports with artifacts.
๐ What You’ll Learn: matrix strategy and job combinations, include and exclude, fail-fast and max-parallel, caching with setup actions and actions/cache, cache keys and restore keys, uploading and downloading artifacts, cache vs artifacts, and a complete cross-browser pipeline.
๐งฎ Three Tools for Faster, Broader Pipelines
| Feature | Solves |
|---|---|
| Matrix | Run the same job for many combinations (browsers, OS, versions) in parallel |
| Caching | Reuse downloaded dependencies between runs to save minutes |
| Artifacts | Keep files produced by a job (reports, screenshots, builds) and share them between jobs |
๐งฎ Matrix Builds
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # keep other combinations running if one fails
max-parallel: 4
matrix:
os: [ ubuntu-latest, windows-latest ]
browser: [ chromium, firefox, webkit ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- run: npm ci
- run: npx playwright install --with-deps ${{ matrix.browser }}
- run: npx playwright test --project=${{ matrix.browser }}
This creates 6 jobs (2 operating systems ร 3 browsers) that run in parallel. Each appears separately in the run, e.g. “test (windows-latest, firefox)”.
include and exclude
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
browser: [ chromium, firefox, webkit ]
exclude:
- os: windows-latest
browser: webkit # skip this combination
include:
- os: macos-latest
browser: webkit # add one extra combination
- os: ubuntu-latest
browser: chromium
smoke: true # add a variable to an existing combination
| Key | Effect |
|---|---|
fail-fast | Default true cancels all jobs when one fails; set false for test suites so you see every failure |
max-parallel | Limit simultaneous jobs |
exclude | Remove combinations |
include | Add combinations or extra values |
The matrix is also how you shard a large suite across machines: see Playwright in GitHub Actions.
โก Caching Dependencies
The easy way: setup actions
Most language setup actions cache package downloads with one line:
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm # also: yarn, pnpm
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: pip
The flexible way: actions/cache
- name: Cache Maven packages
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: maven-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
maven-${{ runner.os }}-
| Field | Meaning |
|---|---|
path | Folder(s) to save and restore |
key | Exact cache name; including hashFiles(...) of the lock file creates a new cache when dependencies change |
restore-keys | Fallback prefixes when there is no exact match |
๐ Note: Caches are scoped to the branch and its base branch, are evicted when unused for about a week, and have a total size limit per repository. Never cache secrets.
๐ก Tip: For Playwright, caching browsers rarely saves time because install --with-deps still installs system packages. Caching npm downloads (cache: npm) is the reliable win.
๐ฆ Artifacts
Upload
- name: Upload Playwright report
if: ${{ !cancelled() }} # also upload when tests fail
uses: actions/upload-artifact@v4
with:
name: playwright-report-${{ matrix.browser }} # unique name per matrix job
path: playwright-report/
retention-days: 14
โ ๏ธ Common mistake: With upload-artifact@v4, artifact names must be unique within a run. In a matrix, include the matrix values in the name, otherwise uploads fail.
Download in a later job
publish:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
pattern: playwright-report-*
path: all-reports
merge-multiple: false
- run: ls -R all-reports
Artifacts also appear at the bottom of the run’s summary page for download by humans.
| Cache | Artifact | |
|---|---|---|
| Purpose | Speed up future runs | Keep outputs of a run |
| Typical content | Dependencies | Reports, screenshots, builds, logs |
| Shared between | Runs | Jobs in the same run, and people |
| Lifetime | Evicted when unused | Retention days (configurable) |
๐งช Putting It Together: Cross-Browser Test Pipeline
name: Cross-browser tests
on: [ pull_request ]
jobs:
e2e:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
browser: [ chromium, firefox, webkit ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- run: npm ci
- run: npx playwright install --with-deps ${{ matrix.browser }}
- run: npx playwright test --project=${{ matrix.browser }}
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: report-${{ matrix.browser }}
path: playwright-report/
retention-days: 7
๐ Assignment
- Create a matrix job that prints
osandbrowserfor 2 ร 3 combinations. - Exclude one combination and include one extra; check the job list.
- Set
fail-fast: falseand make one combination fail on purpose. - Add
cache: npmto setup-node and compare the install time of the first and second run. - Upload a file as an artifact with a matrix-specific name and download it in a later job.
- Bonus: build the cross-browser pipeline above for your Playwright project.
โ FAQ
๐ค What is a matrix in GitHub Actions?
A strategy that runs the same job for every combination of values you list, such as operating systems or browsers, in parallel.
๐ค How do I cache npm dependencies in GitHub Actions?
Use actions/setup-node with cache: npm, or actions/cache with a key based on hashFiles('**/package-lock.json').
๐ค What is the difference between cache and artifacts?
Caches speed up future runs by reusing dependencies. Artifacts store outputs of a run, such as reports, for download or for later jobs.
๐ค Why does upload-artifact fail in my matrix?
Artifact names must be unique per run in v4; include matrix values in the name.
๐ค How do I upload test reports even when tests fail?
Add if: ${{ !cancelled() }} (or always()) to the upload step.
๐ฏ Next Steps
- โป๏ธ Reusable Workflows and Custom Actions
- ๐ Deploy with GitHub Actions
- ๐ Git and GitHub Tutorial: full course
๐ฌ Learn Git and GitHub step by step: watch the series on YouTube!
Subscribe to SqaToolsByDY • Practice on sqatools.in
1 thought on “GitHub Actions Matrix Builds, Caching and Artifacts (with Examples)”