关于 update-release-notes
用于维护 tldraw/tldraw 仓库发布说明的技能,面向负责 SDK 发布流程的开发者。它涵盖 PR 收集、说明更新与归档,以及草拟 GitHub Release 同步。
主要功能
- 01检测发布阶段和来源分支
- 02从 main 或 production 收集 PR
- 03添加条目并清理过期说明
- 04归档已发布版本说明
- 05同步草拟 GitHub Release
适用场景
- 01在开发期间更新 next.mdx
- 02从 production 准备发布周说明
- 03发布后归档版本说明
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tldraw/ tldraw --skill update-release-notes安装后在 Claude Code 中输入/update-release-notes确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/fetch-pr-batch.shget-changelog-status.shget-new-prs-from-main.shget-new-prs.shupdate-draft-release.sh详细介绍
更新发布说明
此技能负责维护 tldraw/tldraw 仓库中发布说明的运营任务:向 next.mdx 添加新的 PR 条目,并在发布新版本时归档发布。
此技能从 tldraw-internal 仓库运行,但操作的是 tldraw/tldraw 的本地克隆。
设置
开始之前,克隆 tldraw 仓库:
git clone https://github.com/tldraw/tldraw.git /tmp/tldraw
所有脚本都将仓库路径作为第一个参数。请在仓库根目录下运行脚本命令,将 <skill-dir> 替换为包含此 SKILL.md 的目录。所有文件编辑都发生在此克隆中。最后,从克隆中提交并推送。
发布周期
SDK 每四周发布一次。发布前一周,SDK 会冻结,并从 main 切出 production 分支。在发布周内,只有热修复会被 cherry-pick 到 production。
next.mdx 中的发布说明最终必须反映 production 分支上发布的内容。然而,在冻结前约 3 周的开发期内,我们从 main 构建发布说明,以免它们为空。状态脚本会根据上一次小版本发布的日期检测我们处于哪个阶段:
- 开发周(
source: "main",距上次小版本发布 <3 周):从上次发布标签以来的main中收集 PR。这些是初步的——如果某些 PR 被回退或 production 的 cherry-pick 不同,它们可能不会发布。 - 冻结周(
source: "production",距上次小版本发布 3+ 周):使用git cherry针对上一个发布分支从production分支收集 PR。只包含在冻结前合入或被热修复到 production 的 PR。从main累积的、不在 production 上的条目将被剔除。
next.mdx 本身也必须在发布发布之前位于 production 上,而不仅仅是描述它。prepack.ts 从正在发布的检出中生成随 tldraw npm 包一起发布的 RELEASE_NOTES.md,使用 next.mdx 作为正在发布的版本的条目。production 在冻结期间仅通过热修复移动,因此合并到 main 的发布说明 PR 只有在同时带有 dotcom-hotfix-please 标签时才能到达它(见步骤 10)。发布前的检查是空 diff:
git diff --stat origin/production origin/main -- apps/docs/content/releases/next.mdx
流程
1. 检查状态
运行状态脚本以确定版本和 diff 分支:
<skill-dir>/scripts/get-changelog-status.sh /tmp/tldraw
返回:
source- 要么是"main"(开发周),要么是"production"(发布周)diff_branch(例如v4.3.x)- 用于 diff 的分支(当source为"production"时使用)last_tag(例如v4.4.0)- 上次发布标签(当source为"main"时使用)latest_release- 最近发布的版本- 是否需要归档
2. 处理归档(如需要)
如果自 next.mdx 中的 last_version 以来发布了新版本:
- 将
next.mdx内容复制到vX.Y.0.mdx(例如v4.3.0.mdx) - 更新新文件中的 frontmatter:
- 将
title设置为版本号 - 更新日期
- 在 frontmatter 之后添加 GitHub 发布链接
- 将
- 将新版本添加到
apps/docs/content/getting-started/releases.mdx的发布索引中:- 在相应
## v{major}.x部分的顶部添加一行 - 格式:
- [vX.Y](/releases/vX.Y.0) - 简要描述 - 描述应为引言段落中发布亮点的简短摘要(3-5 个关键特性,逗号分隔)
- 如果需要新的主版本部分,请将其创建在上一部分之上
- 在相应
- 重置
next.mdx:- 将
last_version字段更新为新发布 - 清空内容部分
- 保留文件结构以累积新更改
- 将
3. 查找新的 PR
具体方法取决于第 1 步中的 source 字段。
如果 source 为 "production"(发布周):
获取自上一个发布以来 production 分支上的 PR 编号:
<skill-dir>/scripts/get-new-prs.sh /tmp/tldraw <diff_branch>
这里使用 git cherry(与 extract-draft-changelog.tsx 相同的方法)来比较 origin/production 与 origin/<diff_branch> 之间的补丁。与 git log 不同,git cherry 通过比较补丁内容而非提交哈希,能够正确处理被 cherry-pick 的热修复提交。
如果 source 为 "main"(开发周):
获取自上一个发布标签以来 main 上的 PR 编号:
<skill-dir>/scripts/get-new-prs-from-main.sh /tmp/tldraw <last_tag>
这里使用 git cherry 来比较 origin/main 与发布标签之间的补丁,排除那些已被 cherry-pick 到 production 并已在发布中交付的提交。
两个脚本的输出:
- stdout:从提交信息中提取的 PR 编号(每行一个)
- stderr:没有 PR 编号的提交(通常是热修复或直接提交)
4. 解析热修复提交
检查第 3 步的 stderr,找出任何没有 PR 编号的 [HOTFIX] 提交。对于每个与 SDK 相关的提交(跳过仅涉及 dotcom 的),找到对应的 PR:
gh pr list -R tldraw/tldraw --state merged --search "<hotfix title keywords>" --json number,title --jq '.[]'
同时检查带有 sdk-hotfix-please 标签的 PR,但要确认它们确实已合入 production —— 该标签也用于上一个发布分支(例如 v4.3.x)上的补丁发布:
gh pr list -R tldraw/tldraw --label "sdk-hotfix-please" --state merged --limit 20 --json number,title,mergedAt
将任何匹配到的 PR 编号添加到第 3 步得到的 production PR 列表中。
5. 获取 PR 详情
批量获取所有 PR 信息:
<skill-dir>/scripts/fetch-pr-batch.sh <pr1> <pr2> ...
6. 移除过期条目
将完整的 PR 列表(来自第 3 步 + 第 4 步)与 next.mdx 中已引用的 PR 编号进行比较。从 next.mdx 中移除所有 PR 不在当前集合中的条目。
- 当
source为"production"时:这会清理开发期间从main累积但未进入 production 的条目。这些是在 production 分支切出之后才合入main的 PR,不会在本次发布中交付。 - 当
source为"main"时:这会移除已被回滚或以其他方式不再位于 main 上的 PR 条目。由于完整集合要到 production 分支切出时才最终确定,此处的清理力度较小。
移除某个条目时,还要检查它是否被某个精选的 “What's new” 板块引用,并一并移除该板块。如果简介段落提到了被移除的功能,也要更新该段落。
7. 添加新条目
对于每个尚未出现在 next.mdx 中的 PR:
- 根据风格指南的分类规则检查 PR 标签和描述
- 跳过应当省略的 PR(参见风格指南)
- 跳过修复同一发布周期内引入的 bug 的 PR(即由
next.mdx中已有、但未出现在上一个发布中的其他 PR 所导致的 bug) - 如果某个 PR 是回滚,还要从
next.mdx中移除被回滚的原始 PR 的条目(如果存在) - 将条目添加到合适的板块
- 在有充分理由时将重要变更提升到精选板块
8. 验证
检查以下各项:
next.mdx中引用的每个 PR 都在当前 PR 集合中(根据source来自main或production)- PR 链接正确
- 社区贡献者已署名
- 各板块顺序正确
- 破坏性变更已用 💥 标记
- 弃用项已用 🔜 标记
注意:当 source 为 "main" 时,条目是初步的。当 production 分支切出、source 切换为 "production" 后,其中一些条目可能会被清理。
9. 更新草稿 GitHub release
让下一个 minor 版本的草稿 GitHub release 与 next.mdx 保持同步。publish-new.ts 会按名称(vX.Y.0)找到草稿,并在发布时原样发布其正文,因此在此处镜像 next.mdx 意味着 GitHub release 与文档发布页面始终一致。
<skill-dir>/scripts/update-draft-release.sh /tmp/tldraw
该脚本会:
- 从
next.mdx中的last_version推导目标版本(minor 递增,patch 为0—— 例如v5.2.0→v5.3.0)。 - 使用
next.mdx的正文(去除 frontmatter)作为 release 正文。 - 若草稿不存在则创建,或编辑名为
vX.Y.0的现有草稿。它会拒绝改动已发布的 release,也会拒绝写入空正文。
主版本发布 / 版本覆盖: 上述 minor 递增是默认行为,因为几乎所有发布都是 minor。publish-new.ts 按它解析出的版本查找草稿 —— 对于 --bump major(或覆盖版本),该版本来自 NPM,而不是 minor 递增,因此硬编码的 minor 会导致草稿命名错误,getDraftRelease 也会失败。当下一版本是主版本或以其他方式不是下一个 minor 时,请显式传入目标版本,以便草稿名称匹配:
<skill-dir>/scripts/update-draft-release.sh /tmp/tldraw v6.0.0
每次更新 next.mdx 后都要运行此脚本,包括发布周的运行。在第二次(发布后)运行时,上一个 minor 的草稿已经发布,因此这会基于重置后的 last_version 为新的下一个 minor 创建一个全新草稿。
10. 推送更改
编辑 next.mdx(以及任何归档文件)后,从 tldraw 克隆中提交并推送。不要向分支提交添加 [skip ci]:只要存在该标记,必需的拉取请求检查就永远不会启动。下面的 PR 标题则会把该标记加到最终的 squash-merge 提交上。
cd /tmp/tldraw
BRANCH="update-release-notes-$(date -u +%Y%m%d-%H%M)"
git checkout -b "$BRANCH"
git add apps/docs/content/releases/
git commit -m "docs(releases): update release notes"
git push -u origin "$BRANCH"
然后使用 ../pr/SKILL.md 工作流和 ../write-pr/SKILL.md 中的标准创建 PR:
- 标签:添加
docs-hotfix-please(gh pr edit <number> --add-label docs-hotfix-please,或在gh pr create时使用--label docs-hotfix-please)。没有它,合并到main永远不会把说明 cherry-pick 到当前发布分支(vX.Y.x),因此更新永远不会到达 tldraw.dev——而这正是本次运行的全部目的。 - 冻结周标签:当
source为"production"时,还要添加dotcom-hotfix-please。这会把已合并的 PR cherry-pick 到hotfixes,再从那里到production,而发布发布时prepack.ts正是从production读取next.mdx(见「发布周期」)。仅靠docs-hotfix-please永远不会触及production。合并后,用「发布周期」中的 diff 命令确认 hotfix 已落地;如果 dotcom hotfix bot 失败,请手动把 squash 提交 cherry-pick 到一个从hotfixes拉出的分支上,从提交信息中去掉任何[skip ci]标记,并针对hotfixes打开一个[HOTFIX]PR。 - 标题:
docs(releases): update release notes [skip ci]——[skip ci]必须放在 PR 标题中,因为 GitHub 的 squash-merge 会把 PR 标题用作合并提交的主题,而正是这个合并提交需要跳过 CI。对该 PR 执行 Squash-merge(不要 rebase,也不要 create-a-merge-commit),这样恰好只有一个带[skip ci]的提交落到基础分支上。 - 变更类型:
other - 测试计划:删除编号列表(没有手动测试步骤)。取消勾选单元测试和端到端测试。
- 发布说明:省略此部分(内部文档工作,对用户无影响)
- 描述段落:以 "In order to..." 开头,并说明来源(
main或production)以及更新了什么(添加了新条目、修剪了过时条目、执行了归档、同步了草稿 GitHub 发布等) - 包含一个 Code changes 表格,其中有一行
Documentation
为什么 [skip ci] 只在 PR 标题中:分支提交需要运行必需的拉取请求检查。GitHub 的 squash merge 使用 PR 标题作为合并提交,因此当仅含说明的变更落到 main 上时,该标记会跳过推送工作流。
[skip ci] 不会干扰 docs-hotfix-please 标签:trigger-sdk-hotfix.yml 在 pull_request_target 上运行,GitHub 的 skip-ci 标记不影响它,并且 hotfix 脚本会从 cherry-pick 的提交中去掉 skip-ci 标记,因此发布分支的推送仍会触发发布工作流。当带标签的 PR 被合并时,触发器会触发;若之后要再次触发,请在已合并的 PR 上移除并重新添加该标签。一旦 #10629 修复,dotcom-hotfix-please 也同样如此;在此之前,其 bot 会保留该标记,而它打开的 hotfix PR 永远无法运行检查。
绝不要在 PR 正文的其他任何地方写入字面字符串 [skip ci]。GitHub 会从整个 squash-merge 提交信息中读取该标记,而 PR 正文会成为该提交的正文。
last_version 字段
next.mdx 的 frontmatter 包含一个 last_version 字段,用于跟踪最近发布的版本。它决定了哪些 PR 是「新的」并需要被添加。
SDK 发布工作流
在 SDK 发布期间,此技能会运行 两次,以将文档站点置于发布后的状态:
- 第一次运行 —— 用将在本次发布中交付的所有 PR 更新
next.mdx(冻结周期间来源为"production")。这确保发布说明在发布前是完整的。草拟发布步骤(第 9 步)会根据此next.mdx同步草稿版vX.Y.0GitHub 发布,因此publish-new.ts已备好完成的说明可供发布。该 PR 同时带有docs-hotfix-please和dotcom-hotfix-please(第 10 步),以便该文件到达站点的v(X.Y-1).x以及包的production。 - 门禁 —— 在任何人发布之前,
next.mdx在production和main上必须完全一致("发布周期"中的 diff 命令不输出任何内容),并且草稿版vX.Y.0发布必须与next.mdx匹配。如果之后对next.mdx的某次编辑在未带 dotcom hotfix 的情况下落到了main,或发生在最后一次草稿同步之后,请先修复该问题。 - 将发布推送到 NPM —— 这在此技能之外进行。
publish-new.ts发布第 1 步创建的草稿发布,而prepack.ts会将production的next.mdx作为该版本的RELEASE_NOTES.md条目烘焙进tldraw包。发布会将版本号提升推送到main,而不是production。 - 第二次运行 —— 现在发布已发布,状态脚本将检测到
needs_archive: true。此工作流在production推送时运行,而发布不会产生这样的推送,因此第二次运行发生在下一次production推送时(通常是来自main的发布后 dotcom 发布),或当有人手动派发update-release-notes.yml时。此运行会:- 将
next.mdx归档为带版本的文件(例如v4.5.0.mdx) - 将新版本添加到发布索引(
releases.mdx) - 用新的
last_version重置next.mdx - 查找冻结期间(自发布标签以来)落到
main上的 PR,并将它们添加到全新的next.mdx - 为新的下一个次要版本同步一份全新的草稿(第 9 步),因为之前的草稿现已发布
- 需要
docs-hotfix-please(而非dotcom-hotfix-please:一旦包发布,production对说明不再重要),以便它落到新的vX.Y.x分支并重新发布站点
- 将
第二次运行之后,文档站点会反映已发布的版本,而 next.mdx 已经为下一周期的变更抢得先机。
参考资料
- 风格指南:参见
../shared/release-notes-guide.md,了解发布说明文章应包含哪些内容以及如何排版。 - 写作指南:参见
../../VOICE.md,了解语气和风格约定。 - 脚本:参见
scripts/了解自动化辅助工具,包括用于同步草稿版 GitHub 发布的update-draft-release.sh