ci-optimization-specialist
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCI Optimization Specialist
CI优化专家
Quick Start
快速开始
This skill optimizes GitHub Actions workflows for:
- Test sharding: Parallel test execution across multiple runners
- Caching: pnpm store, Playwright browsers, Vite build cache
- Workflow optimization: Job dependencies and concurrency
本技能针对以下场景优化GitHub Actions工作流:
- 测试分片:在多个运行器上并行执行测试
- 缓存:pnpm存储、Playwright浏览器、Vite构建缓存
- 工作流优化:任务依赖与并发控制
When to Use
适用场景
- CI execution time exceeds 10-15 minutes
- GitHub Actions costs too high
- Need faster developer feedback loops
- Tests not parallelized
- CI执行时间超过10-15分钟
- GitHub Actions成本过高
- 需要更快的开发者反馈循环
- 测试未进行并行化处理
Test Sharding Setup
测试分片配置
Basic Pattern (Automatic Distribution)
基础模式(自动分配)
Add matrix strategy to :
.github/workflows/ci.ymlyaml
e2e-tests:
name: 🧪 E2E Tests [Shard ${{ matrix.shard }}/3]
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3]
steps:
- name: Run Playwright tests
run: pnpm exec playwright test --shard=${{ matrix.shard }}/3
env:
CI: trueExpected improvement: 60-65% faster for 3 shards
向中添加matrix策略:
.github/workflows/ci.ymlyaml
e2e-tests:
name: 🧪 E2E Tests [Shard ${{ matrix.shard }}/3]
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3]
steps:
- name: Run Playwright tests
run: pnpm exec playwright test --shard=${{ matrix.shard }}/3
env:
CI: true预期优化效果:使用3个分片可提速60-65%
Advanced Pattern (Manual Distribution)
进阶模式(手动分配)
For unbalanced test suites, manually distribute by duration:
yaml
matrix:
include:
- shard: 1
pattern: 'ai-generation|project-management' # Heavy tests
- shard: 2
pattern: 'project-wizard|settings|publishing' # Medium tests
- shard: 3
pattern: 'world-building|versioning|mock-validation' # Light tests针对测试套件负载不均衡的情况,可按测试时长手动分配:
yaml
matrix:
include:
- shard: 1
pattern: 'ai-generation|project-management' # Heavy tests
- shard: 2
pattern: 'project-wizard|settings|publishing' # Medium tests
- shard: 3
pattern: 'world-building|versioning|mock-validation' # Light testsIn step:
In step:
run: pnpm exec playwright test --grep "${{ matrix.pattern }}"
undefinedrun: pnpm exec playwright test --grep "${{ matrix.pattern }}"
undefinedCritical Caching Patterns
关键缓存模式
pnpm Store Cache
pnpm存储缓存
ALWAYS cache pnpm store to avoid re-downloading packages:
yaml
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-始终缓存pnpm存储以避免重复下载包:
yaml
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-Playwright Browsers Cache
Playwright浏览器缓存
Cache 500MB+ browser binaries:
yaml
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps chromium
- name: Install Playwright system dependencies
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: pnpm exec playwright install-deps chromium缓存500MB以上的浏览器二进制文件:
yaml
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps chromium
- name: Install Playwright system dependencies
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: pnpm exec playwright install-deps chromiumVite Build Cache
Vite构建缓存
For monorepos or frequent builds:
yaml
- name: Cache Vite build
uses: actions/cache@v4
with:
path: |
dist/
node_modules/.vite/
key: ${{ runner.os }}-vite-${{ hashFiles('src/**', 'vite.config.ts') }}适用于单体仓库或频繁构建的场景:
yaml
- name: Cache Vite build
uses: actions/cache@v4
with:
path: |
dist/
node_modules/.vite/
key: ${{ runner.os }}-vite-${{ hashFiles('src/**', 'vite.config.ts') }}Workflow Optimization
工作流优化
Job Dependencies
任务依赖
Use to control execution flow:
needsyaml
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Build
run: pnpm run build
- name: Run unit tests
run: pnpm test
e2e-tests:
needs: build-and-test # Wait for build to complete
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3]
steps:
- name: Run E2E tests
run: pnpm exec playwright test --shard=${{ matrix.shard }}/3使用控制执行流程:
needsyaml
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Build
run: pnpm run build
- name: Run unit tests
run: pnpm test
e2e-tests:
needs: build-and-test # Wait for build to complete
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3]
steps:
- name: Run E2E tests
run: pnpm exec playwright test --shard=${{ matrix.shard }}/3Concurrency Control
并发控制
Prevent multiple runs on same branch:
yaml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true避免同一分支上的多次运行:
yaml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: trueArtifact Management
制品管理
Per-Shard Artifacts
分片制品
Upload test reports from each shard:
yaml
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report-shard-${{ matrix.shard }}-${{ github.sha }}
path: playwright-report/
retention-days: 7
compression-level: 6上传每个分片的测试报告:
yaml
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report-shard-${{ matrix.shard }}-${{ github.sha }}
path: playwright-report/
retention-days: 7
compression-level: 6Artifact Cleanup
制品清理
Set short retention for test reports to reduce storage costs:
yaml
retention-days: 7 # Default is 90 days
compression-level: 6 # Compress to reduce storage为测试报告设置较短的保留期以降低存储成本:
yaml
retention-days: 7 # Default is 90 days
compression-level: 6 # Compress to reduce storagePerformance Monitoring
性能监控
Expected Benchmarks
预期基准
| Optimization | Before | After | Improvement |
|---|---|---|---|
| Test sharding (3 shards) | 27 min | 9-10 min | 60-65% |
| pnpm cache hit | 2-3 min | 10-15s | 85-90% |
| Playwright cache hit | 1-2 min | 5-10s | 90-95% |
| Vite build cache | 1-2 min | 5-10s | 90-95% |
| 优化项 | 优化前 | 优化后 | 优化幅度 |
|---|---|---|---|
| 测试分片(3个分片) | 27分钟 | 9-10分钟 | 60-65% |
| pnpm缓存命中 | 2-3分钟 | 10-15秒 | 85-90% |
| Playwright缓存命中 | 1-2分钟 | 5-10秒 | 90-95% |
| Vite构建缓存 | 1-2分钟 | 5-10秒 | 90-95% |
Regression Detection
回归检测
Set timeout thresholds as guardrails:
yaml
timeout-minutes: 30 # Fail if shard exceeds 30 minutesMonitor shard execution times and rebalance if one shard consistently exceeds
others by >2 minutes.
设置超时阈值作为防护措施:
yaml
timeout-minutes: 30 # Fail if shard exceeds 30 minutes监控分片执行时间,如果某个分片的持续时间始终比其他分片长2分钟以上,则需要重新平衡分片。
Optimization Workflow
优化工作流
Phase 1: Baseline
阶段1:基准测试
- Record current CI execution times
- Identify slowest jobs
- Measure cache hit rates (check Actions logs)
- 记录当前CI执行时间
- 识别最慢的任务
- 测量缓存命中率(查看Actions日志)
Phase 2: Implement Caching
阶段2:实现缓存
- Add pnpm store cache (highest impact)
- Add Playwright browser cache
- Add build caches if applicable
- Verify cache keys work correctly
- 添加pnpm存储缓存(影响最大)
- 添加Playwright浏览器缓存
- 如有需要,添加构建缓存
- 验证缓存键是否正常工作
Phase 3: Implement Sharding
阶段3:实现分片
- Calculate optimal shard count (target 3-5 min per shard)
- Add matrix strategy to workflow
- Test locally:
playwright test --shard=1/3 - Monitor shard balance in CI
- 计算最优分片数量(目标每个分片耗时3-5分钟)
- 向工作流中添加matrix策略
- 本地测试:
playwright test --shard=1/3 - 在CI中监控分片负载平衡
Phase 4: Monitor & Adjust
阶段4:监控与调整
- Track execution times over 5-10 runs
- Identify unbalanced shards (>2 min variance)
- Adjust shard distribution if needed
- Set up alerts for regressions
- 跟踪5-10次运行的执行时间
- 识别负载不均衡的分片(差异>2分钟)
- 如有需要,调整分片分配
- 设置回归告警
Common Issues
常见问题
Shard imbalance (one shard takes 2x longer)
- Use manual distribution with patterns
--grep - Group heavy tests together, distribute across shards
Cache misses despite correct key
- Verify glob patterns match actual files
hashFiles - Check if lock file changes on every run (shouldn't happen)
Playwright install fails with cache hit
- Ensure system dependencies installed separately:
playwright install-deps
Tests fail in CI but pass locally
- Check environment variables (CI=true may affect behavior)
- Verify mock setup works in parallel execution
- Increase timeouts for slow operations
分片负载不均衡(某个分片耗时是其他的2倍)
- 使用模式进行手动分配
--grep - 将重型测试分组,分散到不同分片
缓存键正确但缓存未命中
- 验证通配符模式是否匹配实际文件
hashFiles - 检查锁文件是否每次运行都变化(正常情况下不应发生)
缓存命中时Playwright安装失败
- 确保单独安装系统依赖:
playwright install-deps
CI中测试失败但本地通过
- 检查环境变量(CI=true可能影响行为)
- 验证mock设置在并行执行时是否正常工作
- 为慢操作增加超时时间
Success Criteria
成功标准
- CI execution time < 15 minutes total
- Cache hit rate > 85% for dependencies
- Shard execution time variance < 2 minutes
- Zero timeout failures from slow tests
- 总CI执行时间<15分钟
- 依赖缓存命中率>85%
- 分片执行时间差异<2分钟
- 无因测试缓慢导致的超时失败
References
参考资料
For detailed examples and templates:
- GitHub Actions Caching: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows
- Playwright Sharding: https://playwright.dev/docs/test-sharding
- pnpm in CI: https://pnpm.io/continuous-integration
如需详细示例和模板:
- GitHub Actions缓存: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows
- Playwright分片:https://playwright.dev/docs/test-sharding
- pnpm在CI中的使用:https://pnpm.io/continuous-integration