Table of Contents
Open Table of Contents
Introduction
Efficient Testing Across Multiple Platforms and Configurations
GitHub Actions provides powerful features to automate, customize, and execute your software development workflows right in your repository. One such feature is the Matrix Strategy, which allows you to run your jobs across multiple combinations of variables, such as operating systems and software versions, without duplicating code.
In this article, we’ll explore how to leverage the Matrix Strategy in GitHub Actions to streamline your CI/CD pipelines, ensuring your applications are robust across different environments.
1. Why Use the Matrix Strategy?
When developing applications, you often need to test them across different environments:
- Operating Systems: Linux, macOS, Windows.
- Software Versions: Different versions of programming languages or dependencies.
Manually writing separate jobs for each combination is tedious and error-prone. The Matrix Strategy automates this process by generating jobs for every combination of specified parameters.
Benefits
- Efficiency: Write less code to cover more test cases.
- Scalability: Easily add or remove parameters without restructuring your workflow.
- Maintainability: Centralize your configurations, making updates simpler.
2. Defining a Matrix Strategy
The Matrix Strategy is defined within a job using the strategy
and matrix
keywords.
Basic Syntax
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
key1: [value1, value2]
key2: [value3, value4]
steps:
# Your steps here
Example: Testing Multiple Node.js Versions
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16, 18]
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm install
- name: Run Tests
run: npm test
In this example, the job will run three times, once for each Node.js version specified.
3. Using Multiple Keys in a Matrix
You can define multiple keys in your matrix to create combinations of different parameters.
Example: Testing Across OS and Node.js Versions
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [14, 16, 18]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm install
- name: Run Tests
run: npm test
This configuration generates 9 jobs (3 OS versions x 3 Node.js versions).
4. Including and Excluding Combinations
Sometimes, you may want to include specific combinations not covered by the default matrix or exclude certain combinations.
Excluding Combinations
Use the exclude
keyword under matrix
to remove specific combinations.
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [14, 16]
exclude:
- os: windows-latest
node-version: 14
Including Combinations
Use the include
keyword to add specific combinations or additional parameters.
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node-version: [14, 16]
include:
- os: windows-latest
node-version: 18
experimental: true
In this example, an additional job is created for Windows with Node.js version 18 and an experimental flag.
5. Advanced Matrix Settings
Fail-Fast Setting
By default, if any job fails, GitHub cancels all in-progress jobs (fail-fast: true
). You can change this behavior:
strategy:
fail-fast: false
matrix:
# Your matrix keys
Max Parallel
Control the maximum number of jobs running in parallel:
strategy:
max-parallel: 3
matrix:
# Your matrix keys
Continue-On-Error
Allow certain jobs to fail without failing the entire workflow:
jobs:
build:
continue-on-error: ${{ matrix.allow-failure }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [14, 16]
allow-failure: [false, true]
6. Example Workflow Using the Matrix Strategy
Let’s put it all together with a comprehensive example.
Workflow File: .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
strategy:
fail-fast: false
max-parallel: 3
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [14, 16]
include:
- os: ubuntu-latest
node-version: 18
exclude:
- os: windows-latest
node-version: 14
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.os == 'windows-latest' && matrix.node-version == '16' }}
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm install
- name: Run Tests on ${{ matrix.os }} with Node.js ${{ matrix.node-version }}
run: npm test
Explanation
- Matrix Keys:
os
andnode-version
. - Include: Adds an extra job for
ubuntu-latest
with Node.js 18. - Exclude: Removes the combination of
windows-latest
and Node.js 14. - Fail-Fast: Set to false to allow all jobs to complete even if some fail.
- Max-Parallel: Limits the number of parallel jobs to 3.
- Conditional
continue-on-error
: Allows the job onwindows-latest
with Node.js 16 to fail without failing the entire workflow.
7. Conclusion
The Matrix Strategy in GitHub Actions is a powerful tool that simplifies running your workflows across multiple environments and configurations. By leveraging matrices, you can:
- Reduce Redundancy: Avoid duplicating code for similar jobs.
- Improve Coverage: Easily test across various platforms and versions.
- Enhance Flexibility: Quickly adjust parameters as project requirements evolve.
By mastering the Matrix Strategy, you can create more efficient and scalable CI/CD pipelines that ensure your applications work flawlessly in any environment.