Skip to main content

Executando variações de trabalhos em um fluxo de trabalho

Crie uma matriz para definir as variações de cada trabalho.

Sobre estratégias de matriz

Uma estratégia de matriz permite que você use variáveis em uma única definição de trabalho para criar automaticamente várias execuções de trabalho baseadas nas combinações das variáveis. Por exemplo, você pode usar uma estratégia de matriz para testar seu código em várias versões de um idioma ou em vários sistemas operacionais.

Usando uma estratégia de matriz

Use jobs.<job_id>.strategy.matrix para definir uma matriz de diferentes configurações de trabalho. Dentro de sua matriz, defina uma ou mais variáveis seguidas por uma matriz de valores. Por exemplo, a matriz a seguir tem uma variável chamada version com o valor [10, 12, 14] e uma variável chamada os com o valor [ubuntu-latest, windows-latest]:

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

Um trabalho será executado para cada combinação possível das variáveis. Neste exemplo, o fluxo de trabalho executará seis trabalhos, um para cada combinação das variáveis os e version.

Por padrão, o GitHub maximizará o número de trabalhos executados em paralelo, dependendo da disponibilidade do executor. A ordem das variáveis na matriz determina a ordem na qual os trabalhos são criados. A primeira variável definida será o primeiro trabalho criado na execução do fluxo de trabalho. Por exemplo, a matriz acima criará os trabalhos na seguinte ordem:

  • {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}

Uma matriz pode gerar 256 tarefas no máximo por execução do fluxo de trabalho. Esse limite se aplica a executores hospedados pelo GitHube auto-hospedados.

As variáveis que você define se tornam propriedades no contexto matrix, e você pode referenciar a propriedade em outras áreas do arquivo de fluxo de trabalho. Neste exemplo, você pode usar matrix.version e matrix.os para acessar o valor atual de version e os que o trabalho está usando. Para obter mais informações, confira "Acessar informações contextuais sobre execuções de fluxo de trabalho".

Exemplo: usando uma matriz unidimensional

Você pode especificar uma única variável para criar uma matriz unidimensional.

Por exemplo, o fluxo de trabalho a seguir define a variável version com os valores [10, 12, 14]. O fluxo de trabalho executará três trabalhos, um para cada valor na variável. Cada trabalho acessará o valor version por meio do contexto matrix.version e passará o valor como node-version à ação actions/setup-node.

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

Exemplo: usando uma matriz multidimensional

Você pode especificar diversas variáveis para criar uma matriz multidimensional. Um trabalho será executado para cada combinação possível das variáveis.

Por exemplo, o fluxo de trabalho a seguir especifica duas variáveis:

  • Dois sistemas operacionais especificados na variável os
  • Três versões do Node.js especificadas na variável version

O fluxo de trabalho executará seis trabalhos, um para cada combinação entre as variáveis os e version. Cada trabalho definirá o valor runs-on como o valor atual os e passará o valor atual version para a ação 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 }}

Uma configuração variável em uma matriz pode ser um array de objects.

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

Essa matriz produz 4 trabalhos com contextos correspondentes.

- 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

Exemplo: usar contextos para criar matrizes

Você pode usar contextos para criar matrizes. Para obter mais informações sobre contextos, confira "Acessar informações contextuais sobre execuções de fluxo de trabalho".

Por exemplo, o fluxo de trabalho a seguir dispara no evento repository_dispatch e usa informações do conteúdo do evento para criar a matriz. Quando um evento de expedição de repositório é criado com um conteúdo como o abaixo, a variável da matriz version terá um valor de [12, 14, 16]. Para obter mais informações sobre o gatilho repository_dispatch, confira "Eventos que disparam fluxos de trabalho".

