关于矩阵策略
使用矩阵策略,可以在单个作业定义中使用变量自动创建基于变量组合的多个作业运行。 例如,可以使用矩阵策略在某个语言的多个版本或多个操作系统上测试代码。
使用矩阵策略
使用 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
的当前值。 有关详细信息,请参阅“上下文”。
示例:使用单维矩阵
可以指定单个变量来创建单维矩阵。
例如,以下工作流使用值 [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@v3
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@v3
with:
node-version: ${{ matrix.version }}
示例:使用上下文创建矩阵
可以使用上下文来创建矩阵。 有关上下文的详细信息,请参阅“上下文”。
例如,以下工作流触发事件 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@v3
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
变量组合提供一个作业。 当对应于 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@v3
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
。 排除的配置必须是部分匹配项,才能将其排除。 例如,以下工作流将运行 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 }}
注意:所有 include
组合会在 exclude
之后处理。 这允许你使用 include
添加回以前排除的组合。
处理故障
你可以使用 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]