CI/CD 流水线优化指南——从入门到高效
作者: CaoZH
日期: 2026-04-15
本文为原创教程
很多团队的 CI/CD 流水线一次构建要跑 30 分钟以上,严重拖慢开发效率。本文从实际优化经验出发,系统性地介绍如何让 CI/CD 流水线跑得更快更稳。
一、测量现状
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| name: CI Pipeline
on: [push]
jobs: build: runs-on: ubuntu-latest steps: - name: Checkout run: echo "耗时分析"
- name: Install dependencies run: echo "依赖安装时间"
- name: Lint run: echo "Lint 时间"
- name: Test run: echo "测试时间"
- name: Build run: echo "构建时间"
|
使用 GitHub Actions 的 Summary 页面查看每个步骤耗时,找到最慢的部分。
二、缓存策略
依赖缓存
1 2 3 4 5 6 7
| - name: Cache npm dependencies uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-npm-
|
Maven 缓存
1 2 3 4 5 6 7
| - name: Cache Maven dependencies uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven-
|
Docker 镜像缓存
1 2 3 4 5 6 7
| - name: Cache Docker layers uses: actions/cache@v4 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx-
|
三、并行化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run lint
test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test
test-matrix: strategy: matrix: node-version: [18, 20, 22] os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm ci - run: npm test
build: needs: [lint, test, test-matrix] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run build
|
四、条件执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| on: push: paths: - 'src/**' - 'package.json' - '.github/workflows/**' paths-ignore: - 'docs/**' - 'README.md' - '*.md'
jobs: backend-test: if: contains(join(github.event.commits.*.modified, ','), 'backend/')
deploy: if: github.ref == 'refs/heads/main' && success()
|
五、分阶段流水线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| name: Efficient CI/CD
on: push: branches: [main, develop] paths-ignore: ['docs/**', '*.md']
jobs: quick-checks: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci --prefer-offline - run: npm run lint - run: npm run type-check - run: npm run test:unit -- --changed
full-tests: needs: quick-checks strategy: matrix: shard: [1, 2, 3, 4] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test -- --shard=${{ matrix.shard }}/4
build: needs: full-tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - run: | docker build \ --cache-from=type=gha \ --cache-to=type=gha,mode=max \ -t myapp:${{ github.sha }} . - run: docker push myapp:${{ github.sha }}
deploy: needs: build if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: | ssh deploy@server "docker pull myapp:${{ github.sha }} && docker compose up -d"
|
六、优化效果对比
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ## 优化前(35分钟) 检出 → 安装依赖 → Lint → 测试 → 构建 → Docker构建 → 部署 (5m) (8m) (3m) (5m) (8m) (4m) (2m) 全部串行执行
## 优化后(8分钟) ┌── 检出(30s) ├── 安装依赖并行 ↓ │ ├── Lint(2m) ← 并行 │ ├── 单元测试(3m) ← 并行 │ └── 类型检查(1m) ← 并行 ├── 集成测试(3m,分片4×并行) ├── Docker构建(2m,带缓存) └── 部署(1m,条件执行)
|
七、错误处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| - name: Flaky test retry uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 command: npm run test:e2e
- name: Notify on failure if: failure() uses: slackapi/slack-github-action@v2 with: webhook: ${{ secrets.SLACK_WEBHOOK }} message: "CI 失败: ${{ github.repository }}@${{ github.ref }}"
- name: Upload debug info if: failure() uses: actions/upload-artifact@v4 with: name: debug-info path: | test-results/ *.log
|
八、总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ## CI/CD 优化清单
□ 启用依赖缓存(npm/Maven/Docker) □ 并行运行独立任务 □ 使用测试分片加速大规模测试 □ 只在需要时运行 CI(path filter) □ 使用条件执行(只部署 main 分支) □ Docker 构建缓存 □ 失败时自动重试不稳定测试 □ 分阶段流水线(快速失败)
## 效果 优化前:30-60 分钟 优化后:5-15 分钟
|
首发于 CaoZH 的笔记