Skip to main content

Выполнение вариантов заданий в рабочем процессе

Создайте матрицу для определения вариантов для каждого задания.

Сведения о стратегиях матрицы

Стратегия матрицы позволяет использовать переменные в одном определении задания для автоматического создания нескольких выполнений заданий, основанных на сочетаниях переменных. Например, можно использовать стратегию матрицы для тестирования кода в нескольких версиях языка или в нескольких операционных системах.

Использование стратегии матрицы

Используйте jobs.<job_id>.strategy.matrix для создания матрицы различных конфигураций заданий В матрице определите одну или несколько переменных, за которыми следует массив значений. Например, в указанной ниже матрице есть переменная под именем version со значением [10, 12, 14] и переменная под именем os со значением [ubuntu-latest, windows-latest]:

jobs:
  example_matrix:
    strategy:
      matrix:
        version: [10, 12, 14]
        os: [ubuntu-latest, windows-latest]

Задание будет выполняться для каждой возможной комбинации переменных. В этом примере рабочий процесс будет выполнять шесть заданий, по одному для каждой комбинации переменных os и version.

По умолчанию GitHub максимизирует количество параллельно выполняемых заданий в зависимости от доступности средства выполнения. Порядок переменных в матрице определяет порядок создания заданий. Первая переменная, которую вы определите, будет первым заданием, созданным в ходе выполнения рабочего процесса. Например, указанная выше матрица создаст задания в следующем порядке:

  • {version: 10, os: ubuntu-latest}
  • {version: 10, os: windows-latest}
  • {version: 12, os: ubuntu-latest}
  • {version: 12, os: windows-latest}
  • {version: 14, os: ubuntu-latest}
  • {version: 14, os: windows-latest}

Матрица создаст не более 256 заданий для каждого выполнения рабочего процесса. Это ограничение применяется как к размещенным в GitHub, так и к локальным средствам выполнения.

Переменные, которые вы определяете, становятся свойствами в контексте matrix, и можно ссылаться на это свойство в других областях файла рабочего процесса. В этом примере можно использовать matrix.version и matrix.os, чтобы получить доступ к текущим значениям version и os, которые использует задание. Дополнительные сведения см. в разделе Доступ к контекстной информации о запусках рабочих процессов.

Пример. Использование матрицы с одним измерением

Можно указать одну переменную для создания одномерной матрицы.

Например, следующий рабочий процесс определяет переменную version со значениями [10, 12, 14]. Рабочий процесс будет выполнять три задания, по одному для каждого значения в переменной. Каждое задание будет получать доступ к значению version через контекст matrix.version и передавать значение node-version в действие actions/setup-node.

jobs:
  example_matrix:
    strategy:
      matrix:
        version: [10, 12, 14]
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.version }}

Пример. Использование матрицы с несколькими измерениями

Для создания многомерной матрицы можно указать несколько переменных. Задание будет выполняться для каждой возможной комбинации переменных.

Например, для следующего рабочего процесса устанавливаются две переменные:

  • Две операционные системы, указанные в переменной os
  • Три версии Node.js, указанные в переменной version

Рабочий процесс будет выполнять шесть заданий, по одному для каждой комбинации переменных os и version. В каждом задании параметру runs-on присваивается текущее значение os и передается текущее значение version в действие actions/setup-node.

jobs:
  example_matrix:
    strategy:
      matrix:
        os: [ubuntu-22.04, ubuntu-20.04]
        version: [10, 12, 14]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.version }}

Конфигурация переменной в матрице может иметь значение array objects.

matrix:
  os:
    - ubuntu-latest
    - macos-latest
  node:
    - version: 14
    - version: 20
      env: NODE_OPTIONS=--openssl-legacy-provider

Эта матрица создает 4 задания с соответствующими контекстами.

- matrix.os: ubuntu-latest
  matrix.node.version: 14
- matrix.os: ubuntu-latest
  matrix.node.version: 20
  matrix.node.env: NODE_OPTIONS=--openssl-legacy-provider
- matrix.os: macos-latest
  matrix.node.version: 14
- matrix.os: macos-latest
  matrix.node.version: 20
  matrix.node.env: NODE_OPTIONS=--openssl-legacy-provider

Пример. Использование контекстов для создания матриц

Контексты можно использовать для создания матриц. Дополнительные сведения о контекстах см. в разделе "Доступ к контекстной информации о запусках рабочих процессов".