{
  "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 }}

Expandir ou adicionar configurações de matriz

Use jobs.<job_id>.strategy.matrix.include para expandir as configurações de matriz existentes ou para adicionar novas configurações. O valor de include é uma lista de objetos.

Para cada objeto na lista include, os pares key:value no objeto serão adicionados a cada uma das combinações de matriz se nenhum dos pares key:value substituir qualquer um dos valores de matriz originais. Se o objeto não puder ser adicionado a nenhuma das combinações de matriz, uma nova combinação de matriz será criada. Observe que os valores de matriz originais não serão substituídos, mas os valores de matriz adicionados podem ser substituídos.

Por exemplo, esta matriz:

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

resultará em seis trabalhos com as seguintes combinações de matriz:

  • {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}

seguindo esta lógica:

  • {color: green} será adicionado a todas as combinações de matriz originais porque ele pode ser adicionado sem substituir nenhuma parte das combinações originais.
  • {color: pink, animal: cat} adiciona color:pink apenas às combinações de matriz originais que incluem animal: cat. Isso substitui o color: green que foi adicionado pela entrada anterior include.
  • O {fruit: apple, shape: circle} adiciona shape: circle apenas às combinações de matriz originais que incluem fruit: apple.
  • O {fruit: banana} não pode ser adicionado a nenhuma combinação de matriz original sem substituir um valor, portanto, ele é adicionado como uma combinação de matriz adicional.
  • O {fruit: banana, animal: cat} não pode ser adicionado a nenhuma combinação de matriz original sem substituir um valor, portanto, ele é adicionado como uma combinação de matriz adicional. Ele não adiciona à combinação de matriz {fruit: banana} porque essa combinação não era uma das combinações de matriz originais.

Exemplo: expandindo configurações

Por exemplo, o fluxo de trabalho a seguir executará quatro trabalhos, um para cada combinação de os e node. Quando o trabalho para o valor os de windows-latest e valor node as execuções 16, uma variável adicional chamada npm com o valor de 6 será incluída no trabalho.

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

Exemplo: adicionando configurações

Por exemplo, essa matriz executará dez trabalhos, um para cada combinação de os e version na matriz, além de um trabalho para o valor os de windows-latest e o valor version de 17.

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

Se você não especificar nenhuma variável de matriz, todas as configurações abaixo de include serão executadas. Por exemplo, o fluxo de trabalho a seguir executaria dois trabalhos, um para cada entrada include. Isso permite que você aproveite a estratégia de matriz sem ter uma matriz totalmente populada.

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

Excluindo configurações de matriz

Para remover configurações específicas definidas na matriz, use jobs.<job_id>.strategy.matrix.exclude. Uma configuração excluída só precisa ser uma correspondência parcial para que ela seja excluída. Por exemplo, o fluxo de trabalho a seguir executará nove trabalhos: um trabalho para cada uma das 12 configurações, menos o trabalho excluído correspondente {os: macos-latest, version: 12, environment: production}e os dois trabalhos excluídos correspondentes {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 }}

Note

Todas as combinações de include são processadas após exclude. Isso permite que você use include para adicionar combinações anteriores que já foram excluídas.

Exemplo: usar uma saída para definir duas matrizes

Você pode usar a saída de um trabalho para definir matrizes para vários trabalhos.

Por exemplo, o fluxo de trabalho a seguir demonstra como definir uma matriz de valores em um trabalho, usar essa matriz em um segundo trabalho para produzir artefatos e então consumir esses artefatos em um terceiro trabalho. Cada artefato está associado a um valor da matriz.

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

Tratamento de falhas

Você pode controlar como as falhas de trabalho são tratadas com jobs.<job_id>.strategy.fail-fast e jobs.<job_id>.continue-on-error.

jobs.<job_id>.strategy.fail-fast aplica-se a toda a matriz. Se jobs.<job_id>.strategy.fail-fast estiver definido como true ou sua expressão for avaliada como true, GitHub cancelará todos os trabalhos em andamento e enfileirados na matriz se algum trabalho na matriz falhar. Essa propriedade tem como padrão true.

jobs.<job_id>.continue-on-error aplica-se a um único trabalho. Se jobs.<job_id>.continue-on-error for true, outros trabalhos na matriz continuarão em execução mesmo que o trabalho com jobs.<job_id>.continue-on-error: true falhe.

Você não pode usar jobs.<job_id>.strategy.fail-fast e jobs.<job_id>.continue-on-error juntos. Por exemplo, o fluxo de trabalho a seguir iniciará quatro trabalhos. Para cada trabalho, continue-on-error é determinado pelo valor de matrix.experimental. Se algum dos trabalhos com continue-on-error: false falhar, todos os trabalhos em andamento ou enfileirados serão cancelados. Se o trabalho com continue-on-error: true falhar, os outros trabalhos não serão afetados.

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

Como definir o número máximo de trabalhos simultâneos

Por padrão, o GitHub maximizará o número de trabalhos executados em paralelo, dependendo da disponibilidade do executor. Para definir o número máximo de trabalhos que podem ser executados simultaneamente com uma estratégia de trabalho matrix, use jobs.<job_id>.strategy.max-parallel.

Por exemplo, o fluxo de trabalho a seguir executará no máximo dois trabalhos por vez, mesmo que haja executores disponíveis para executar todos os seis trabalhos ao mesmo tempo.

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