Compare commits

...

1 Commits

Author SHA1 Message Date
Betterlol 3ad282d395 [stage-init][workflow] add release pipeline automation workflow
- Add release-pipeline-architecture.md with Mermaid architecture diagrams
- Add release-pipeline-workflow.md with 7-step end-to-end workflow
- Includes GitLink-specific defenses: status_id filtering, PR/commit dedup,
  BREAKING CHANGE body scanning, dry-run safety, batch notification anti-rate-limit
2026-06-12 21:15:49 +08:00
2 changed files with 425 additions and 0 deletions

View File

@ -0,0 +1,113 @@
# Release Pipeline — Architecture
> 自动化发布管理 Pipeline 架构说明
> 第八届 CCF 开源创新大赛 · Track 1: GitLink CLI · 子赛题三
---
## 1. 总体架构
```mermaid
graph TB
subgraph Layer1["Layer 1: 数据采集(只读)"]
A1["release +list"] --> |当前版本号 上次发布时间| A2
A3["pr +list --state merged"] --> |合并 PR 列表| A2
A4["ci +builds"] --> |CI 状态| A2
A5["compare +view"] --> |Commit 列表 Diff 统计| A2
A6["issue +list"] --> |已关闭 Issue 列表| A2
end
subgraph Layer2["Layer 2: AI 分析"]
direction TB
A2["数据聚合与清洗"]
A2 --> B1["PR/Commit 穿透去重"]
B1 --> B2["Issue status_id 二次过滤"]
B2 --> B3["语义化版本推断 (Major/Minor/Patch)"]
B3 --> B4["Changelog 分类生成"]
B4 --> B5["就绪度检查 (PR/CI/Issue)"]
B5 --> B6["通知列表生成"]
end
subgraph Layer3["Layer 3: 执行(写入)"]
C1["release +create"] --> C2{"用户确认?"}
C2 --> |是| C3["创建 Release"]
C2 --> |否| C4["终止"]
C6["issue +comment"] --> C7{"选择模式"}
C7 --> |A 全量自动| C8["逐个通知 遇错跳过"]
C7 --> |M 逐个确认| C9["每次询问 y/N"]
C7 --> |S 跳过| C10["跳过通知"]
end
B5 --> C1
B6 --> C6
```
---
## 2. 步骤流(含决策节点)
```mermaid
flowchart LR
Start([开始]) --> S1["Step 1: release +list<br/>获取当前版本"]
S1 --> S2{"有 Release?"}
S2 --> |否| S2a["设 baseline v0.0.0"]
S2a --> S3
S2 --> |是| S3["Step 2: pr +list --state merged<br/>获取合并 PR"]
S3 --> S4{"有新 PR?"}
S4 --> |否| Stop1([终止: 无需发布])
S4 --> |是| S5["Step 3: ci +builds<br/>检查 CI 状态"]
S5 --> S6{"CI 通过?"}
S6 --> |失败| S6a["⚠️ 警告用户"]
S6a --> S6b{"继续?"}
S6b --> |否| Stop2([终止])
S6b --> |是| S7
S6 --> |通过/未知| S7["Step 4: compare +view<br/>获取变更提交"]
S7 --> S8["Step 5: issue +list<br/>获取已解决 Issue"]
S8 --> S9["Step 6: AI 分析<br/>去重 → 分类 → 版本推断 → Changelog"]
S9 --> S10["Step 7a: release +create<br/>创建 Release(--dry-run)"]
S10 --> S11{"用户确认?"}
S11 --> |否| Stop3([终止])
S11 --> |是| S12["实际创建 Release"]
S12 --> S13["Step 7b: issue +comment<br/>通知模式选择"]
S13 --> S14[执行通知]
S14 --> End([完成])
```
---
## 3. 数据流
```mermaid
flowchart TB
subgraph Input["输入"]
I1["release +list"] --> |tag_name: v1.2.3| P
I2["pr +list --state merged"] --> |PR 列表| P
I3["ci +builds"] --> |CI 状态| P
I4["compare +view --head master --base v1.2.3"] --> |Commit 列表| P
I5["issue +list --state all"] --> |Issue 列表| P
end
subgraph Process["处理"]
P["数据聚合"]
P --> D1["PR/Commit 核销去重"]
P --> D2["Issue status_id 过滤<br/>(3=已解决 / 5=关闭)"]
D1 --> C["Changelog 生成"]
D2 --> C
end
subgraph Output["输出"]
C --> O1["release +create --tag v1.3.0 --body ..."]
C --> O2["issue +comment --number N<br/>(逐个通知)"]
end
```
---
## 4. 文件结构
```
doc/workflows/
├── release-pipeline-architecture.md # 本文件:架构图
├── release-pipeline-workflow.md # 工作流说明文档
└── release-pipeline-transcript.md # Agent 对话记录
```