Например, следующий рабочий процесс активирует событие repository_dispatch и использует сведения из его полезных данных для построения матрицы. При создании события диспетчеризации репозитория с полезными данными, как показано ниже, переменная version матрицы будет иметь значение [12, 14, 16]. Дополнительные сведения об триггере repository_dispatch см. в разделе "События, инициирующие рабочие процессы".

{
  "event_type": "test",
  "client_payload": {
    "versions": [12, 14, 16]
  }
}
on:
  repository_dispatch:
    types:
      - test
 
jobs:
  example_matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        version: ${{ github.event.client_payload.versions }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.version }}

Развертывание или добавление конфигураций матрицы

Используйте jobs.<job_id>.strategy.matrix.include для разворачивания существующих конфигураций матрицы или добавления новых конфигураций. Значение include является списком объектов.

Для каждого объекта в списке include пары ключ:значение в объекте будут добавлены к каждой из комбинаций матриц, если ни одна из пар ключ:значение не перезаписывает какие-либо исходные значения матрицы. Если объект не может быть добавлен в какие-либо комбинации матриц, будет создана новая. Обратите внимание, что исходные матричные значения не будут перезаписаны, но добавленные матричные значения могут быть перезаписаны.

Например, эта матрица:

strategy:
  matrix:
    fruit: [apple, pear]
    animal: [cat, dog]
    include:
      - color: green
      - color: pink
        animal: cat
      - fruit: apple
        shape: circle
      - fruit: banana
      - fruit: banana
        animal: cat

приведет к шести заданиям со следующими комбинациями матриц:

  • {fruit: apple, animal: cat, color: pink, shape: circle}
  • {fruit: apple, animal: dog, color: green, shape: circle}
  • {fruit: pear, animal: cat, color: pink}
  • {fruit: pear, animal: dog, color: green}
  • {fruit: banana}
  • {fruit: banana, animal: cat}

следуя этой логике:

  • {color: green} добавляется ко всем исходным комбинациям матриц, так как его можно добавить без перезаписи любой части исходных комбинаций.
  • {color: pink, animal: cat} добавляет color:pink только к исходным комбинациям матриц, которые включают animal: cat. Это перезаписывает color: green, добавленный предыдущей записью include.
  • {fruit: apple, shape: circle} добавляет shape: circle только к исходным комбинациям матриц, которые включают fruit: apple.
  • {fruit: banana} невозможно добавить ни в какую исходную комбинацию матриц без перезаписи значения, поэтому он добавляется в качестве дополнительной комбинации матриц.
  • {fruit: banana, animal: cat} невозможно добавить ни в какую исходную комбинацию матриц без перезаписи значения, поэтому он добавляется в качестве дополнительной комбинации матриц. Он не добавляется к комбинации матриц {fruit: banana}, так как эта комбинация не была одной из исходных комбинаций матриц.

Пример. Развертывание конфигураций

Например, следующий рабочий процесс будет выполнять четыре задания, по одному для каждого сочетания os и node. Если выполняется задание для значения windows-latest параметра os и значения 16 параметра node, в задание будет включена дополнительная переменная npm со значением 6.

jobs:
  example_matrix:
    strategy:
      matrix:
        os: [windows-latest, ubuntu-latest]
        node: [14, 16]
        include:
          - os: windows-latest
            node: 16
            npm: 6
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - if: ${{ matrix.npm }}
        run: npm install -g npm@${{ matrix.npm }}
      - run: npm --version

Пример. Добавление конфигураций

Например, в этой матрице будет выполняться 10 заданий, по одному для каждого сочетания os и version в матрице, а также еще одно задание для windows-latest со значением os и 17 со значением version.

jobs:
  example_matrix:
    strategy:
      matrix:
        os: [macos-latest, windows-latest, ubuntu-latest]
        version: [12, 14, 16]
        include:
          - os: windows-latest
            version: 17

Если не указать переменные матрицы, будут выполняться все конфигурации в include. Например, следующий рабочий процесс выполнит два задания, по одному для каждого элемента include. Это позволяет использовать не полностью заполненную матрицу.

jobs:
  includes_only:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - site: "production"
            datacenter: "site-a"
          - site: "staging"
            datacenter: "site-b"

Исключение конфигураций матрицы

