← 中文资源

简体中文版本

用 GitHub Actions Matrix 并行展开 CI

在同一份工作流中并行测试多个运行时与操作系统,关闭 fail-fast 避免互相掩盖,并用聚合任务维持单一必需检查。

阅读英文原文

概述

声称支持 Node 20 与 22,只有在 CI 真正测试两者时才成立。matrix 会把一个 job 展开成多个并行 job,每个组合一个。最常见的错误是保留 fail-fast 默认值:一旦为 true,某个组合失败会取消其他任务,日志只显示一个错误,掩盖了另外三个组合同样失败的事实。稳定期应显式设置 fail-fast: false,之后再根据成本决定是否允许提前取消。

步骤

  1. 声明 matrix 并关闭 fail-fast:
strategy:
  fail-fast: false
  matrix:
    os: [ubuntu-latest, windows-latest]
    node: [20, 22]
  1. 使用 exclude 移除明确不支持的组合:
matrix:
  os: [ubuntu-latest, windows-latest]
  node: [20, 22]
  exclude:
    - os: windows-latest
      node: 20
  1. 让缓存按 matrix 维度隔离,避免不同版本互相覆盖:
- uses: actions/setup-node@v4
  with:
    node-version: ${{ matrix.node }}
    cache: pnpm
- run: pnpm install --frozen-lockfile
  1. 增加聚合任务,分支保护只要求它:
required:
  needs: test
  if: always()
  runs-on: ubuntu-latest
  steps:
    - run: test "${{ needs.test.result }}" = "success"

验证

一次运行中应出现四个(排除后为三个)独立 job,名称包含操作系统与 Node 版本。聚合任务只有在所有 matrix 任务成功时才通过,被排除的组合视为跳过而不是失败。若分支保护一直处于等待状态,说明必需检查仍在匹配展开后的任务名,应改为要求聚合任务,这样新增 Node 版本不必修改保护规则。

注意事项

  • 每个 matrix 条目都会占用一台完整 runner,组合过多会显著拉长排队时间。
  • 缓存 key 必须包含 matrix 值,否则 Windows 任务会恢复 Linux 的依赖缓存,实际仍需重新安装。
  • matrix 值必须是字面量 YAML,动态列表需要先由发现任务输出,再通过 fromJSON 传入。
  • Windows 与 Linux 的换行符和路径分隔符不同,必要时统一使用 shell: bash。
  • 所有 action 仍应按照 commit SHA 固定版本,避免矩阵行为在发布期间发生变化。