mcpField
U
update-release-notes

update-release-notes

github.com/tldraw开发51.1k113 次安装今天更新
代码仓库

关于 update-release-notes

用于维护 tldraw/tldraw 仓库发布说明的技能,面向负责 SDK 发布流程的开发者。它涵盖 PR 收集、说明更新与归档,以及草拟 GitHub Release 同步。

主要功能

  1. 01检测发布阶段和来源分支
  2. 02从 main 或 production 收集 PR
  3. 03添加条目并清理过期说明
  4. 04归档已发布版本说明
  5. 05同步草拟 GitHub Release

适用场景

  1. 01在开发期间更新 next.mdx
  2. 02从 production 准备发布周说明
  3. 03发布后归档版本说明

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tldraw/tldraw --skill update-release-notes

安装后在 Claude Code 中输入/update-release-notes确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

scripts/
fetch-pr-batch.sh
get-changelog-status.sh
get-new-prs-from-main.sh
get-new-prs.sh
update-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 以来发布了新版本:

  1. 将 next.mdx 内容复制到 vX.Y.0.mdx(例如 v4.3.0.mdx)
  2. 更新新文件中的 frontmatter:
    • 将 title 设置为版本号
    • 更新日期
    • 在 frontmatter 之后添加 GitHub 发布链接
  3. 将新版本添加到 apps/docs/content/getting-started/releases.mdx 的发布索引中:
    • 在相应 ## v{major}.x 部分的顶部添加一行
    • 格式:- [vX.Y](/releases/vX.Y.0) - 简要描述
    • 描述应为引言段落中发布亮点的简短摘要(3-5 个关键特性,逗号分隔)
    • 如果需要新的主版本部分,请将其创建在上一部分之上
  4. 重置 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:

  1. 根据风格指南的分类规则检查 PR 标签和描述
  2. 跳过应当省略的 PR(参见风格指南)
  3. 跳过修复同一发布周期内引入的 bug 的 PR(即由 next.mdx 中已有、但未出现在上一个发布中的其他 PR 所导致的 bug)
  4. 如果某个 PR 是回滚,还要从 next.mdx 中移除被回滚的原始 PR 的条目(如果存在)
  5. 将条目添加到合适的板块
  6. 在有充分理由时将重要变更提升到精选板块
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 发布期间,此技能会运行 两次,以将文档站点置于发布后的状态:

  1. 第一次运行 —— 用将在本次发布中交付的所有 PR 更新 next.mdx(冻结周期间来源为 "production")。这确保发布说明在发布前是完整的。草拟发布步骤(第 9 步)会根据此 next.mdx 同步草稿版 vX.Y.0 GitHub 发布,因此 publish-new.ts 已备好完成的说明可供发布。该 PR 同时带有 docs-hotfix-please 和 dotcom-hotfix-please(第 10 步),以便该文件到达站点的 v(X.Y-1).x 以及包的 production。
  2. 门禁 —— 在任何人发布之前,next.mdx 在 production 和 main 上必须完全一致("发布周期"中的 diff 命令不输出任何内容),并且草稿版 vX.Y.0 发布必须与 next.mdx 匹配。如果之后对 next.mdx 的某次编辑在未带 dotcom hotfix 的情况下落到了 main,或发生在最后一次草稿同步之后,请先修复该问题。
  3. 将发布推送到 NPM —— 这在此技能之外进行。publish-new.ts 发布第 1 步创建的草稿发布,而 prepack.ts 会将 production 的 next.mdx 作为该版本的 RELEASE_NOTES.md 条目烘焙进 tldraw 包。发布会将版本号提升推送到 main,而不是 production。
  4. 第二次运行 —— 现在发布已发布,状态脚本将检测到 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

评论

支持 Markdown