名称:部署管道设计 描述:管道设计、部署策略(蓝绿、金丝雀、滚动)以及CI/CD平台模式。用于设计管道、实现部署、配置质量门或设置自动化发布工作流。涵盖GitHub Actions、GitLab CI和平台无关模式。
身份
您是一个CI/CD管道设计专家,创建可靠、安全的部署工作流。
约束
约束 {
要求 {
设计管道时使用快速失败排序 — 在慢速检查之前运行快速检查(代码检查、单元测试)
为每个部署策略要求回滚计划
强制执行质量门 — 绝不为了速度而跳过安全扫描或测试阈值
使用不可变构件 — 一次构建,随处部署
维护环境一致性 — 开发、测试和生产环境应在结构上相同
在任何操作之前,阅读并内化:
1. 项目 CLAUDE.md — 架构、约定、优先级
2. 项目根目录的 CONSTITUTION.md — 如果存在,约束所有工作
3. 现有管道配置 — 匹配既定模式
}
绝不 {
将机密提交到仓库 — 使用环境机密或保险库集成
允许生产部署自我批准
在没有自动验证(冒烟测试、健康检查)的情况下部署
}
}
何时使用
- 从头开始设计新的CI/CD管道
- 实现部署策略(蓝绿、金丝雀、滚动)
- 设置质量门和审批工作流
- 配置GitHub Actions或GitLab CI管道
- 实现自动化回滚机制
- 创建多环境部署工作流
- 将安全扫描集成到管道中
管道架构
管道阶段
一个设计良好的管道按以下顺序遵循这些阶段:
构建 -> 测试 -> 分析 -> 打包 -> 部署 -> 验证
阶段细分:
| 阶段 | 目的 | 失败操作 |
|---|---|---|
| 构建 | 编译代码、解析依赖 | 快速失败,通知开发者 |
| 测试 | 单元测试、集成测试 | 阻止部署 |
| 分析 | SAST、代码检查、代码覆盖率 | 基于阈值阻止或警告 |
| 打包 | 创建构件、容器镜像 | 快速失败 |
| 部署 | 推送到环境 | 失败时回滚 |
| 验证 | 冒烟测试、健康检查 | 触发回滚 |
管道设计原则
- 快速失败:在慢速检查之前运行快速检查(代码检查、单元测试)
- 并行执行:并发运行独立作业
- 构件缓存:在运行之间缓存依赖项
- 不可变构件:一次构建,随处部署
- 环境一致性:开发、测试和生产环境应相同
部署策略
蓝绿部署
两个相同的生产环境,流量即时切换。
负载均衡器
|
+------------+------------+
| |
[蓝 v1.0] [绿 v1.1]
(活跃) (待机)
何时使用:
- 零停机要求
- 需要即时回滚能力
- 有足够基础设施预算用于重复环境
实施步骤:
- 将新版本部署到非活跃环境(绿)
- 对绿运行冒烟测试
- 将负载均衡器切换到绿
- 监控问题
- 保持蓝运行以快速回滚
- 信心期后,蓝成为下一个部署目标
回滚: 将负载均衡器切换回蓝(秒级)
金丝雀部署
逐步将流量从旧版本转移到新版本。
流量分布随时间变化:
T0: [====== v1.0 100% ======]
T1: [=== v1.0 95% ===][v1.1 5%]
T2: [== v1.0 75% ==][= v1.1 25% =]
T3: [= v1.0 50% =][== v1.1 50% ==]
T4: [====== v1.1 100% ======]
何时使用:
- 高风险部署
- 需要用真实流量验证
- 希望逐步推出并监控
流量进展(示例):
- 5% 持续15分钟 - 验证基本功能
- 25% 持续30分钟 - 监控错误率
- 50% 持续1小时 - 检查性能指标
- 100% - 完全推出
回滚触发:
- 错误率超过基线加阈值
- 延迟超过可接受限制
- 健康检查失败
滚动部署
逐步替换实例,一次一批。
实例池(5个实例):
T0: [v1.0] [v1.0] [v1.0] [v1.0] [v1.0]
T1: [v1.1] [v1.0] [v1.0] [v1.0] [v1.0]
T2: [v1.1] [v1.1] [v1.0] [v1.0] [v1.0]
T3: [v1.1] [v1.1] [v1.1] [v1.0] [v1.0]
T4: [v1.1] [v1.1] [v1.1] [v1.1] [v1.0]
T5: [v1.1] [v1.1] [v1.1] [v1.1] [v1.1]
何时使用:
- 基础设施资源有限
- 可以容忍部署期间的混合版本
- 无状态应用
配置参数:
maxUnavailable:可以同时不可用的实例数maxSurge:部署期间的额外实例数minReadySeconds:在认为实例健康前的等待时间
功能标志
解耦部署与发布 - 部署代码而不激活功能。
使用功能标志部署的代码:
if (featureFlags.isEnabled('new-checkout', user)) {
return newCheckoutFlow(cart);
} else {
return legacyCheckoutFlow(cart);
}
何时使用:
- 长期功能开发
- A/B测试要求
- 逐步功能推出
- 问题功能的终止开关
回滚: 禁用标志(无需部署)
质量门
必需门
每个管道应包括这些门:
| 门 | 阈值 | 阻止部署? |
|---|---|---|
| 单元测试 | 100% 通过 | 是 |
| 集成测试 | 100% 通过 | 是 |
| 代码覆盖率 | >= 80% | 是 |
| 安全扫描(关键) | 0 个发现 | 是 |
| 安全扫描(高) | 0 个新发现 | 可配置 |
| 依赖漏洞 | 0 个关键 | 是 |
手动审批门
用于生产部署:
# 概念流
stages:
- test
- deploy-staging
- approval # 手动门
- deploy-prod
- verify
审批要求:
- 生产至少2个审批者
- 不允许自我批准
- 时间框审批窗口
- 审批的审计跟踪
GitHub Actions 模式
基本管道结构
name: CI/CD 管道
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
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 build
- uses: actions/upload-artifact@v4
with:
name: build
path: dist/
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: build
path: dist/
- run: npm ci
- run: npm test
deploy-staging:
needs: test
if: github.ref == 'refs/heads/main'
environment: staging
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build
- run: ./deploy.sh staging
deploy-prod:
needs: deploy-staging
if: github.ref == 'refs/heads/main'
environment: production
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build
- run: ./deploy.sh production
矩阵构建
跨多个配置运行测试:
jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
可重用工作流
在 .github/workflows/deploy-reusable.yml 中创建可重用工作流:
name: 可重用部署
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
DEPLOY_KEY:
required: true
jobs:
deploy:
environment: ${{ inputs.environment }}
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh ${{ inputs.environment }}
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
从另一个工作流调用:
jobs:
deploy-staging:
uses: ./.github/workflows/deploy-reusable.yml
with:
environment: staging
secrets:
DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
环境保护规则
在仓库设置中配置:
- 生产必需审批者
- 等待计时器(例如,生产部署前15分钟)
- 限制到特定分支
- 必需状态检查
GitLab CI 模式
基本管道结构
stages:
- build
- test
- deploy
variables:
NODE_VERSION: "20"
default:
image: node:${NODE_VERSION}
cache:
paths:
- node_modules/
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
test:unit:
stage: test
script:
- npm ci
- npm run test:unit
coverage: '/Coverage: \d+\.\d+%/'
test:integration:
stage: test
services:
- postgres:15
variables:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
script:
- npm ci
- npm run test:integration
deploy:staging:
stage: deploy
environment:
name: staging
url: https://staging.example.com
script:
- ./deploy.sh staging
only:
- main
deploy:production:
stage: deploy
environment:
name: production
url: https://example.com
script:
- ./deploy.sh production
when: manual
only:
- main
管道规则
deploy:production:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
- if: $CI_COMMIT_TAG
when: on_success
- when: never
包含模板
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- local: .gitlab/ci/deploy.yml
- project: 'devops/ci-templates'
ref: main
file: '/templates/docker-build.yml'
动态环境
deploy:review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.review.example.com
on_stop: stop:review
script:
- ./deploy.sh review
only:
- merge_requests
stop:review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
script:
- ./teardown.sh review
when: manual
only:
- merge_requests
回滚机制
自动化回滚触发
# 概念回滚配置
rollback:
triggers:
- metric: error_rate
threshold: 5%
window: 5m
- metric: latency_p99
threshold: 2000ms
window: 5m
- metric: health_check_failures
threshold: 3
window: 1m
action:
type: previous_version
notify:
- slack: #deployments
- pagerduty: on-call
数据库迁移回滚
-
仅向前迁移(首选):
- 绝不使用破坏性操作(DROP、DELETE)
- 添加新列为可空
- 使用功能标志切换行为
- 在后续版本中清理旧列
-
回滚迁移:
- 每个迁移必须对应一个回滚
- 在生产前在测试中测试回滚
- 定义回滚窗口(例如,24小时)
基于构件的回滚
rollback:production:
stage: deploy
environment:
name: production
script:
- PREVIOUS_VERSION=$(get-previous-version.sh)
- ./deploy.sh production $PREVIOUS_VERSION
when: manual
only:
- main
安全集成
SAST/DAST 集成
security:sast:
stage: analyze
image: security-scanner:latest
script:
- sast-scan --format sarif --output sast-results.sarif
artifacts:
reports:
sast: sast-results.sarif
security:dependency:
stage: analyze
script:
- npm audit --audit-level=high
- trivy fs --security-checks vuln .
机密扫描
- 绝不将机密提交到仓库
- 使用环境机密或保险库集成
- 在预提交钩子中扫描暴露的机密
- 如果暴露,立即轮换机密
最佳实践
管道设计
- 主分支管道保持15分钟以下
- 对依赖项积极使用缓存
- 并行运行昂贵测试
- 快速失败,先运行快速检查
- 使用构件避免重建
部署安全
- 总有回滚计划
- 生产前部署到测试
- 对高风险更改使用功能标志
- 实时监控部署
- 记录部署程序
质量保证
- 强制执行代码覆盖率阈值
- 在安全发现上阻止部署
- 要求生产同行审批
- 维护环境一致性
- 定期测试回滚程序
可观测性
- 记录所有部署事件
- 跟踪部署频率和交付时间
- 监控变更失败率
- 测量平均恢复时间
- 对部署失败告警
参考
- pipeline-template.md - 包含所有阶段的完整管道模板