教程概述
系列索引: gstack 教程系列
发布工程技能形成完整的 CI/CD 管道:/ship → /land-and-deploy → /canary → /benchmark。
你将学到
- ✅
/ship完整发布工作流 - ✅ 测试框架引导
- ✅ 每次发布的覆盖审计
- ✅
/land-and-deploy合并 → CI → 部署 → 验证 - ✅
/canary部署后监控 - ✅
/benchmark性能基线跟踪
发布管道概述
flowchart TD
A[代码完成] --> B[/ship]
B --> C[PR 创建]
C --> D[人工审批]
D --> E[/land-and-deploy]
E --> F[CI 通过]
F --> G[部署]
G --> H[/canary]
H --> I{错误?}
I -->|是| J[回滚]
I -->|否| K[/benchmark]
K --> L[基线更新]
style B fill:#fff3e0
style E fill:#e8f5e9
style H fill:#ffebee
style K fill:#e1f5ff
/ship — 推送和 PR
它做什么
- 同步 main — 拉取最新,变基你的分支
- 运行测试 — 完整测试套件
- 审计覆盖 — 每个
/ship生成覆盖报告 - 推送分支 — 安全的 force push with lease
- 创建 PR — 用标准模板创建 PR
使用
/ship
输出:
正在运行 /ship 工作流...
┌─────────────────────────────────────────────────────────────┐
│ SHIP 工作流 │
├─────────────────────────────────────────────────────────────┤
│ 步骤 1: 同步 main │
│ ✅ 已拉取 origin/main │
│ ✅ 已变基 feature/add-auth │
│ │
│ 步骤 2: 运行测试 │
│ ✅ 47 个测试通过 │
│ ❌ 2 个测试失败 │
│ │
│ 🔧 正在修复测试失败... │
│ - auth.test.ts:23: 缺失 mock │
│ - api.test.ts:45: 错误断言 │
│ ✅ 测试已修复,重新运行 │
│ ✅ 全部 49 个测试通过 │
│ │
│ 步骤 3: 覆盖审计 │
│ 覆盖率: 78% │
│ 目标: 80% │
│ │
│ 低于目标的文件: │
│ - src/auth/login.ts: 65% │
│ - src/api/users.ts: 72% │
│ │
│ ⚠️ 覆盖率低于目标。添加测试? │
│ → 输入 'y' 添加测试,'n' 继续 │
│ │
│ 步骤 4: 推送分支 │
│ ✅ 已推送 feature/add-auth 到 origin │
│ │
│ 步骤 5: 创建 PR │
│ ✅ PR #42 已创建 │
│ 标题: Add authentication system │
│ 分支: feature/add-auth → main │
│ │
│ 审查 URL: https://github.com/owner/repo/pull/42 │
└─────────────────────────────────────────────────────────────┘
Ship 工作流完成。PR 等待审查。
测试框架引导
如果没有测试框架,/ship 会创建一个:
未检测到测试框架。
正在创建测试基础设施:
- jest.config.js
- tests/setup.ts
- tests/example.test.ts
✅ 测试框架已初始化
✅ 运行示例测试: PASS
将你的测试添加到 tests/ 目录。
覆盖率门槛
| 门槛 | 行为 |
|---|---|
| < 70% | 阻止: 无法发布 |
| 70-80% | 警告: 提示添加测试 |
| > 80% | 通过: 继续创建 PR |
| > 90% | 优秀: 无警告 |
Force push with lease
安全的强制推送,检查远程状态:
git push --force-with-lease origin feature/add-auth
如果远程有你没有的提交,推送失败(防止覆盖他人工作)。
/land-and-deploy — 合并 → 部署
它做什么
- 合并 PR — 压缩合并到 main
- 等待 CI — 监控 CI 状态,失败时阻止
- 部署 — 平台特定部署
- 验证生产 — 健康检查、冒烟测试
使用
/land-and-deploy
输出:
正在运行 /land-and-deploy 工作流...
┌─────────────────────────────────────────────────────────────┐
│ LAND AND DEPLOY │
├─────────────────────────────────────────────────────────────┤
│ 步骤 1: 合并 PR │
│ ✅ PR #42 已审批 │
│ ✅ 已压缩合并到 main │
│ 提交: Add authentication system (#42) │
│ │
│ 步骤 2: 等待 CI │
│ 正在监控 CI 状态... │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% │
│ │
│ ✅ CI 通过 (3m 24s) │
│ - lint: PASS │
│ - test: PASS │
│ - build: PASS │
│ - typecheck: PASS │
│ │
│ 步骤 3: 部署 │
│ 平台: Vercel │
│ │
│ 正在部署... │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% │
│ │
│ ✅ 已部署到生产 │
│ URL: https://myapp.com │
│ 部署 ID: dpl_abc123 │
│ │
│ 步骤 4: 验证生产 │
│ ✅ 健康检查: 200 OK │
│ ✅ 冒烟测试: 登录正常 │
│ ✅ 响应时间: 124ms │
│ │
│ 部署完成于 2026-04-07 14:32:05 │
└─────────────────────────────────────────────────────────────┘
部署成功。监控已激活。
运行 /canary 检查部署后健康状态。
平台检测
| 平台 | 部署命令 |
|---|---|
| Vercel | vercel --prod |
| Netlify | netlify deploy --prod |
| AWS Amplify | amplify push |
| Railway | railway up |
| Fly.io | fly deploy |
| 自定义 | .deploy.sh 脚本 |
CI 超时
默认: 15 分钟。通过 .gstack/config.yml 配置:
ci:
timeout: 20m
required_checks:
- lint
- test
- build
冒烟测试
默认冒烟测试检查:
- 健康端点 (
/health或/api/health) - 主页加载 (200 OK)
- 关键用户流程(登录,如果有认证)
/canary — 部署后监控
监控什么
- 控制台错误 — 部署站点上的浏览器控制台错误
- 性能回归 — 页面加载时间 vs 基线
- 错误率 — 日志中的 API 错误率
- 用户侧问题 — 关键流程仍然工作
使用
/canary
输出:
正在为 myapp.com 运行 canary 监控...
┌─────────────────────────────────────────────────────────────┐
│ CANARY 监控 │
├─────────────────────────────────────────────────────────────┤
│ 持续时间: 5 分钟 │
│ │
│ 📊 控制台错误 │
│ ✅ 0 个错误检测到 │
│ │
│ 📊 性能 │
│ 主页: 124ms (基线: 120ms) │
│ 仪表板: 156ms (基线: 150ms) │
│ ✅ 无回归 (>10% 门槛) │
│ │
│ 📊 API 错误率 │
│ ✅ 0.1% (目标: <1%) │
│ │
│ 📊 用户流程 │
│ ✅ 登录: 正常 │
│ ✅ 仪表板: 渲染正常 │
│ ✅ API 调用: 响应正常 │
│ │
│ ─────────────────────────────────────────────────────────────│
│ CANARY 状态: 健康 │
│ │
│ 所有指标在门槛内。 │
│ 生产环境稳定。 │
└─────────────────────────────────────────────────────────────┘
Canary 通过。部署确认健康。
运行 /benchmark 更新性能基线。
门槛
| 指标 | 健康 | 警告 | 严重 |
|---|---|---|---|
| 控制台错误 | 0 | 1-5 | >5 |
| 性能回归 | <10% | 10-20% | >20% |
| API 错误率 | <1% | 1-5% | >5% |
自动回滚
如果 canary 检测到严重问题:
🔴 严重: 性能回归 35%
主页: 162ms (基线: 120ms)
错误率: 12%
正在启动回滚...
┌────────────────────────────────────────────┐
│ 回滚 │
├────────────────────────────────────────────┤
│ 之前部署: dpl_prev456 │
│ 当前部署: dpl_abc123 │
│ │
│ ✅ 已回滚到 dpl_prev456 │
│ ✅ 生产已恢复 │
│ │
│ 重新部署前请调查失败原因。 │
└────────────────────────────────────────────┘
/benchmark — 性能基线
跟踪什么
- 页面加载时间
- Core Web Vitals
- API 响应时间
- 打包大小
使用
/benchmark
输出:
正在运行性能基准测试...
┌─────────────────────────────────────────────────────────────┐
│ 性能基准测试 │
├─────────────────────────────────────────────────────────────┤
│ 页面: 主页 │
│ ─────────────────────────────────────────────────────────────│
│ 加载时间: 124ms │
│ First Contentful Paint: 89ms │
│ Largest Contentful Paint: 124ms │
│ Time to Interactive: 156ms │
│ Cumulative Layout Shift: 0.02 │
│ │
│ 页面: 仪表板 │
│ ─────────────────────────────────────────────────────────────│
│ 加载时间: 156ms │
│ First Contentful Paint: 120ms │
│ Largest Contentful Paint: 156ms │
│ Time to Interactive: 180ms │
│ Cumulative Layout Shift: 0.01 │
│ │
│ 打包大小 │
│ ─────────────────────────────────────────────────────────────│
│ main.js: 45KB │
│ vendor.js: 120KB │
│ CSS: 28KB │
│ 总计: 193KB │
│ │
│ ─────────────────────────────────────────────────────────────│
│ 比较 │
│ ─────────────────────────────────────────────────────────────│
│ 之前基线: 2026-04-01 │
│ │
│ 主页加载: 124ms vs 120ms (+4ms, +3.3%) │
│ 仪表板加载: 156ms vs 150ms (+6ms, +4%) │
│ 打包大小: 193KB vs 190KB (+3KB, +1.6%) │
│ │
│ ✅ 全部在 10% 门槛内 │
│ │
│ 基线已更新到 2026-04-07 │
└─────────────────────────────────────────────────────────────┘
基准测试完成。基线已保存。
前后比较
发布后运行:
/benchmark --compare
显示与之前基线的差异,高亮回归。
/setup-deploy — 一键配置
它做什么
检测你的部署平台并创建配置。
使用
/setup-deploy
输出:
正在检测部署平台...
┌─────────────────────────────────────────────────────────────┐
│ 部署配置 │
├─────────────────────────────────────────────────────────────┤
│ 检测到: Vercel │
│ │
│ 正在检查要求: │
│ ✅ vercel CLI 已安装 │
│ ✅ 项目已关联 │
│ ✅ 生产分支: main │
│ │
│ 已创建配置: │
│ .gstack/deploy.yml │
│ │
│ platform: vercel │
│ branch: main │
│ health_check: /api/health │
│ smoke_tests: │
│ - login │
│ - dashboard │
│ │
│ ✅ 部署配置完成 │
│ │
│ PR 合并后用 /land-and-deploy 部署。 │
└─────────────────────────────────────────────────────────────┘
完整发布流程示例
完整工作流
# 1. Ship: 推送代码,创建 PR
/ship
# 2. 人工在 GitHub 审批 PR
# 3. Land and deploy: 合并 → CI → 部署
/land-and-deploy
# 4. Canary: 监控 5 分钟
/canary
# 5. Benchmark: 更新性能基线
/benchmark
# 6. 文档发布(下一篇教程)
/document-release
时间线
14:00 /ship 完成,PR #42 开放
14:15 人工审批 PR
14:16 /land-and-deploy 开始
14:19 CI 通过 (3m)
14:21 部署完成 (2m)
14:21 /canary 开始
14:26 /canary 通过
14:27 /benchmark 更新
14:28 /document-release
总计: 从 ship 到生产 28 分钟
技能快速参考
| 命令 | 用途 | 持续时间 |
|---|---|---|
/ship |
推送 + PR | 2-5m |
/land-and-deploy |
合并 → 部署 | 5-10m |
/canary |
部署后监控 | 5m |
/benchmark |
性能基线 | 1m |
/setup-deploy |
一键平台配置 | 1m |
/ship --skip-tests |
紧急发布 | 30s |
总结
gstack 中的发布工程提供:
- 完整 CI/CD 管道 — Ship → Deploy → Monitor → Benchmark
- 测试引导 — 缺失时创建框架
- 覆盖审计 — 每次发布检查覆盖
- 平台检测 — 自动检测 Vercel、Netlify 等
- 自动回滚 — Canary 在严重问题时触发回滚
关键要点
- ✅ 运行
/ship创建 PR - ✅ 人工审批 PR(人工门控)
- ✅ 审批后运行
/land-and-deploy - ✅ 运行
/canary进行 5 分钟监控 - ✅ 运行
/benchmark更新基线
系列导航:
- ←上一篇: 教程 9:设计审查实时版
- →下一篇: 教程 11:文档与回顾
- 返回: 系列索引