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]

将针对变量的每个可能组合运行作业。 在此示例中,工作流将运行六个作业,其中一个作业用于每个 osversion 变量组合。

默认情况下,GitHub Enterprise Cloud 将根据运行器的可用性最大程度地增加并行运行的作业数量。 矩阵中变量的顺序决定了作业的创建顺序。 定义的第一个变量将是在工作流运行中创建的第一个作业。 例如,上述矩阵将按以下顺序创建作业:

  • {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 Enterprise Cloud 托管和自托管运行器。

定义的变量将成为 matrix 上下文中的属性,你可以在工作流文件的其他区域中引用该属性。 在此示例中,可以使用 matrix.versionmatrix.os 来访问作业正在使用的 versionos 的当前值。 有关详细信息,请参阅“访问有关工作流运行的上下文信息”。

示例:使用单维矩阵

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

例如,以下工作流使用值 [10, 12, 14] 定义变量 version。 工作流将运行三个作业,其中针对变量中的每个值提供一个作业。 每个作业都会通过 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 变量组合提供一个作业。 当对应于 windows-latestos 值和 16node 值的作业运行时,作业中将包含一个被称为 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 的组合一个作业,再加上一个用于 windows-latestos 值和 17version 值的作业。

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。 排除的配置必须是部分匹配项,才能将其排除。 例如,以下工作流将运行 9 个作业:每 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 }}

Note

所有 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 Enterprise Cloud 将取消矩阵中所有正在进行和在队列中的作业。 此属性的默认值为 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-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 Enterprise Cloud 将根据运行器的可用性将并行运行的作业数最大化。 若要设置使用 matrix 作业策略时可以同时运行的最大作业数,请使用 jobs.<job_id>.strategy.max-parallel

例如,以下工作流一次最多运行两个作业,即使运行器可同时运行六个作业。

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