SuperAPI AI Directory

ship-infrastructure-ci-cd

Deployment & operations

View repository

Updated 10-16 09:30

About this skill

CI/CD — Continuous Integration and Continuous Deployment

Entry/Exit

  • Entry: A new project needs CI, existing CI needs modification, deployment automation configuration
  • Exit: Working pipeline definition + all quality gates pass
  • Points to: After CI/CD configuration is complete, continue /ship process
  • Preload: CANON.md
  • Output path: Working pipeline definition + all quality gates pass → ship-workflow-ship(continue release process)

When not to use

  • Just running existing CI or viewing a single build result
  • The project has no newly added/modified automated pipeline, quality gate, or deployment process
  • Release decisions or go-live verification are the main issue (use ship-workflow-ship / ship-infrastructure-deploy)

Iron Law

Core Principles

Shift Left

The earlier a problem is found, the lower the cost. Catching it in a PR is 10x cheaper than in staging, and 100x cheaper than in production.

Faster is Safer

Smaller batches + more frequent releases = lower risk. Big bang release = big bang rollback.

Quality Gate Pipeline

Lint ──→ Type Check ──→ Unit Tests ──→ Build ──→ Integration Tests ──→ E2E Tests ──→ Security Audit ──→ Bundle Size
  │          │              │            │             │                  │                │                │
  ▼          ▼              ▼            ▼             ▼                  ▼                ▼                ▼
 代码风格  类型安全    单元行为    可构建    跨组件交互    关键用户流程    OWASP/CVE        不超过预算

任何门失败 → 管道停止 → 反馈给开发者

Do not create skippable gates. Every gate must pass to reach the next one.

GitHub Actions Configuration

name: CI
on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20', cache: 'npm' }
      - run: npm ci
      - run: npm run lint
      - run: npm run type-check
      - run: npm test -- --coverage
      - run: npm run build

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm audit --audit-level=high  # 有 high/critical → 失败

Good/Bad CI Configuration Comparison

Bad CI configuration — never write it like this:

# Bad: 无缓存、允许失败、密钥硬编码、无超时
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout
      - run: npm install
      - run: npm test
        continue-on-error: true  # 测试失败也继续!
      - run: npm run deploy
        env:
          AWS_SECRET_KEY: abc123hardcoded  # 密钥硬编码!

Good CI configuration — use this as the standard:

# Good: 缓存、严格失败、密钥安全、超时、分离关注点
jobs:
  lint-and-typecheck:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: npm }
      - run: npm ci
      - run: npm run lint
      - run: npx tsc --noEmit

  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: npm }
      - run: npm ci
      - run: npm test -- --coverage
      - uses: codecov/codecov-action@v4

  deploy:
    needs: [lint-and-typecheck, test]
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - run: npm run deploy
        env:
          AWS_SECRET_KEY: ${{ secrets.AWS_SECRET_KEY }}

Anti-pattern Fix Table

Problem Fix
In CI continue-on-error: true Remove. The point of CI is gating. Allowing failure = no gate.
Full install every time with no cache Use actions/cache or the cache parameter of setup-node
Manual SSH deployment to the server Use GitHub Actions / GitLab CI for automated deployment, auditable and rollback-capable
Skipping security audit in CI Add npm audit / Snyk / Trivy steps; critical must block
Not pinning Action versions (using @main) Pin to @v4 or @sha256. @main may be subject to supply chain attacks.
All steps crammed into one job Separate by concern: lint, test, build, deploy as independent jobs
No timeout setting Set timeout-minutes for each job. Prevent hangs from consuming resources

CI Failure Feedback Loop

When CI fails → the output must tell the developer:

  1. What failed(Lint?Type?Test?)
  2. Which line/which file
  3. How to fix it(command hint)
# CI 配置加:失败时跑特定诊断
- name: Debug test failures
  if: failure()
  run: cat test-results.xml | grep -A 5 "failure"

Deployment Strategies

Strategy Risk Applicable
Preview Deploy (per PR) Very low Independent environment per PR, reviewers can experience it directly
Blue/Green Low Two complete environments, instant switch, instant rollback
Staged Rollout (10% → 50% → 100%) Low-Medium High-traffic services, gradually reduce risk
Rolling Update Medium Update instance by instance, standard K8s/ECS

Minimum requirements:

  • Every deployment must have a corresponding rollback plan (command or one-click button)
  • Staging deployment must precede production deployment
  • Feature Flags are used to decouple deployment (shipping code) from release (enabling functionality)

CI optimization

CI 慢 (>10 min)?
├── 缓存 node_modules (.npm / actions/cache)
├── 测试并行 (按模块分 job)
├── 使用本地 CI runner (而非 GitHub hosted)
├── 仅跑受影响的测试 (test impact analysis)
└── 拆分 heavy job (lint + type 并行)

Common sayings