Чтобы удалить конкретные конфигурации, определенные в матрице, используйте jobs.<job_id>.strategy.matrix.exclude. Исключенная конфигурация должна иметь хотя бы частичное совпадение, чтобы ее можно было исключить. Например, следующий рабочий процесс будет выполнять девять заданий: одно задание для каждой из 12 конфигураций, минус одно исключенное задание, которое совпадает с {os: macos-latest, version: 12, environment: production}, и два исключенных задания, которые совпадают с {os: windows-latest, version: 16}.

strategy:
  matrix:
    os: [macos-latest, windows-latest]
    version: [12, 14, 16]
    environment: [staging, production]
    exclude:
      - os: macos-latest
        version: 12
        environment: production
      - os: windows-latest
        version: 16
runs-on: ${{ matrix.os }}

Примечание. Все комбинации include обрабатываются после exclude. Это позволяет использовать include для добавления обратных комбинаций, которые были ранее исключены.

Пример. Использование выходных данных для определения двух матриц

Выходные данные из одного задания можно использовать для определения матриц для нескольких заданий.

Например, в следующем рабочем процессе показано, как определить матрицу значений в одном задании, использовать эту матрицу во втором задании для создания артефактов, а затем использовать эти артефакты в третьем задании. Каждый артефакт связан со значением из матрицы.

YAML
name: shared matrix
on:
  push:
  workflow_dispatch:

jobs:
  define-matrix:
    runs-on: ubuntu-latest

    outputs:
      colors: ${{ steps.colors.outputs.colors }}

    steps:
      - name: Define Colors
        id: colors
        run: |
          echo 'colors=["red", "green", "blue"]' >> "$GITHUB_OUTPUT"

  produce-artifacts:
    runs-on: ubuntu-latest
    needs: define-matrix
    strategy:
      matrix:
        color: ${{ fromJSON(needs.define-matrix.outputs.colors) }}

    steps:
      - name: Define Color
        env:
          color: ${{ matrix.color }}
        run: |
          echo "$color" > color
      - name: Produce Artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.color }}
          path: color

  consume-artifacts:
    runs-on: ubuntu-latest
    needs:
    - define-matrix
    - produce-artifacts
    strategy:
      matrix:
        color: ${{ fromJSON(needs.define-matrix.outputs.colors) }}

    steps:
    - name: Retrieve Artifact
      uses: actions/download-artifact@v4
      with:
        name: ${{ matrix.color }}

    - name: Report Color
      run: |
        cat color

Обработка сбоев

Можно управлять обработкой сбоев заданий с помощью jobs.<job_id>.strategy.fail-fast и jobs.<job_id>.continue-on-error.

jobs.<job_id>.strategy.fail-fast применяется ко всему тому. Если jobs.<job_id>.strategy.fail-fast задано значение true или его выражение оценивается true, GitHub отменит все выполняемые и очередные задания в матрице, если любое задание в матрице завершается ошибкой. По умолчанию свойство имеет значение true.

jobs.<job_id>.continue-on-error применяется к одному заданию. Если jobs.<job_id>.continue-on-error имеет значение true, другие задания в матрице будут продолжать выполняться, даже если задание с jobs.<job_id>.continue-on-error: true завершается сбоем.

Можно использовать jobs.<job_id>.strategy.fail-fast и jobs.<job_id>.continue-on-error совместно. Например, следующий рабочий процесс запустит четыре задания. Для каждого задания continue-on-error определяется значением matrix.experimental. При сбое любого из заданий с continue-on-error: false все выполняемые или помещенные в очередь задания будут отменены. При сбое задания с continue-on-error: true другие задания не будут затронуты.

jobs:
  test:
    runs-on: ubuntu-latest
    continue-on-error: ${{ matrix.experimental }}
    strategy:
      fail-fast: true
      matrix:
        version: [6, 7, 8]
        experimental: [false]
        include:
          - version: 9
            experimental: true

Определение максимального числа параллельных заданий

По умолчанию GitHub максимизирует количество параллельно выполняемых заданий в зависимости от доступности средства выполнения. Для настройки максимального числа заданий, которые могут выполняться одновременно при применении стратегии задания matrix, используйте jobs.<job_id>.strategy.max-parallel.

Например, следующий рабочий процесс будет выполнять не более двух заданий одновременно, даже если для одновременного выполнения всех шести заданий доступны средства выполнения.

jobs:
  example_matrix:
    strategy:
      max-parallel: 2
      matrix:
        version: [10, 12, 14]
        os: [ubuntu-latest, windows-latest]