View File

@ -0,0 +1,312 @@
# 自动化发布管理 Pipeline
## 场景描述
开源项目维护者在发版时通常需要手动完成:检查哪些 PR 已合并待发布、检查 CI 是否绿色、翻阅提交历史写 Release Notes、创建 Release、通知相关 Issue。本工作流将上述步骤串联为一条完整的自动化链AI Agent 按步骤执行,维护者只需确认关键决策点。
## 工作流架构
![架构图](release-pipeline-architecture.md)
三层架构:
- **Layer 1: 数据采集** — 只读命令获取所有上下文
- **Layer 2: AI 分析** — 数据清洗、去重、分类、版本推断
- **Layer 3: 执行写入** — 创建 Release + 通知 Issue默认 dry-run
---
## 前置条件
- `gitlink-cli` 已安装并认证(`gitlink-cli auth status`
- 具备目标仓库的 `write` / `maintain` 权限(执行写操作时需要)
- GitLink Token 有效期 **7 天**,过期需 `gitlink-cli auth login` 重新登录
---
## 执行步骤
### Step 1获取当前发布信息
确定当前最新版本号和 version_id。
```bash
gitlink-cli release +list --owner <owner> --repo <repo> --limit 1 --format json
```
```json
{
"ok": true,
"data": {
"releases": [
{
"version_id": 42,
"tag_name": "v1.2.3",
"created_at": "2026-05-01T10:00:00Z"
}
]
}
}
```
**提取字段**`tag_name`(当前版本号)、`version_id`Release ID、`created_at`(上次发布时间)。
**无 Release 时**:假设 baseline 为 `v0.0.0`,首个 Release 推荐 `v0.1.0`
---
### Step 2检查已合并 PR
获取自上次发布以来合并的 PR。
```bash
gitlink-cli pr +list --owner <owner> --repo <repo> --state merged \
--sort-by updated_at --sort-direction desc --limit 50 --format json
```
AI Agent 从返回中过滤 `updated_at` > 上次发布 `created_at` 的 PR。
> **排序字段注意**`pr +list` 的排序字段为 `updated_at`,与 `issue +list``updated_on` 不同Agent 需按命令组使用正确字段名。
**决策点**:若无新合并 PR`len(prs) == 0`),终止并提示"自上次发布以来无变更"。
---
### Step 3检查 CI 状态
验证 master 分支的 CI 是否通过。
```bash
gitlink-cli ci +builds --owner <owner> --repo <repo> --format json
```
| CI 状态 | 行为 |
|---------|------|
| `success` | ✅ 继续 |
| `failed` | ⚠️ 警告用户,询问是否继续 |
| `running` | ⏳ 等待或询问是否跳过 |
| 无 CI/401 | 跳过CI 未配置) |
---
### Step 4获取变更提交
通过 `compare +view` 获取 commit 列表和 diff 统计。
```bash
gitlink-cli compare +view --owner <owner> --repo <repo> \
--head master --base v1.2.3 --format json
```
> **GitLink 主分支是 `master`**(非 GitHub 的 `main`),所有分支参数均使用 `master`
> ⚠️ **BREAKING CHANGE 检查要点**Conventional Commits 中 `BREAKING CHANGE` 通常写在 commit 正文的 **Footer最后几行**而非标题。Agent 必须检查 `commit.body` 或 PR 描述中的完整文本。
```json
{
"commits": [
{
"sha": "abc123",
"message": "feat: add user avatar upload (#234)",
"body": "Implement avatar upload feature\n\nBREAKING CHANGE: avatar API response format changed",
"author": { "login": "zhangsan" }
}
],
"total_commits": 18,
"files_changed": 24
}
```
---
### Step 5获取已解决 Issue
> ⚠️ **GitLink 状态过滤防御机制**
>
> GitLink API 的 `--state closed` 过滤**不精确**,且 Issue 状态分为 `1=新增, 2=正在解决, 3=已解决, 5=关闭`。被修复的 Issue 可能停留在"已解决(3)"而未演进到"关闭(5)"。
>
> **解决方案**:不相信 API 的 state 过滤结果。改用 `--state all` 拉取全量列表AI Agent 在本地根据 `status_id == 3 || status_id == 5` 做二次精确筛选。
```bash
gitlink-cli issue +list --owner <owner> --repo <repo> \
--state all --sort-by issues.updated_on --sort-direction desc \
--limit 50 --format json
```
> **排序字段注意**`issue +list` 命令组的排序字段为 `issues.updated_on`,与 `pr +list``updated_at` 不同Agent 务必使用正确的字段名。
AI 过滤逻辑:
1. 拉取全部近期有更新的 Issue`--state all`
2. 本地按 `status_id == 3`(已解决)或 `status_id == 5`(关闭)筛选
3. 再过滤 `updated_on` > 上次发布 `created_at` 的条目
---
### Step 6生成 ChangelogAI 分析)
聚合 Step 1-5 的数据,生成结构化的 Release Notes。
#### ⚠️ PR 与 Commit 穿透去重
Step 2 的合并 PR 列表与 Step 4 的 commit 列表存在天然重叠PR 的提交历史包含在 commit 中)。**必须做关联核销,否则 Changelog 条目会翻倍。**
```
Agent 去重逻辑:
1. 优先以 PR 标题作为 Changelog 条目来源(经过 Code Review质量最高
2. 扫描 commit 列表,做以下核销:
- "Merge pull request #234" → 丢弃,由 PR 条目覆盖
- "feat: add avatar (#234)" → 关联到 PR #234,以 PR 描述为准
- "fix: critical hotfix"(无 PR 编号的孤立 commit→ 保留为独立条目
3. 最终 Changelog 来源:
├── 已关联 PR 的 commit → 去重,用 PR 标题
├── 孤立 commit → 保留为独立条目
└── 已关闭 Issue → 补充到对应分类
```
#### 语义化版本推断
```
1. 扫描 BREAKING CHANGE两处
a. commit.body 的 Footer 部分
b. PR 描述的 Body
→ 任一处有 → MAJOR 升级 (v1.2.3 → v2.0.0)
2. 有 feat: 前缀(无 breaking→ MINOR 升级 (v1.3.0)
3. 仅有 fix:/perf:/docs: 等 → PATCH 升级 (v1.2.4)
```
#### 分类规则
| 类型 | Changelog 分类 | 版本影响 |
|:---|:--------------|:--------:|
| `BREAKING CHANGE` | ⚠️ 不兼容变更 | MAJOR |
| `feat:` | ✨ 新功能 | MINOR |
| `fix:` | 🐛 Bug 修复 | PATCH |
| `perf:` | ⚡ 性能优化 | PATCH |
| `refactor:` | ♻️ 代码重构 | PATCH |
| `docs:` | 📝 文档 | PATCH |
| `test:` | ✅ 测试 | PATCH |
| `ci:` / `build:` | 🔧 CI/CD | PATCH |
#### Release Notes 模板
```markdown
## v1.3.0 (2026-06-12)
### ✨ 新功能
- feat(user): 新增用户头像上传功能 (#234)
- feat(search): 支持全文搜索 (#256)
### 🐛 Bug 修复
- fix(login): 修复登录超时问题 (#245)
### 📊 统计
- 18 commits | 24 files changed | +1200 -300
```
---
### Step 7a创建 Release写入默认 dry-run
> ⚠️ **安全措施**:所有写操作**默认 `--dry-run` 预览**,用户确认后才实际执行。
```bash
# 第一步dry-run 预览
gitlink-cli release +create \
--owner <owner> --repo <repo> \
--tag v1.3.0 \
--name "v1.3.0" \
--body "## v1.3.0\n\n### ✨ 新功能\n..." \
--target master \
--dry-run
# 第二步:用户确认后,移除 --dry-run 实际创建
gitlink-cli release +create \
--owner <owner> --repo <repo> \
--tag v1.3.0 \
--name "v1.3.0" \
--body "## v1.3.0\n\n### ✨ 新功能\n..." \
--target master
```
> **验证**:创建后用 `release +list` 确认,再用 `release +view --id <version_id>` 查看详情。
> ⚠️ `release +view` 必须使用 `version_id`(整数),不能用 tag 名称。
---
### Step 7b通知相关 Issue写入
> ⚠️ **防频控与防单点失败机制**
>
> 批量通知可能因 Issue 数量多而触发 Rate Limit或单条评论失败导致整体中断。
> Agent 先展示待通知清单,让用户选择通知模式:
```
请选择通知模式:
[A] 全量自动通知 — 逐个执行,遇错跳过
[M] 逐个确认 — 每次评论前询问 y/N
[S] 跳过通知 — 不执行任何 Issue 评论
```
```bash
# 单条通知命令
gitlink-cli issue +comment --owner <owner> --repo <repo> \
--number <issue_number> \
--body "🎉 此问题已在 v1.3.0 中修复,请更新验证。"
```
**容错策略**:若某条评论失败,记录错误日志并继续执行下一条,**不阻塞整体 Pipeline**。Rate Limit 触发时等待 60 秒重试 1 次。
---
## 预期输出
工作流执行完毕后生成一份 Markdown 报告:
```markdown
# 发布报告v1.2.3 → v1.3.0
## 版本信息
- 当前版本v1.2.3 → 目标版本v1.3.0
- 升级类型MINOR新增功能
## 就绪度检查
- ✅ 已合并 PR18 个
- ✅ CI 状态:通过
- ✅ 已关闭 Issue6 个
## Release Notes
(完整 Changelog
## 执行结果
- ✅ Release v1.3.0 创建成功
- ✅ 6 个 Issue 已通知
```
---
## 注意事项
### GitLink 特有防御汇总
| 防御点 | 说明 |
|--------|------|
| **Issue 状态二次过滤** | 不信任 `--state closed`,用 `status_id == 3 \|\| 5` 本地筛 |
| **BREAKING CHANGE 查 Body** | 不仅查 commit title还要查 commit.body 的 Footer |
| **主分支为 master** | 所有 `--target` / `--base` 参数使用 `master` |
| **排序字段名差异** | `pr +list``updated_at``issue +list` 用 `issues.updated_on` |
| **release +view 用 version_id** | 不能传 tag_name否则返回 HTML 页面 |
| **默认 dry-run** | 所有写操作首次执行均为预览模式 |
### 已知限制
- `ci +builds` 可能因 CI 未激活返回 401此时跳过检查
- `compare +view` 的 commit.body 字段可能因 API 版本不同而缺失
- 初次发布(无历史 Release需走初始化路径无法做比较
## 扩展思路
- **集成 gitlink-changelog Skill**:将 Changelog 生成逻辑抽取为独立 Skill可在其他工作流中复用
- **预发布流程**:支持 `--prerelease` 创建 beta/rc 版本
- **Hotfix 流程**:支持从特定 tag 创建 hotfix 分支并快速发布 PATCH 版本
- **跨仓库发布**:支持同时发布关联的多个仓库(如前端 + 后端 + 文档)