关于矩阵策略
矩阵策略允许您在单个作业定义中使用变量,以根据变量的组合自动创建多个作业运行。例如,您可以使用矩阵策略在多种语言版本或多个操作系统上测试您的代码。
使用矩阵策略
使用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]
。工作流将运行三个作业,每个值一个。每个作业都将通过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 版本
工作流将运行六个作业,每个作业对应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 }}
矩阵中的变量配置可以是object
的array
。
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}
矩阵组合中,因为该组合不是原始矩阵组合之一。
示例:扩展配置
例如,以下工作流将运行四个作业,每个作业对应os
和node
的一个组合。当os
值为windows-latest
且node
值为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 个作业,每个作业对应矩阵中os
和version
的一个组合,以及os
值为windows-latest
且version
值为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
添加先前已排除的组合。
示例:使用输出定义两个矩阵
您可以使用一个作业的输出为多个作业定义矩阵。
例如,以下工作流演示了如何在其中一个作业中定义一系列值,在第二个作业中使用该矩阵生成工件,然后在第三个作业中使用这些工件。每个工件都与矩阵中的一个值相关联。
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
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]