配了三年 CI/CD,今天才发现流水线跑得慢从来不是代码的错——2026 年 GitHub Actions 把这件事彻底原生化了

配了三年的 CI/CD,每次点完「Commit」就开始焦虑——要等多久来着?二十分钟?隔壁组同样的代码量五分钟跑完了。团队开始互相甩锅:是不是谁写了什么烂代码?是不是测试太慢了?

翻了一圈 issue 才发现,流水线跑得慢,从来不是代码的错——是配置方式的问题。2026 年的 GitHub Actions,已经把这些问题从根上原生化了。

大多数团队的流水线,都有三个通病。

第一个,没缓存。每次运行都从零安装依赖,冷启动十分钟就没了。第二个,任务串行执行。本来可以并行的 lint 和 test 非要排队,lint 等 test,test 等 type check。第三个,无效运行。一个文档改动触发全流水线,后端测试跑在只改了前端的 PR 上。这三个问题每一个都有对应的 GitHub Actions 原生解法,2026 年已经全部稳定。

第一个解法:缓存策略。

依赖缓存是最直接的性能杠杆。setup-node 自带 cache 参数,三行搞定:

- uses: actions/setup-node@v4
  with:
    node-version: 22
    cache: 'pnpm'

进阶一点,缓存 Next.js 构建产物和 Playwright 浏览器:

- name: Cache Next.js build
  uses: actions/cache@v4
  with:
    path: .next/cache
    key: nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
- name: Cache Playwright browsers
  uses: actions/cache@v4
  with:
    path: ~/.cache/ms-playwright
    key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}

配置到位的缓存,可以把冷启动十分钟的流水线压缩到两分钟,节省 40-60% 的运行时间。

第二个解法:并行任务与分片。

lint 和 test 本来可以同时跑,非要排队是历史遗留问题。job 默认并行,用 needs 声明依赖关系即可:

jobs:
  lint-and-typecheck:
    runs-on: ubuntu-latest
    steps:
      - run: pnpm lint
      - run: pnpm tsc --noEmit
  test:
    runs-on: ubuntu-latest
    steps:
      - run: pnpm test --coverage
  build:
    needs: [lint-and-typecheck, test]
    runs-on: ubuntu-latest

大测试套件用 matrix 分片并行:

strategy:
  matrix:
    shard: [1, 2, 3, 4]
steps:
  - run: pnpm test --shard=${{ matrix.shard }}/4

四个 runner 同时跑,总wall time从四倍降到一倍。

第三个解法:并发控制与触发过滤。

同一个分支重复推送,旧运行还没跑完新运行又来了,白白浪费资源。一行 concurrency 配置解决:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

路径过滤则让改动精准触发该跑的 job:

on: pull_request
  paths:
    - 'app/**'
    - 'packages/**'
jobs:
  python-tests:
    if: contains(github.event.pull_request.changed_files, 'app/')

文档改动不会触发后端测试,后端改动不会触发前端构建。

可复用工作流:团队级别的 CI 配置。

如果你管着多个仓库,每个仓库都在复制同一套 YAML——这本身就是问题。可复用工作流把完整流程定义为单文件,其他仓库直接调用:

# .github/workflows/node-ci.yml
name: Node CI
on: workflow_call:
  inputs:
    node-version:
      type: string
      default: '22'
  jobs:
    test:
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v4
        - uses: actions/setup-node@v4
          with:
            node-version: ${{ inputs.node-version }}
            cache: 'npm'
        - run: npm ci
        - run: npm test

其他仓库调用:

jobs:
  ci:
    uses: ./.github/workflows/node-ci.yml
    with:
      node-version: '24'

一个改动全局生效,不用逐仓库同步。

2026 年的安全加固三件事。

管道本身也是攻击面。第一,第三方 Actions 固定到 SHA,不用 @main 或 @latest。第二,最小权限原则,workflow 级别声明 permissions,默认 read-only。第三,生产环境 Secrets 走 environment 隔离,不写在 YAML 里,OIDC 模式替代长期云密钥。

permissions:
  contents: read
  id-token: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # 只有这个 environment 的 secrets 可用

三个下一步,现在就能落地。

第一,跑一次现有的 pipeline,测一下冷启动时间——这是基准线。第二,在 lint 和 test 之间加 needs 依赖,测一下并行后省了多少分钟。第三,把 @latest 替换成 @v4.x.x 的固定版本。

CI/CD 配置是代码,不是配置文件——它值得用对待代码的方式对待它:模块化、审查、可复用。2026 年的 GitHub Actions 已经把这件事彻底原生化了,就看你用不用。

评论区

0 条评论

登录后可评论。