P0-1: SessionStart Hook — hooks/session-context.sh 从分支名解析 REQ-ID,调 MCP API 查询需求详情注入 system-reminder P0-2: PreToolUse Hook — hooks/pre-tool-confirm.sh 拦截生产推送、force push、docker prod 容器操作、git reset --hard 等 P0-3: Release Draft 闸门设计文档 — docs/design/release-draft-gate.md 完整架构 + 渐进式落地路径(拆 7 个子任务延后) 附最小可用脚本 hooks/release-draft.sh 创建 Gitea draft release P0-4: Memory 隔离规则 — 写入 req-prd / req-design / req-workflow 禁止 auto-memory 污染模板产出物(章节结构、字段定义、文档结构) P0-5: CLAUDE.md 架构检查 + 架构片段库 dev-coding skill 执行前检查架构关键词 新增 templates/claude-md-snippets/ 含 Go+Gin / React+AntD / Vue+Element / MCP+TS / generic 五套骨架 P0-6: /commit 分支保护自动化 — 新 skill dev-commit-plugin 保护分支自动建功能分支 + Conventional Commits + REQ-XXX 自动关联 安装: bash hooks/install.sh 后续: P0-3 完整实现拆 7 个子任务(P0-3.1 ~ P0-3.7) 建议先部署 hooks 跑 1-2 周观察,再推进 Release 机制落地
7.8 KiB
7.8 KiB
Release Draft 闸门机制 — 设计文档
REQ: REQ-20260416-0017 P0-3 状态: 设计阶段 创建时间: 2026-04-16
1. 背景
当前问题
ai-proj 当前 CI/CD 流程(.gitea/workflows/build.yaml):
push 到 main → 自动 build 镜像 → 自动部署生产
这个链路没有"最后一道人工闸门"。merge develop→main 的 PR 一合并,生产就开始部署。一旦合并,只能事后回滚。
典型事故场景:PR 评审时漏了某个改动,merge 后立即推到线上,5 分钟后发现问题,但已经影响用户 5 分钟。
借鉴方案
devflow-claude /req:release 命令的核心做法:
- merge PR 不直接部署
- 创建一个 draft release(草稿)
- 需要人工在 Gitea/GitHub 平台点 "Publish" 按钮 才触发部署
- Draft 可以审查 SQL migration、回滚脚本、changelog 等"产物清单"
- Publish 后才打 tag + 触发 build.yaml
2. 目标
- 在 merge main 和"真正部署"之间插入 人工 publish 闸门
- 提供 release 产物清单预览(SQL migration / 回滚脚本 / changelog)
- 支持 一键回滚(从 draft release 追溯回滚脚本)
- 与现有 ai-proj MCP 工具链集成
3. 架构设计
3.1 流程对比
当前流程:
[feat/xxx] → PR → merge develop → 测试
[develop] → PR → merge main → ✗ 立即触发 build.yaml → 生产部署
新流程:
[feat/xxx] → PR → merge develop → 测试
[develop] → PR → merge main → Gitea draft release(待审查)
↓
人工 publish
↓
tag 推送 + 触发 build.yaml → 生产部署
3.2 组件职责
| 组件 | 新增/改造 | 职责 |
|---|---|---|
| ai-proj backend | 新增 | /api/v1/releases REST API(创建 draft、publish、查询、回滚) |
| mcp-task-bridge | 新增工具 | create_release_draft / publish_release / list_releases / get_release / rollback_release |
| Gitea Actions | 改造 | build.yaml 触发条件改为 release.published 事件 |
release skill |
新增 | AI 侧命令封装(/release new, /release publish, /release rollback) |
| release-draft.sh | 新增脚本 | 本地命令行工具,用于在 CI 外手动创建 draft |
3.3 数据模型
新增 releases 表:
CREATE TABLE releases (
id SERIAL PRIMARY KEY,
display_id VARCHAR(64) UNIQUE NOT NULL, -- e.g. "RELEASE-20260416-001"
version VARCHAR(64) NOT NULL, -- e.g. "v1.2.0"
title VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(32) NOT NULL, -- draft / published / rolled_back
git_base_ref VARCHAR(255) NOT NULL, -- e.g. previous tag "v1.1.9"
git_head_ref VARCHAR(255) NOT NULL, -- e.g. commit sha after merge
git_tag VARCHAR(64), -- 生成的 tag,publish 后才有
changelog_md TEXT NOT NULL, -- 自动生成的 changelog
sql_migration_paths TEXT[], -- 合并的 SQL 文件路径列表
sql_rollback_md TEXT, -- 回滚脚本
gitea_release_id BIGINT, -- Gitea 上的 release ID
gitea_release_url VARCHAR(512),
created_by INT REFERENCES users(id),
published_by INT REFERENCES users(id),
published_at TIMESTAMP,
rolled_back_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
3.4 API 设计
| Endpoint | 作用 | 权限 |
|---|---|---|
POST /api/v1/releases/drafts |
创建 draft release(自动推导版本、生成 changelog) | 开发者 |
POST /api/v1/releases/:id/publish |
发布(推 tag、触发部署) | 需确认 |
GET /api/v1/releases |
列表 | 所有人 |
GET /api/v1/releases/:id |
详情 | 所有人 |
POST /api/v1/releases/:id/rollback |
回滚到上一版本 | 管理员 |
3.5 Gitea 集成
创建 draft release(调 Gitea API):
POST /api/v1/repos/{owner}/{repo}/releases
{
"tag_name": "v1.2.0",
"target_commitish": "main",
"name": "v1.2.0",
"body": "...<changelog>...",
"draft": true
}
build.yaml 改造:
# Before
on:
push:
branches: [main]
# After
on:
release:
types: [published]
workflow_dispatch: # 保留手动触发
关键变化:release.published 事件只在草稿被 publish 时触发,merge main 不再自动触发。
4. 用户流程(典型场景)
4.1 开发者发版
1. 合并 PR 到 main(照旧)
2. 在 Claude Code 里:/release new
- AI 读 git log,自动推导版本号
- 汇总 SQL migration
- 生成 changelog
- 生成回滚脚本
- 展示产物清单,等用户确认
3. 确认后:MCP create_release_draft → 后端 API → Gitea draft
4. 收到 Slack/企微通知:"draft release v1.2.0 已创建,请审查"
5. 打开 Gitea 查看产物清单
6. 点 "Publish release" 按钮
7. CI/CD 自动触发 → 生产部署
4.2 回滚
1. /release rollback v1.2.0
2. MCP rollback_release → 后端执行回滚 SQL → 重新部署上一版本镜像
3. 记录到 releases 表:status=rolled_back
5. 渐进式落地路径(P0-3 拆分子任务)
由于 P0-3 完整实现涉及后端 + MCP + CI/CD + skill 四个层面,不建议单会话完成。拆分为:
| 子任务 | 范围 | 风险 |
|---|---|---|
| P0-3.1 | 后端 release model + migration | 低(只是建表) |
| P0-3.2 | 后端 /api/v1/releases API(draft + publish) | 中 |
| P0-3.3 | MCP 工具 create_release_draft / publish_release | 中 |
| P0-3.4 | release skill 创建 |
低 |
| P0-3.5 | Gitea draft release 集成 | 中 |
| P0-3.6 | build.yaml 改为 release.published 触发 | 高(影响所有人的发版流程) |
| P0-3.7 | 回滚能力 | 中 |
推荐落地节奏:
- 先做 P0-3.1 ~ P0-3.5(构建基础能力)
- 保留旧 push-to-main 流程作为 fallback
- 跑 2 周观察
- 再做 P0-3.6(切换 CI/CD 触发源)
- 最后 P0-3.7(回滚能力)
6. 风险与应对
R1: build.yaml 触发源切换影响所有开发者
影响:目前大家习惯 "merge main 即部署",切换后需等 publish
应对:
- 上线前 1 周发邮件 + 企微通知
- 提供手动触发(workflow_dispatch)作为应急入口
- 文档化新流程
R2: 回滚脚本自动生成不够可靠
影响:复杂 migration(如数据迁移)的回滚无法自动推导
应对:
- AI 只生成简单反向 DDL(CREATE→DROP 等)
- 复杂情况标记
⚠️ 需手工补全 - 回滚 SQL 由人工审查后纳入 draft release
R3: draft release 被忘记 publish
影响:功能开发完但生产没部署
应对:
- 企微机器人每天检查超 24h 未 publish 的 draft,发提醒
- 管理员 dashboard 显示 draft 列表
7. 验收标准
releases表创建,migration 落地/api/v1/releases/drafts创建 draft(至少支持最小字段)- MCP
create_release_draft工具可用 - 能从 Claude Code 一键创建 Gitea draft release
- build.yaml 支持
release.published触发 - 至少跑通 1 次完整流程(draft → 人工 publish → 自动部署)
- 回滚脚本自动生成覆盖 >80% 的 DDL 场景
8. 参考
- devflow-claude:
plugins/req/commands/release.md - REQ-20260416-0017(母需求)
- 当前 build.yaml:
/Users/donglinlai/coding/qiudl/new-ai-proj/.gitea/workflows/build.yaml - Gitea Release API: https://docs.gitea.com/api/next/#tag/repository/operation/repoCreateRelease
9. 下一步行动
- 本文档提交评审
- 评审通过后拆 7 个子任务(P0-3.1 ~ P0-3.7)并分别关联到 REQ-20260416-0017
- 从 P0-3.1(数据模型)开始实施