How to make Github Actions matrix items conditional

要点#

matrixのアイテムに条件を表すものを追加し、それをexcludeで除外することで、条件によって matrix のアイテムを切り替えることができる。

matrixの利用方法については、公式ドキュメントを読んだ方が良い。

実装例 1#

実行しているブランチがデフォルトブランチの場合のみ、macOS を除外する例。

storategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
onDefaultBranch: ${{ github.ref_name == github.event.repository.default_branch }}
exclude:
- os: macos-latest
onDefaultBranch: false

excludeに指定された条件と一致する全てのアイテムが除外されるため、macos-latestであれば、node のバージョンが182022のいずれであっても除外される。

実装例 2#

macOS で実行する場合のみ、webkit の Playwright テストを実行する例。

env:
RUNNER_OS: ${{ github.event.pull_request.base.ref == 'stable' && 'macos-latest' || 'ubuntu-latest' }}
runs-on: ${{ env.RUNNER_OS }}
strategy:
matrix:
project:
- name: webkit
browser: webkit
if: ${{ env.RUNNER_OS == 'macos-latest' }}
- name: Mobile Safari
browser: webkit
if: ${{ env.RUNNER_OS == 'macos-latest' }}
- name: chromium
browser: chromium
if: true
- name: Mobile Chrome
browser: chromium
if: true
exclude:
- project:
if: false
steps:
# ...
- run: yarn playwright install --with-deps ${{ matrix.project.browser }}
- run: yarn playwright test --project="${{ matrix.project.name }}"

matrixで指定されたアイテムの組み合わせではなく、特定の組み合わせのみ実行したい場合、上記のように出来る。 この形式の場合、if アイテムを生やすことで、疑似的にstepsなどのifを模倣できる

includeexcludeの併用に注意#

公式ドキュメントでも言及されているが、includeexcludeを併用する場合、includeが後から評価されるため、この記事で紹介したexcludeを使った方法で除外されたアイテムがincludeで再度追加される可能性がある。

余談#

この方法を考えた当時、matrixのアイテムを条件によって切り替える方法について調べると、前段の job で JSON 文字列を生成したり、matrix を表した JSON ファイルを用意しておき、それをfromJSONで読み込ませる方法が紹介されていた。

確かに、JSON を読み込ませる方法で実現は出来るが、可読性を悪い上、無意味な情報の分離が発生するため、この方法を採用することは避けるべきだろう。