Files
ai-proj-helper/docs/design/release-draft-gate.md
John Qiu 23ea8fdca5 feat: 融合 devflow-claude P0 批机制 (REQ-20260416-0017)
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 机制落地
2026-04-16 21:02:29 +09:30

254 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 命令的核心做法:**
1. merge PR 不直接部署
2. 创建一个 **draft release**(草稿)
3. **需要人工在 Gitea/GitHub 平台点 "Publish" 按钮** 才触发部署
4. Draft 可以审查 SQL migration、回滚脚本、changelog 等"产物清单"
5. 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` 表:**
```sql
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), -- 生成的 tagpublish 后才有
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**
```http
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 改造:**
```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 APIdraft + 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 只生成简单反向 DDLCREATE→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(数据模型)开始实施