mcpField
R
release-plannotator

release-plannotator

github.com/backnotprop开发9.7k291 次安装今天更新
代码仓库

关于 release-plannotator

release-plannotator 是指导 Plannotator 项目执行版本发布的技能,供维护者从编写发布说明到打标签发布时使用。流程涵盖贡献者调研、版本更新、构建检查及发布验证。

主要功能

  1. 01收集版本变更与贡献者信息
  2. 02起草并提交发布说明供审阅
  3. 03更新指定文件中的版本号
  4. 04按依赖顺序运行构建
  5. 05检查 Pi 扩展打包内容
  6. 06提交版本、创建标签并发布

适用场景

  1. 01准备新版本发布说明
  2. 02核对并更新多个包的版本
  3. 03验证扩展构建与发布包
  4. 04执行标签触发的发布流程

安装

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

$npx skills add https://github.com/backnotprop/plannotator --skill release-plannotator

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

包含的文件

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

references/
release-notes-v0.12.0.md
release-notes-v0.13.0.md
release-notes-v0.13.1.md

详细介绍

Plannotator 发布

整个流程分为四个阶段。阶段 1(发布说明)是大部分工作的所在——请先提交草稿供审核,再进入后续阶段。

阶段 1:起草发布说明

这是最重要的阶段。发布说明是每个版本面向公众的窗口,也是社区了解贡献者所作贡献得到认可的主要途径。

步骤 1:确定范围
  1. 查找最新的发布标签:git tag --sort=-v:refname | head -1
  2. 确定新版本号。如果不明确,请询问用户(patch、minor 或 major)。
  3. 收集自上一个标签以来的所有变更:
    • 使用 git log --oneline <last-tag>..HEAD 查看提交历史
    • 使用 git log --merges --oneline <last-tag>..HEAD 查看已合并的 PR
  4. 对每个 PR,使用 gh pr view <number> --json title,author,body,closedIssues,labels 获取详情。
步骤 2:调查贡献者

这一步至关重要。每位参与此次发布的人都应获得认可——不只是 PR 作者。

针对每个 PR 及其关联的问题,收集以下信息:

  • PR 作者——编写代码的人
  • 问题报告者——提交 Bug 报告或功能请求的人
  • 问题评论者——参与讨论并提供有用背景信息的人
  • 讨论发起者——发起相关 GitHub Discussions 的人
  • 功能请求者——检查关联的 "closes #N" 问题及其作者

使用 gh 调用 GitHub API:

# Get issue details including author
gh issue view <number> --json author,title,body

# Get issue comments to find participants
gh api repos/backnotprop/plannotator/issues/<number>/comments --jq '.[].user.login'

# Get PR review comments
gh api repos/backnotprop/plannotator/pulls/<number>/comments --jq '.[].user.login'
步骤 3:编写发布说明

阅读 references/ 中的参考发布说明,了解规范的模板结构。这些都是真实的过往版本发布说明——请遵循其语气、结构和详略程度。

  • release-notes-v0.13.0.md — 大型发布,包含 14 个 PR、3 位首次贡献者,以及叙述式的 "New Contributors" + "Contributors" 部分
  • release-notes-v0.12.0.md — 大型社区发布,包含 14 个 PR,其中 10 个来自外部贡献者,并设有详细的叙述式 "Contributors" 部分
  • release-notes-v0.13.1.md — 小型补丁发布,包含 2 个 PR、没有外部作者,"Community" 部分重点介绍问题报告者

请留意每份参考说明在致谢贡献者时采用的不同方式。选择适合此次发布贡献者情况的模式——有许多外部 PR 的发布适合采用叙述式的 "Contributors" 部分;由问题报告推动的补丁则适合采用更精简的 "Community" 部分。

将文件写入仓库根目录,命名为 RELEASE_NOTES_v<VERSION>.md。

