Sitemap

What is GitHub Actions Matrix Strategy?

3 min readApr 10, 2025

The GitHub Actions matrix strategy is a powerful feature that allows you to run the same job across multiple combinations of variables — like environments, operating systems, or software versions — without duplicating code. It’s ideal for scenarios such as:

  • Testing across different browser environments
  • Running code against multiple versions of a language
  • Deploying across multiple platforms (e.g., Android and iOS)

By using a strategy.matrix section in your workflow, you can define all the variations you want to test or execute. GitHub will then automatically create a job for each combination. This not only helps keep workflows clean and scalable, but also provides a clear view of which combinations succeed or fail.

Here’s a basic example:

strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [16, 18]

This configuration will run four jobs in parallel:

  • Ubuntu + Node 16
  • Ubuntu + Node 18
  • Windows + Node 16
  • Windows + Node 18

Learn more from GitHub’s official documentation

Cross-Browser UI Testing with GitHub Actions Matrix Strategy

When building UI automation workflows, one of the most common challenges is ensuring consistent functionality across different browsers. Initially, I handled this by creating separate GitHub Actions YAML files for each browser:

  • ui_chrome_pytest.yml
  • ui_firefox_pytest.yml

Each file had almost identical steps, with only minor differences.

🔍 Key Differences in the Old Files

  • ui_chrome_pytest.yml manually installs Google Chrome and ChromeDriver
  • ui_firefox_pytest.yml uses browser-actions/setup-firefox to install

Firefox and GeckoDriver

  • The pytest command uses --browser chrome in one, --browser firefox in the other
  • Both upload the same artifacts, which could overwrite each other

This setup worked, but had several downsides:

  • Duplication of logic — every change had to be applied in multiple files
  • Error-prone — it’s easy to forget updating one of them
  • Not scalable — adding another browser meant copying more of the same logic

The Solution: Matrix Strategy

So, to eliminate the duplication and better manage different browser setups, I leveraged the GitHub Actions matrix strategy. This approach allows each browser to be tested in parallel, using a single, unified workflow file.

I created a new workflow called:

ui_cross_browser_test.yml

name: UI Automation Tests

on:
pull_request:
branches:
- main
jobs:
build_and_test:
runs-on: ubuntu-latest
strategy:
matrix:
browser: [chrome, firefox]
steps:
- name: Checkout resume repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install dependencies and build
run: |
yarn install
yarn build
- name: Start the application
run: |
yarn start &
env:
PORT: 3000
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Chrome and ChromeDriver
if: matrix.browser == 'chrome'
run: |
sudo apt update
sudo apt install -y wget gnupg
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb
CHROMEDRIVER_VERSION=$(curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
wget https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin/chromedriver
sudo chmod +x /usr/local/bin/chromedriver
- name: Set up Firefox and GeckoDriver
if: matrix.browser == 'firefox'
uses: browser-actions/setup-firefox@latest
- name: Clone the test repository
run: |
git clone https://github.com/serhatozdursun/serhatozdursun-ui-tests.git
env:
GITHUB_TOKEN: ${{ secrets.UI_TEST_TOKEN }}
- name: Install Python dependencies
working-directory: serhatozdursun-ui-tests
run: |
pip install -r requirements.txt
- name: Run tests on ${{ matrix.browser }}
working-directory: serhatozdursun-ui-tests
id: run_tests
run: |
pytest --browser ${{ matrix.browser }} --base_url http://localhost:3000 --html=reports/html/report.html --junitxml=reports/report.xml
- name: Upload HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: html-report-${{ matrix.browser }}
path: serhatozdursun-ui-tests/reports/html
retention-days: 5
continue-on-error: true
- name: Upload XML report
if: always()
uses: actions/upload-artifact@v4
with:
name: xml-report-${{ matrix.browser }}
path: serhatozdursun-ui-tests/reports/report.xml
retention-days: 5
continue-on-error: true

👉 View the full workflow file on GitHub

Before vs After

Final Thoughts

Using GitHub Actions’ matrix strategy is a game-changer for cross-browser testing — or any testing that requires variation in environments, tools, or platforms.

If you’re still duplicating workflow files for minor differences, it’s time to simplify and scale.

--

--

Serhat Ozdursun
Serhat Ozdursun

Written by Serhat Ozdursun

QA Automation Engineer at Index

No responses yet