Матрицы: тестируем на нескольких версиях
Один job — десятки комбинаций версий и платформ без копипасты.
Matrix — механизм, который размножает один job по комбинациям заданных значений, запуская их параллельно.
Зачем нужна матрица
Библиотека должна работать на Node 18 и 20, приложение — на Linux и Windows. Писать четыре почти одинаковых job — боль. Матрица описывает варианты один раз, а GitHub сам создаёт по job на каждую комбинацию.
Базовый пример
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
Это создаст три параллельных job: для Node 18, 20 и 22. Значение текущей версии доступно как ${{ matrix.node }}.
Несколько измерений
Можно перемножать оси. Здесь 3 версии × 2 ОС = 6 job:
strategy:
matrix:
node: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
fail-fast и max-parallel
По умолчанию fail-fast: true — если одна комбинация упала, остальные отменяются. Иногда хочется увидеть результат всех вариантов:
strategy:
fail-fast: false
max-parallel: 2
matrix:
node: [18, 20, 22]
max-parallel ограничивает число одновременных job (бережёт лимит минут).
include и exclude
exclude убирает ненужную комбинацию, include добавляет особую:
strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest, windows-latest]
exclude:
- node: 18
os: windows-latest # эту пару не запускаем
include:
- node: 22
os: ubuntu-latest
experimental: true # добавили особый вариант с доп. полем
Итог
- Матрица размножает job по комбинациям значений и гоняет их параллельно.
- Текущее значение оси доступно как
${{ matrix.имя }}. fail-fast,max-parallel,include/excludeточно настраивают набор и поведение.
Проверьте себя
1. Сколько job создаст матрица с node: [18, 20] и os: [ubuntu-latest, windows-latest] без exclude?
A2
B4
C1
D8
2. Что делает fail-fast: false в стратегии матрицы?
AУскоряет сборку вдвое
BНе отменяет остальные комбинации, если одна упала — увидите результат всех
CОтключает тесты
DЗапускает job последовательно
3. Как внутри шагов получить текущее значение оси матрицы node?
A$NODE_VERSION
B${{ matrix.node }}
Cmatrix.get('node')
D${{ env.node }}