结构
  1. X/Twitter 关注链接 — 第一行,始终相同:

    Follow [@plannotator](https://x.com/plannotator) on X for updates
    
  2. “错过了最近的版本发布?” 可折叠表格 — 从上一个版本的说明中复制,然后:

    • 将上一个版本(即当前版本的前一个版本)作为最新一行添加
    • 保留约 10-12 行;必要时删除最旧的行
    • 每行:版本链接 + 以逗号分隔的功能亮点(简短短语)
  3. “vX.Y.Z 有什么新内容” — 说明的核心

    • 开篇用 1-3 句话总结版本主题和范围。说明 PR 数量、外部贡献者提交的 PR 数量,以及是否有首次贡献者。
    • 每项主要功能或修复都单独设为一个 ### 小节,其中包含:
      • 描述性标题(不要照搬 PR 标题,应重新表述以便读者理解)
      • 用 1-4 段解释改了什么以及为何重要。具体、明确地说明原先存在的问题、这项改动的作用,以及用户会如何体验到它。
      • 底部注明来源:PR 链接、使用 closing [#N] 标注的关联 issue,以及贡献者署名
    • 次要改动放在 ### 其他改动 下,作为带粗体标题的列表项
  4. 安装 / 更新 — 标准内容块,从上一个版本的说明中读取并原样复用

  5. “改动内容” — 列出版本中每个 PR 的项目符号:

    - feat: descriptive PR title by @author in [#N](url)
    
  6. “新贡献者” — 如果有首次贡献者:

    - @username made their first contribution in [#N](url)
    
  7. “贡献者”或“社区” — 叙述性章节,感谢所有参与者:

    • 用一句话介绍 PR 作者完成的工作
    • 列出 issue 报告者和评论者,并说明他们报告或讨论的内容
    • 在最后用项目符号列表列出社区 issue 报告者
  8. 完整变更日志链接:

    **Full Changelog**: https://github.com/backnotprop/plannotator/compare/<prev-tag>...<new-tag>
    
写作指南
  • 重叙述,少堆砌。 使用清晰易读的文字。不要写成营销文案,也不要堆砌变更记录。用通俗语言解释改了什么,以及为什么值得关注。
  • 在适当之处使用项目符号。 用项目符号列举离散事项(其他改动、贡献者列表),用段落解释功能。
  • 避免陈词滥调和流行语。 不要说“令人兴奋”“颠覆性”“无缝”“强大”。只描述实际发生了什么。
  • 不要用俏皮话收尾。 不要在章节末尾加巧妙的俏皮话或总结性金句。让功能本身说明其价值。
  • 着眼于实际收益。 具体、可靠地描述改动内容及其对用户的意义。不要空谈愿景或炒作,只说明实际作用。
  • 不要过度使用破折号。 每个版本用一两个即可。如果发现破折号太多,请重构句子。
  • 注意语法结构。 变换句式。使用主动语态。明确说明主语和动作。
  • 贡献者标记。 使用 @username — 直接写 @ 提及,不要使用 [@user](url) 这样的 Markdown 链接。GitHub 会在发布说明中为直接写出的 @提及显示头像图标。这对感谢社区成员很重要。
  • 每位贡献者都很重要。 提及每一位提交 issue、发表影响决策的评论或参与讨论的人。社区是这个项目的命脉。
第 4 步:提交审核

将草稿写入仓库根目录下的 RELEASE_NOTES_v<VERSION>.md,并告知用户已准备好审核。不要对该文件执行 git add 或提交操作——发布说明按设计会保持未跟踪状态。等待用户反馈后再进入第 2 阶段。


阶段 2:版本号更新

更新这 7 个文件中的版本字符串(仅限这些文件——其他 package.json 文件使用占位版本号):

文件字段
根目录的 package.json"version"
apps/opencode-plugin/package.json"version"
apps/pi-extension/package.json"version"
apps/hook/.claude-plugin/plugin.json"version"
apps/copilot/plugin.json"version"
根目录的 openpackage.ymlversion:
packages/server/package.json"version"

读取每个文件,确认当前版本符合预期,然后以原子方式更新全部 7 个文件。

不要更新 VS Code 扩展(apps/vscode-extension/package.json)的版本——它有独立的版本管理。


阶段 3:构建

按依赖顺序运行构建:

bun run build:review    # 1. Code review editor (standalone Vite build)
bun run build:hook      # 2. Plan review + hook server (copies review's built HTML into hook dist)
bun run build:opencode  # 3. OpenCode plugin (copies built HTML from hook + review)
bun run build:pi        # 4. Pi extension (chains review → hook → pi internally, safe to run after 1-2)

build:pi 会在内部串联 review 和 hook,因此完成步骤 1-2 后,它只会运行 Pi 专属构建。

继续之前,请确认所有构建均成功。

Pi 对等性检查关卡

构建通过后,审查 Pi 扩展,确保所有服务端导入项都包含在发布包中。这有助于在缺失文件进入 npm 前发现问题。

  1. 检查导入项与 files 数组。 从 index.ts、server.ts、tool-scope.ts 以及 server/ 中的每个文件开始,追踪所有本地导入项(以 ./ 或 ../ 开头)。确认每个目标文件都由 apps/pi-extension/package.json 的 files 数组中的某个模式覆盖。

  2. 检查 vendor.sh 是否涵盖所有 shared/ai 导入项。 服务端文件中的每个 ../generated/*.js 导入项,都必须在 vendor.sh 的复制循环中有对应条目。如果在 packages/shared/ 或 packages/ai/ 中新增了共享模块或 AI 模块,并且 Pi 的服务端代码导入了该模块,则必须将其添加到 vendor.sh。

  3. 试运行打包。 运行 cd apps/pi-extension && bun pm pack --dry-run,并确认输出包含服务端导入的所有文件。特别留意自上次发布以来新增的文件。

  4. 快速冒烟测试。 确认构建后 generated/ 包含所有预期文件,尤其是新增文件(例如本次发布周期新增的共享模块)。

如果发现缺失项,请在继续阶段 4 之前修复。常见修复方式:

  • 将文件添加到 vendor.sh 的复制循环
  • 将文件或目录添加到 package.json 的 files 数组
  • 修正导入路径(Pi 使用 ../generated/,而不是 @plannotator/shared 或 @plannotator/ai)

阶段 4:提交、打标签并发布

  1. 提交版本号更新:

    chore: bump version to X.Y.Z
    

    仅暂存更新了版本号的 7 个文件。不要暂存发布说明文件(它有意保持未跟踪状态)。

  2. 创建并推送标签:

    git tag vX.Y.Z
    git push origin main
    git push origin vX.Y.Z
    

    推送 v* 标签会触发发布流水线(.github/workflows/release.yml)。

  3. 流水线会处理其他所有工作:

    • 运行测试
    • 为 6 个平台交叉编译二进制文件(macOS ARM64/x64、Linux x64/ARM64、Windows x64/ARM64)
    • 编译粘贴服务二进制文件(同样覆盖 6 个平台)
    • 在不涉及凭据的作业中打包两个 npm 包
    • 下载固定版本且经过校验和验证的 Syft 和 Grype 二进制文件;在所有待发布对象生成后,生成覆盖整个版本的 CycloneDX SBOM 并验证其架构
    • 强制使用仓库自有且不含抑制规则的 Grype 配置,将官方数据库更新重试最多 3 次,要求数据库有效、处于活动状态、符合架构 v6、更新时间不超过 120 小时且没有待处理更新,并将机器可读的扫描、数据库和策略证据保存为工作流工件
    • 拒绝扫描器侧所有被忽略的匹配项,然后在生成任何证明或发布之前,拦截 CISA KEV 中列出的漏洞,或被归类为已发布/运行时影响或适用性未知且有修复方案的严重(Critical)问题。高危、仅影响开发环境以及没有修复方案的严重(Critical)问题仅生成报告,但仍保留在证据中
    • 通过 actions/attest-build-provenance 为全部 12 个二进制文件生成 SLSA 构建来源证明(通过 Sigstore 签名并记录在 Rekor 中)
    • 使用独立的官方 actions/attest SBOM 流程,通过同一 GitHub OIDC/Sigstore 服务,将 CycloneDX 谓词绑定到全部 12 个二进制文件和两个 npm tarball。这是清单证明,不可替代 SLSA 或 npm 来源证明
    • 创建 GitHub Release,并附上所有二进制文件、SHA256 校验和文件、带版本号的 CycloneDX SBOM 及其 SHA256 校验和文件
    • 将 @plannotator/opencode 和 @plannotator/pi-extension 发布到 npm,并附带来源证明

    **SBOM 范围:**公开文档是基于 Syft 生成的版本级清单,涵盖 monorepo 中锁定的构建输入和依赖项。它有意不描述为二进制文件的精确运行时内容。覆盖率测试发现,Bun 独立可执行文件会隐藏打包的 JavaScript 依赖元数据,使 Syft 无法读取。OpenCode tarball 同样不透明;Pi tarball 只能通过嵌套的 package-lock 文件展示部分信息。范围和限制也已写入 CycloneDX 元数据。

    **例外:**目前没有生效的生产环境例外文件。如果未来版本基线需要例外,不要添加宽泛的忽略规则。应添加经过仓库审核的 OpenVEX 文档,并通过 PLANNOTATOR_RELEASE_VEX 明确接入;每条声明必须匹配一个确切的包 URL 和漏洞 ID,并包含 not_affected 状态、OpenVEX 理由、影响说明、HTTPS 证据、负责人、创建日期和到期日期。策略测试会拒绝过期、格式错误、范围过宽或不匹配的记录。

    **关于不可变发布的说明:**仓库已启用 GitHub 不可变发布,因此推送 v* 标签并创建发布后,标签→提交和标签→资源的绑定将永久固定。你不能删除标签并重新创建来“修复”有问题的发布,必须发布新版本。发布说明仍可编辑(见步骤 5),但其他内容都已锁定。

  4. 监控流水线: 监视发布工作流运行,直到完成:

    gh run list --workflow=release.yml --limit=1
    gh run view <run-id> --log
    

    验证:

    • 所有作业均通过,包括 release-security、attest、release 和 npm-publish
    • release-security-evidence 记录了 Syft/Grype 版本、活动数据库的架构/构建版本/校验和/更新状态、所有 Grype 匹配项,以及 ACCEPT 策略决策
    • GitHub Release 已创建,并包含所有二进制工件、SHA256 校验和文件、带版本号的 plannotator-X.Y.Z-release-sbom.cdx.json 及其 .sha256 校验和文件
    • npm 包已成功发布(使用 npm view @plannotator/opencode version 和 npm view @plannotator/pi-extension version 检查) 拉取请求可验证生成、schema/哨兵值验证、数据库策略、Grype 评估、最小权限作业配置以及所有报告产物。GitHub OIDC 凭证签发、向制品证明服务发布,以及最终发布发行版资源,仅会在符合条件的真实 v* 标签上运行。该控制措施生效后的首次发行版发布时,在宣布推出完成前,先完成以下范围有限的仅限标签验证:

    为首次发行版打标签前,更新规范的 Mintlify 页面 https://docs.plannotator.ai/open-source/start/installation#pin-or-verify-a-release,加入 SBOM 范围/限制、Grype 策略、下载/校验和命令,以及 README 中的两条谓词验证命令。apps/marketing/src/content/docs/ 下的旧版 Astro 文件仅用于重定向/已弃用,不是公开文档的来源。确认线上 Mintlify 页面包含这些内容;不要让页面发布时间晚于该控制措施的发布。

    tag=vX.Y.Z
    version="${tag#v}"
    gh release download "$tag" --pattern 'plannotator-linux-x64*' --pattern "plannotator-${version}-release-sbom.cdx.json*" --dir /tmp/plannotator-release-verify
    (cd /tmp/plannotator-release-verify && sha256sum --check plannotator-linux-x64.sha256)
    (cd /tmp/plannotator-release-verify && sha256sum --check "plannotator-${version}-release-sbom.cdx.json.sha256")
    
    gh attestation verify /tmp/plannotator-release-verify/plannotator-linux-x64 \
      --repo backnotprop/plannotator \
      --source-ref "refs/tags/$tag" \
      --signer-workflow backnotprop/plannotator/.github/workflows/release.yml \
      --predicate-type https://slsa.dev/provenance/v1
    
    gh attestation verify /tmp/plannotator-release-verify/plannotator-linux-x64 \
      --repo backnotprop/plannotator \
      --source-ref "refs/tags/$tag" \
      --signer-workflow backnotprop/plannotator/.github/workflows/release.yml \
      --predicate-type https://cyclonedx.org/bom
    

    另外,使用 gh attestation verify --format json --jq '.[0].verificationResult.statement.predicate' 提取已证明的 CycloneDX 谓词,使用 jq -S 对其和下载的发行版 SBOM 进行规范化,然后用 cmp 比较。如果下载了确切的已发布 tarball,也用同样方法验证其中一个 npm tarball subject。将任何仅在标签上出现的差异记录为发行版阻塞项,并发布新版本,而不是修改不可变的发行版。

    如果任何步骤失败,请调查日志,并在重试前向用户报告。

  5. 替换发行说明: 发行版上线并通过验证后,将自动生成的说明正文替换为起草好的发行说明:

    gh release edit vX.Y.Z --notes-file RELEASE_NOTES_v<VERSION>.md
    

检查清单

打标签前,确认:

  • 所有 7 个版本文件的版本号均已统一更新
  • 发行说明已起草并审核
  • bun run build:review 已成功
  • bun run build:hook 已成功
  • bun run build:opencode 已成功
  • bun run build:pi 已成功(或已完成 pi 专属构建步骤)
  • 版本更新已提交
  • Pi 一致性门禁已通过(导入、vendor.sh、试运行打包)
  • 没有陈旧的构建产物(使用干净构建,无缓存问题;依赖变更时先运行 bun install)
  • PR 安全的 release-security 作业已生成 schema 有效且哨兵值完整的 SBOM,并使用最新数据库通过 Grype 策略检查
  • 没有暂存扫描器二进制文件、数据库、生成的 SBOM/报告、凭证或 DO_NOT_COMMIT 内容
  • 对于首个启用 SBOM 的发行版,规范的 Mintlify 安装/验证页面包含 README 中的 SBOM 范围、策略、校验和、SLSA 和 CycloneDX 命令(请勿改为编辑已弃用的 Astro 文档)

打标签后,确认:

  • 发行版工作流已完成,且 release-security、attest、release 和 npm-publish 均成功
  • GitHub Release 已创建,包含所有二进制文件、附属文件、SBOM 和 SBOM 附属文件
  • 一个原生二进制文件通过了 SLSA 和 CycloneDX 谓词的显式检查,且检查已固定到该标签和签名者工作流
  • 下载的 SBOM 校验和通过,规范化 JSON 与已证明的谓词一致
  • release-security-evidence 显示数据库为最新/活跃状态,且策略判定已接受
  • npm 包已按正确版本发布
  • 两个包的 npm 可信发布来源证明仍然可见
  • 已通过 gh release edit 替换发行说明

评论

支持 Markdown