Skip to main content
A matrix strategy lets you run the same workflow job across multiple PHP versions, operating systems, and configurations in parallel. This is the most effective way to ensure your code works everywhere your users run it.

Basic matrix example

The following workflow runs tests on Ubuntu, Windows, and macOS against PHP 8.2 through 8.5. Each combination becomes a separate job that runs in parallel.
This produces 12 parallel jobs (3 operating systems × 4 PHP versions).

Including specific PHP and PHPUnit version combinations

Use the include: key to add specific combinations that fall outside the main matrix. This is useful when you need to support an older PHP version that requires a pinned tool version.
The include: entry adds one extra job: PHP 8.1 on Ubuntu with PHPUnit 10. All other combinations use the latest PHPUnit version.

Multi-arch setup

To run tests on both amd64 and arm64 architectures, use shivammathur/node container images. These images have compatible Node.js and PHP installed for setup-php on Ubuntu and Debian runners. PHP 5.6 to PHP 8.5 are supported on multiple architectures through this approach.
The container image tag format is shivammathur/node:php-{version}-{ubuntu-version}-{arch}. The include: entries map each architecture to the appropriate runner label.

Matrix configuration tips

By default, GitHub Actions cancels all in-progress jobs when one matrix job fails. Set fail-fast: false to let all jobs complete so you can see which combinations fail.
If certain combinations are not relevant (for example, PHP 5.x only on Linux), use exclude: to skip them and reduce job count.
Add a name: field to the job to make the matrix jobs easier to identify in the Actions UI.
Test both the minimum and stable versions of your Composer dependencies by adding a prefer dimension to your matrix. This is especially useful for libraries that need to support a range of dependency versions.
The GitHub-hosted runner label ubuntu-latest currently maps to Ubuntu 24.04. Pin to a specific version like ubuntu-24.04 in production workflows to avoid unexpected changes when the latest label is updated.