跳至主要内容

在工作流中运行作业的变体

创建矩阵以定义每个作业的变体。

关于矩阵策略

矩阵策略允许您在单个作业定义中使用变量,以根据变量的组合自动创建多个作业运行。例如,您可以使用矩阵策略在多种语言版本或多个操作系统上测试您的代码。

使用矩阵策略

使用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]

每个可能的变量组合都会运行一个作业。在本例中,工作流将运行六个作业,每个作业对应osversion变量的一个组合。

默认情况下,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.versionmatrix.os来访问作业正在使用的versionos的当前值。有关更多信息,请参阅“访问有关工作流运行的上下文信息”。

示例:使用单维度矩阵

您可以指定单个变量来创建单维度矩阵。

例如,以下工作流定义了变量version,其值为[10, 12, 14]。工作流将运行三个作业,每个值一个。每个作业都将通过matrix.version上下文访问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变量中指定的两个操作系统
  • version变量中指定的三个 Node.js 版本

工作流将运行六个作业,每个作业对应osversion变量的一个组合。每个作业都将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 }}

矩阵中的变量配置可以是objectarray

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的原始矩阵组合中。这会覆盖先前include条目添加的color: green
  • {fruit: apple, shape: circle}仅将shape: circle添加到包含fruit: apple的原始矩阵组合中。
  • {fruit: banana}无法在不覆盖任何值的情况下添加到任何原始矩阵组合中,因此它被添加为一个额外的矩阵组合。
  • {fruit: banana, animal: cat}无法在不覆盖任何值的情况下添加到任何原始矩阵组合中,因此它被添加为一个额外的矩阵组合。它不会添加到{fruit: banana}矩阵组合中,因为该组合不是原始矩阵组合之一。

示例:扩展配置

例如,以下工作流将运行四个作业,每个作业对应osnode的一个组合。当os值为windows-latestnode值为16的作业运行时,一个名为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 个作业,每个作业对应矩阵中osversion的一个组合,以及os值为windows-latestversion值为17的作业。

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-fastjobs.<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-errortrue,则即使具有jobs.<job_id>.continue-on-error: true的作业失败,矩阵中的其他作业也将继续运行。

您可以将jobs.<job_id>.strategy.fail-fastjobs.<job_id>.continue-on-error结合使用。例如,以下工作流将启动四个作业。对于每个作业,continue-on-errormatrix.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]