
🎯 学 gstack 的发布后文档同步系统:不是手动更新"忘了改的 README",而是自动检测需要更新的文档文件、从 git log 生成 CHANGELOG 条目、更新架构图和 API 文档、同步版本号——让每次发布都有完整、准确、一致的文档。 ⏱️ 预计时间:25 分钟
[!quote]- 📖 原Skill精要 技能名称:document-release 核心功能:发布后文档更新。读取所有项目文档、交叉引用 diff、更新 README/ARCHITECTURE/CONTRIBUTING/CLAUDE.md 以匹配发布内容、打磨 CHANGELOG 语调、清理 TODOS、可选升级 VERSION。让每次发布都有完整、准确、一致的文档。 所属体系:gstack 虚拟工程团队 协作关系:建议在 PR 合入或代码发布后([[L6-25-发布上线管理|ship]] 之后)运行
§1 课程概览
document-release 解决的是"文档腐烂"问题——代码更新了但文档停留在三个月前。它通过 git diff 驱动的智能检测(变更了 src/api/ → 更新 API.md;变更了 package.json → 更新 README 技术栈部分)自动识别需要更新的文档文件。核心能力覆盖四个方面:CHANGELOG 自动生成(面向用户的 "You can now..." 风格 + release-summary 数据表)、README/ARCHITECTURE/API 文档的交叉更新、API 文档漂移检测(对比 OpenAPI spec 与实际路由文件)、版本号一致性检查。与 /ship 的明确分工:ship 创建初步 CHANGELOG 和版本基本结构,document-release 补全到生产级质量,land-and-deploy 验证文档就绪。
[!tip] 白话小课堂 你有没有遇到过——接手一个项目,打开 README 按步骤配置,第一步就报错,因为文档里写的依赖版本是两年前的。document-release 就是解决这个的:每次发版自动检查哪些文档过时了,从代码变更反推文档更新,让文档始终反映"现在的事实"而非"当时的计划"。
§2 文档腐烂——发布的隐形杀手
为什么需要 document-release?
真实情况: → README 说"支持 Node 14+"但项目早就用了 Node 20 → CHANGELOG 上次更新是 3 个月前 → API 文档中新增的端点没有记录 → 架构图少了一个微服务 → VERSION 文件还是 v0.1.0 但实际已经是 v1.2.0
文档腐烂的代价: → 新成员花 3 天搞清楚"实际架构"vs"文档说的架构" → API 消费者发现文档中的端点不存在 → 安全审计时发现"代码中有的"和"文档中记载的"不一致 → CHANGELOG 缺失意味着无法追溯变更——谁加了这个功能?
document-release 的核心承诺
→ 每次 /ship 或 /land-and-deploy 后自动建议运行 → 检测需要更新的文档文件 → 从 git log 生成 CHANGELOG → 更新版本引用 → 确保文档反映"现在的事实"而不是"当时的计划"
💡 白话小课堂:你有没有遇到过这种情况——你接手一个项目,打开 README 按步骤配置,结果第一步就报错,因为文档里写的依赖版本是两年前的。
§3 文档检测——哪些文件需要更新
自动检测策略
document-release 通过以下方式判断哪些文档需要更新:
1. Git diff 驱动的文档检测
→ git diff origin/main...HEAD --name-only → 检查变更文件与文档文件的关系 → 变更了 src/api/ → 需要更新 API.md 或 OpenAPI spec → 变更了 src/components/ → 需要更新 COMPONENTS.md → 变更了 package.json dependencies → 需要更新 README 的技术栈部分 → 变更了 ARCHITECTURE.md 中提到的文件 → 需要审查架构图
2. 项目配置文件扫描
→ 扫描项目中存在的文档文件 → 常见文档文件: README.md, CHANGELOG.md, ARCHITECTURE.md, CONTRIBUTING.md, API.md, docs/, openapi.yaml → 判断哪些与本次变更相关
3. VERSION 文件检测
→ 检查 VERSION 文件是否在本次变更中被更新 → 如果 VERSION 未更新 → 标记为"需要 bump" → 检查 CHANGELOG 是否有新版本条目 → 检查 PR 标题中的版本号是否与 VERSION 一致
4. API 文档漂移检测
→ 如果项目有 OpenAPI/Swagger spec → 对比 spec 中的端点与实际路由文件 → 新增路由但 spec 中缺少 → 标记 → 删除路由但 spec 中仍有 → 标记
§4 CHANGELOG 生成——从 commit 到发布说明
自动化 CHANGELOG 生成
生成原则
→ 以用户能理解的语言描述变更 → "You can now..." 风格,不是 commit message 列表 → 按类别分组:Added / Changed / Fixed / Deprecated → 内部变更放在 "For contributors" 部分
生成流程
- git log origin/main...HEAD --oneline → 获取提交列表
- 将提交按类型分类: → feat: → Added → fix: → Fixed → refactor/chore/docs: → Changed / For contributors → BREAKING CHANGE → 单独突出
- 合并相关提交(3 个关于同一功能的 commit → 1 个条目)
- 用自然语言重写每个条目
- 检查是否有遗漏的功能(对比 git diff --stat)
CHANGELOG 条目标准
→ 开头动词:Added / Changed / Fixed / Deprecated → 面向用户:用户能"做什么"而不是"代码改了什么" → 例:✓ "You can now export reports as PDF" ✗ "Added PDF export functionality to ReportController" → 破坏性变更用 BREAKING 标记
Release Summary(版本摘要)
每个版本以 release-summary 开头: → 两行标题(10-14 词,如判决般有力) → 导览段落(3-5 句,具体的、有数据的) → "The N numbers that matter" 表格(BEFORE / AFTER / Δ) → 结束段落(对用户意味着什么) → 然后是 "### Itemized changes"
防止覆盖
→ 使用 Edit 而非 Write 修改 CHANGELOG → 只添加新条目,不修改已有条目 → 不删除其他版本的条目
⚠️ 避坑指南: CHANGELOG 最容易被滥用的写法是"把 commit message 直接复制粘贴"。你去看很多开源项目的 CHANGELOG,一长串
fix: adjusted margin in login form、refactor: extracted helper function——这些对用户来说毫无意义。
§5 其他文档更新——不只是 CHANGELOG
README 更新
→ 检测新增命令/功能 → 更新 Usage 部分 → 检测依赖变更 → 更新 Prerequisites 部分 → 检测配置变更 → 更新 Configuration 部分 → 检测 API 变更 → 更新 Quick Start 中的示例
ARCHITECTURE 更新
→ 检测新增模块/服务 → 更新架构图描述 → 检测模块间关系变更 → 更新依赖关系说明 → 检测数据流变更 → 更新数据流文档 → framework agnostic → 描述"是什么"而非"用什么实现"
API 文档更新
→ 如果有 OpenAPI/Swagger spec → 更新端点定义 → 如果有 docs/api/ → 更新对应的 .md 文件 → 新增端点 → 添加文档 → 删除/废弃端点 → 标记 deprecated → 参数变更 → 更新参数表
VERSION 文件
→ 确保 VERSION 文件已 bump → 确保 package.json 中的版本一致 → 确保所有版本引用一致(README badge、安装命令等)
§6 与 /ship 的协作——发布流程的最后一步
/ship → /document-release → /land-and-deploy
标准发布流程:
- /ship 创建 PR(包含初步 CHANGELOG)
- /document-release 完善文档(PR 审查期间)
- /land-and-deploy 合入到生产(文档已就绪)
/ship 中已经做的文档工作
→ /ship Step 13: 生成 CHANGELOG 条目 → /ship Step 10: 更新 VERSION → /ship Step 4: 更新 PR 描述
/document-release 补充做的
→ 更新 README/ARCHITECTURE/API docs 中遗漏的部分 → 生成 release summary(带数据表) → 检查 API 文档与代码的一致性 → 标记模块间的文档漂移
land-and-deploy 的文档检查
→ Step 3.5d: 检查 /document-release 是否已运行 → 如果已运行 → ✓ → 如果未运行但有新功能 → WARNING → 如果只改了 docs → 跳过检查
🔑 核心秘诀:/ship、/document-release、/land-and-deploy 三者之间的分工有一条清晰的时间线——ship 负责"创建发布的基本结构"(包括初步 CHANGELOG),document-release 负责"把文档补全到生产级质量",land-and-deploy 负责"验证文档是否真的全了再合入"。
§7 电商 Skill 案例:电商平台发版CHANGELOG自动生成
🛒 实战案例:某电商App的后端团队维护200+ API端点,OpenAPI spec (openapi.yaml)是客户端SDK自动生成的输入源。长期痛点:开发者加新端点时经常忘记更新spec,导致文档与代码不一致——客户端说“文档里/api/orders/:id/cancel返回{status: ‘cancelled’}”,实际返回{order_status: ‘CANCELLED’, cancelled_at: ‘2026-...’}——客户端crash。每次都要在Slack上问“这个端点到底返回什么?”
- document-release运行:
/document-release检测git diff origin/main...HEAD→自动关联文档映射——src/api/routes/orders.ts→API.md+openapi.yaml、src/services/inventory.ts→ARCHITECTURE.md、package.json→README.md。- 发现的问题:(1)
/api/orders/:id/cancel响应schema与代码不一致——spec记录{status: string}但代码实际返回{order_status: string, cancelled_at: datetime}(字段名从status改为order_status+新增cancelled_at时间戳);(2)新端点/api/products/bulk(批量商品查询)在路由文件中已实现但openapi.yaml中完全缺失;(3)/api/cart/*三个端点spec与代码一致✓;(4)CHANGELOG中遗漏了一个breaking change——订单状态枚举从CANCELLED重命名为CANCELED(拼写修正),但旧客户端仍使用旧枚举值。- 自动修复:(1)更新openapi.yaml中
/api/orders/:id/cancel的响应schema(字段名+类型同步);(2)从路由文件中提取/api/products/bulk端点的完整定义(path/parameters/response schema)补充到spec;(3)CHANGELOG补上breaking change条目——**BREAKING**: Order status enum ‘CANCELLED’ renamed to ‘CANCELED’. Update your client code accordingly.;(4)修复后重新验证spec与代码一致性——全部通过✓。- CI中SDK自动生成:在CI pipeline中添加步骤——
openapi-generator generate -i openapi.yaml -g typescript-fetch -o client-sdk/→git diff --exit-code client-sdk/检测SDK是否与spec同步→如果有diff则阻断构建并提示“SDK out of sync with spec, please run document-release”。确保Android/iOS/Web三个客户端始终使用与后端一致的API定义。
- 电商文档特有关注点:订单状态枚举在代码和文档中必须完全一致(PENDING→CONFIRMED→SHIPPED→DELIVERED,不能代码用CONFIRMED文档用APPROVED);支付回调webhook payload格式必须与实际完全匹配(字段名/类型/顺序,微信支付对签名验证的body字节序敏感);错误码一致性(文档中的error codes与代码返回的一致——不能文档说
ORDER_NOT_FOUND代码返回order_missing);分页参数统一(page/page_sizevsoffset/limit,一旦选择一种就不能在另一端点用另一种)。
🔑 启示:文档漂移是API生命周期中最隐蔽的技术债务——代码在持续演进,文档在持续漂移,两者的差距每多一天就多一分客户端崩溃的风险。document-release的价值不在“生成好看的CHANGELOG”——而在让文档与代码的差距从“不定期发现”变成“每次发布前必检”。
[!info] 参考来源 此案例参考了 Shopify API Docs 的维护模式和 OpenAPI Generator 项目的 spec-to-SDK 自动生成流程。
§8 结构拆解
document-release 结构模板
核心特征
- 管理对象: 项目文档与代码的一致性(README、CHANGELOG、ARCHITECTURE、API docs、VERSION)
- 核心原则: git diff 驱动的智能关联——变更了哪个目录就更新对应的文档,而非全量更新所有 .md 文件
- 关键设计: CHANGELOG 面向用户措辞("You can now...")+ API 文档漂移检测(OpenAPI spec vs 路由文件)+ 防止覆盖(Edit 而非 Write)
通用结构
- 变更检测层: git diff origin/main...HEAD --name-only → 关联文档映射(src/api/ → API.md, src/components/ → COMPONENTS.md, package.json → README)
- CHANGELOG 生成层: git log 分类(feat→Added, fix→Fixed, BREAKING CHANGE→突出)→ 合并相关提交 → 自然语言重写 → release-summary(标题+导览+数据表+尾声)
- 文档更新层: README(Usage/Prerequisites/Configuration)→ ARCHITECTURE(模块/依赖/数据流)→ API docs(OpenAPI spec 同步 + 漂移检测)
- 一致性验证层: VERSION 文件 bump 检查 → package.json 版本一致性 → README badge/安装命令版本引用
- 协同接口: /ship(初步 CHANGELOG + VERSION)→ document-release(补全到生产级质量)→ land-and-deploy(文档就绪验证)
§9 掌握检验
Q1:document-release 检测哪些文档需要更新的核心机制是什么?
- A) 每次运行时更新项目中所有 .md 文件
- B) 通过 git diff 分析变更文件与文档文件的关联关系(如 src/api/ 变更 → 更新 API.md)
- C) 只检查 CHANGELOG.md 和 README.md 两个文件
- D) 依赖开发者在 PR 描述中手动列出需要更新的文档
Q2:CHANGELOG 生成中,"Added PDF export functionality to ReportController"为什么被认为是不好的条目写法?
- A) 因为它没有包含版本号
- B) 因为它是面向开发者的技术描述而非面向用户的"你能做什么"——好的写法是 "You can now export reports as PDF"
- C) 因为它超过了字数限制
- D) 因为它没有使用英文写作
Q3:Release Summary 的结构包含"两行标题"、"导览段落"、"The N numbers that matter"数据表、和"结束段落"——这四个部分分别的目标读者是谁?各部分分别传达什么信息?如果缺少"数据表"(只有文字描述),对产品经理和运维团队分别有什么不同的信息缺失?
Q4:API 文档漂移检测中,"spec 中的响应 schema 与代码不一致"如何在技术上被检测到?请描述从"路由文件提取响应结构"到"对比 OpenAPI spec"到"标记不一致"的完整流程。并分析:如果这个不一致没有被检测到,客户端 SDK 自动生成的代码会导致什么后果?
Q5:document-release 与 /ship 之间有明确的分工——/ship 生成初步 CHANGELOG,document-release 补全文档到生产级质量。但如果一个团队跳过 document-release 直接用 land-and-deploy(门禁只 WARNING 不阻止),事后可能出现什么问题?请从"下次发布时"和"新成员接手项目时"两个时间点分别分析。
Q6:电商场景中,为什么"订单状态枚举一致性"(PENDING → CONFIRMED → SHIPPED → DELIVERED)是 document-release 的重点检查项?假设文档中写的是 {status: 'cancelled'} 但代码返回的是 {order_status: 'CANCELLED', cancelled_at: '2026-...'}——这个不一致会导致的完整故障链是什么(从前端到后端到用户)?如果这个不一致在双11大促当天被发现,修复成本与在 document-release 阶段发现有什么数量级的差异?
§10 答案
点击查看答案
Q1:B —— document-release 通过 git diff 驱动的文档检测:git diff origin/main...HEAD --name-only 检查变更文件与文档文件的关联关系。
Q2:B —— "Added PDF export functionality to ReportController" 是面向开发者的技术描述,暴露了代码的内部结构(ReportController 是开发者的细节,用户不需要也不应该知道)。
Q3:各部分目标读者和信息:①两行标题(10-14 词)→ 所有人——版本的核心价值在 5 秒内传达;②导览段落(3-5 句)→ 产品经理 + 用户——这个版本做了什么、为什么重要;③"The N numbers that matter"表格(BEFORE/AFTER/Δ)→ 技术负责人 + 运维——用数据量化变更的影响(如"API 响应时间从 350ms → 120ms, -65%"),这是最容易被跳过的部分但也是最有力的部分;④结束段落(2-4 句)→ 所有人——对用户意味着什么的总结。缺少数据表的影响:产品经理失去了量化判断"这个版本是否值得推送给用户"的依据(只有描述没有数据);运维失去了"部署后应该关注哪些指标"的具体参考(部署后不知道性能预期是什么)。
Q4:检测流程:①从路由文件中提取响应结构——解析路由处理函数的返回类型/序列化逻辑(如 TypeScript 的返回类型注解、Python 的 response_model、Ruby 的 serializer);②从 OpenAPI spec 中读取对应端点的 response schema;③对比两者——字段名、类型、必填/可选、嵌套结构;④不一致 → 标记并记录差异(spec 中 {status: string} → 代码中 {order_status: string, cancelled_at: datetime})。SDK 自动生成的后果:客户端 SDK 从 spec 生成类型定义(TypeScript 接口、Swift 结构体、Kotlin 数据类)→ spec 错误 → SDK 类型错误 → 客户端按错误类型解析 JSON → order.status 为 undefined → 客户端 crash 或显示空白。用户看到的:点了"取消订单"→ 页面白屏或报错"未知错误"。
Q5:下次发布时的后果:上一个版本的文档不全 → /ship 在创建新 PR 时读取文档状态 → 发现 README/ARCHITECTURE 与实际代码不一致 → 无法准确判断"这个新功能会不会和已有的矛盾" → 审查效率下降。新成员接手的后果:打开 README 按步骤配置 → 第一步就报错(文档写的依赖版本是旧的)→ 翻代码找问题 → 3 天过去了还没跑通环境 → "文档=谎言"的印象形成 → 以后不再信任文档 → 知识传递完全依赖口口相传。跳过 document-release 的代价是累积性的——每次跳过的成本很小,但 10 次跳过后文档与代码的差距变得不可弥合。
Q6:故障链:前端按文档解析 response.status → 得到 undefined(因为实际字段是 order_status)→ 前端条件判断 if (status === 'cancelled') 永远为 false → "已取消"状态的订单在前端显示为"未知状态"或"处理中" → 用户看到订单已取消但页面显示"处理中" → 用户以为取消失败 → 重复取消操作 → 后端收到重复的取消请求(可能触发边界情况 bug)→ 用户投诉。修复成本差异:document-release 阶段发现 → 改 spec 一行 JSON(5 分钟);双11当天发现 → 客户端团队紧急更新 SDK → 移动端需要重新构建 + 应用商店审核(iOS 审核通常 24-48 小时,双11期间更慢)→ Android 可以热更新但 Web 端需要紧急部署 → 三个客户端版本的修复时间窗口不统一 → 部分用户 3 天后还在用有 bug 的旧版本 → GMV 损失 = 修复延迟 × 每小时订单量 × 受影响用户比例。成本差异:5 分钟 vs 3 天 + 不可计量的 GMV 损失。
(5/6 通过)
延伸阅读
- 下一步:[[L6-30-版本发布报告|版本发布报告]] —— 用 landing-report 一览所有 PR 的合入队列和版本号状态
- [[L6-28-代码冻结与解冻|代码冻结与解冻]] —— 大促封网期间的文档变更管理
- [[L6-25-发布上线管理|发布上线管理]] —— /ship 创建初步 CHANGELOG,document-release 补全

评论区
共 0 条评论