Saying Reality Consequence
"Skip CI and deploy directly, it's too slow" Skipping CI = moving quality checks to production. You will discover in production the problems CI could find in 5 minutes. Skipping CI to deploy to production → introducing known lint/type/test issues → the cost of a production incident rollback is 100x the CI runtime.
"It's okay if this check fails" Every "it's okay" becomes the next "it's okay." Eventually CI is completely ignored. 3 months later CI is red and nobody looks → all quality gates become meaningless → the team loses trust in CI and reverts to manual processes.
"Manual deployment is faster" Manual deployment = steps may be missed, the environment may be wrong, rollback steps are uncertain. One manual mistake > all automation costs. Manual deployment misses one environment variable → production 500 errors persist for 45 minutes until someone notices → not rollback-able, not auditable.
"Ignore CI red for now, fix it later" CI red is the project's only current truth. Continuing to commit on red CI = continuing to build on an uncertain foundation. Continuing to commit on red CI → new code mixes with existing problems → root cause diagnosis takes 5-10x longer → "fix it later" becomes "never fix it."
"CI is green, so it's safe" Green CI ≠ good tests. Tests may have insufficient coverage or allow_failure. Green CI + low coverage = false sense of security. When coverage < 50%, major bugs still ship under green CI because critical paths are not tested. After release, 30% of bugs come from uncovered paths.
"E2E is too slow and unnecessary" Critical user flows must have E2E. Only run critical paths, not full coverage. Critical flows without E2E (payment/registration/login) → the user's first action in a real browser fails. After release, 40% of production failures come from browser compatibility issues in critical flows.
"Flaky tests are someone else's problem" Flaky tests erode team trust. Whoever finds it fixes it, or marks it and creates an issue. Flaky tests not fixed → the team gets used to ignoring CI failures → real failures are ignored as flaky → production bugs. When flaky rate > 5%, team trust in CI drops to < 30%.
"Add caching later" Add caching on day one. Adding it after CI gets slow = waiting two months for nothing. CI without caching takes 5-10 minutes to install dependencies each time → the whole team wastes hours cumulatively every day → developers avoid running CI.
"Manual QA is more reliable than CI" Manual QA is not durable, not repeatable, and cannot bisect. Automation is the baseline. Manual QA cannot regress → retesting all flows before every release → 20-30% miss rate and worsening as the project grows.
"Adding security audit steps to CI is too slow" Security audits run in parallel in CI and do not increase critical path time. Not running security audits in CI → known CVEs quietly enter production → supply chain attack risk keeps accumulating. On average, each project introduces 2-3 known CVEs per month, with detection lagging 30+ days.

Violating the letter of the rule is violating the spirit. There is no gray area.

Red flag — STOP

  • A CI gate is skipped/commented out/set to allow_failure
  • Secrets written directly in CI yaml (use GitHub Secrets / Vault)
  • In CI, npm audit has high/critical but is unhandled
  • Manual deployment without an automatic rollback mechanism
  • E2E tests are disabled in CI (too slow → parallelize or give more CI resources, do not disable)
  • No caching in the CI configuration causes reinstallation every time (wasting CI minutes)

Pay attention to signals from human partners:

  • "Did CI pass?" — You may not have waited for the CI result
  • "How long does the build take?" — CI is too slow and needs optimization
  • "Can we skip the security check just this once?" — Absolutely not. This is a red flag.
  • "Why did CI fail?" — You need to read the error logs instead of guessing

Handling verification failures

Failure scenario Handling method
CI flaky (sometimes passes, sometimes fails) Mark the flaky test. Run it in isolation to confirm. Fix nondeterminism (timing, order dependence, external services).
Passes locally but fails in CI Check environment differences (Node version, OS, environment variables). Test locally using the same Docker image as CI.
CI build time > 30 minutes Priority: add caching > split jobs for parallelism > reduce dependencies > incremental builds.
Security audit finds a Critical CVE Block the merge. Assess actual exploitability. If a patch exists, update immediately; if not, evaluate alternatives.
E2E test timeout Check the test waiting strategy (use wait-for instead of sleep). Check whether CI resources are sufficient.

Output template

# CI/CD Pipeline Report — 持续集成与持续部署管道报告

## 元信息
- **配置者**: [姓名/角色]
- **项目**: [项目名]
- **配置日期**: YYYY-MM-DD
- **平台**: [GitHub Actions / GitLab CI / 其他]

## Quality Gate 状态

| Gate | 状态 | 阈值 | 实际值 | 备注 |
|------|------|------|--------|------|
| Lint | ✅ / ❌ | 零 error | [实际 error 数] | — |
| Type Check | ✅ / ❌ | 零 error | [实际 error 数] | — |
| Unit Tests | ✅ / ❌ | 覆盖率 ≥ 80% | [实际覆盖率] | — |
| Build | ✅ / ❌ | 成功构建 | [构建时间] | — |
| Integration Tests | ✅ / ❌ | 全部通过 | [通过/总数] | — |
| E2E Tests | ✅ / ❌ | 关键路径通过 | [通过/总数] | — |
| Security Audit | ✅ / ❌ | zero high/critical CVE | [high/critical 数] | — |
| Bundle Size | ✅ / ❌ | ≤ [预算]KB | [实际大小]KB | — |

## CI 配置清单
- [ ] 缓存配置(node_modules/.cache)
- [ ] 所有 job 有 timeout-minutes
- [ ] 密钥使用 Secrets(无硬编码)
- [ ] Action 版本固定(@v4 或 @sha256,非 @main)
- [ ] 失败时输出诊断信息

## 部署策略
- **策略类型**: [Preview / Blue-Green / Staged Rollout / Rolling Update]
- **Staging 先于生产**: ✅ / ❌
- **回滚方案**: [描述或命令]
- **Feature Flag**: ✅ 已配置 / ❌ 未配置

## 性能指标
- **总 CI 运行时间**: [分钟]
- **关键路径时间**: [分钟]
- **优化建议**: [如有 > 10min,列出优化方向]

## 审查结论
- **通过**: 所有质量门 ✅ + 部署策略明确 + 回滚方案就绪
- **阻止**: 任何质量门 ❌ 或回滚方案缺失

## 验证清单

- [ ] 所有质量门在 CI 中启用且必须通过
- [ ] CI 配置文件已提交(无密钥硬编码)
- [ ] 依赖缓存配置(node_modules/.cache)
- [ ] 部署策略明确(Preview / Blue-Green / Staged)
- [ ] 每个部署有回滚方案
- [ ] CI 失败输出包含具体诊断信息
- [ ] Staging 先于生产部署