关于 release
用于确定语义化版本、准备发布说明、为提交打标签并发布 GitHub Release 的技能。它为维护者提供带有审批与验证步骤的发布流程。
主要功能
- 01语义化版本升级指引
- 02发布说明撰写策略
- 03变更日志更新指引
- 04附注标签与审批流程
- 05GitHub Release 验证
适用场景
- 01从默认分支准备版本发布
- 02为基于 PR 或提交的发布选择说明策略
- 03更新现有 CHANGELOG.md
- 04检查已发布版本与标签状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ git-gouda --skill release安装后在 Claude Code 中输入/release确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/release-notes-template.mdevals/evals.jsonreferences/release-notes.mdsemver.md详细介绍
release
发布一个有版本号的版本:选择下一个语义化版本,撰写恰当的发行说明,为提交打标签,并发布 GitHub 发行版。
它与 /gh-bootstrap 相辅相成,但回答的是不同的问题。/gh-bootstrap 一次性配置发行流程基础设施(.github/release.yml、由标签触发的工作流)。此技能则是每次发布时要执行的流程:决定版本变更幅度、起草说明、打标签并发布。在此流程之外执行一次性发行命令时,直接使用 gh CLI。
此技能的适用场景
| 关注事项 | 技能 |
|---|---|
| 一次性配置发行说明和由标签触发的工作流 | /gh-bootstrap |
| 决定版本、起草说明、打标签并发布 | /release(此技能) |
如果仓库已有由标签触发的发行工作流(由 /gh-bootstrap 配置),推送标签就足够了——工作流会发布发行版。此技能仍负责决定版本,并可选择起草经过整理的说明。推送标签后,它不会运行 gh release create。它会等待工作流完成,然后应用已批准的整理后说明。否则,它会自行使用 gh release create 发布发行版。
流程
1. 发布前检查
如果工作区不干净或分支已分叉,则拒绝发布——发行标签是永久且公开的。
git fetch --tags origin
DEFAULT=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
git diff-index --quiet HEAD || { echo "uncommitted changes — commit or stash first"; exit 1; }
[ "$(git rev-parse HEAD)" = "$(git rev-parse "origin/$DEFAULT")" ] || { echo "HEAD is not the tip of origin/$DEFAULT — check out and update it first"; exit 1; }
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
向用户确认:
- 要打标签的提交。只有
origin/$DEFAULT的最新提交可以打标签。 - 上一个发行标签(
$LAST_TAG)——它是版本变更和说明范围的基准。如果仓库还没有标签,这就是首次发布。
如果工作区不干净,或 HEAD 不是 origin/$DEFAULT 的最新提交,就停止并告知用户——不要打标签。
2. 决定版本
阅读 references/semver.md,了解完整的判定规则。简而言之:扫描上一个标签以来的 Conventional Commits,并根据影响最大的变更确定版本变更幅度。
git log "${LAST_TAG:+$LAST_TAG..}HEAD" --no-merges --pretty='%s'
| 上一个标签以来影响最大的变更 | 变更幅度(≥ 1.0.0) | 变更幅度(0.x,未达 1.0) |
|---|---|---|
feat!: / fix!: / BREAKING CHANGE: 页脚 | 主版本 | 次版本 |
feat: | 次版本 | 补丁版本 |
fix: / perf: | 补丁版本 | 补丁版本 |
只有 docs / chore / refactor / test / ci | 补丁版本(或跳过——询问用户) | 补丁版本 |
沿用仓库现有的标签格式——如果 $LAST_TAG 是 v1.2.3,下一个标签应为 v1.3.0,而不是 1.3.0。检测并沿用 v 前缀(或无前缀的格式)。检测预发行标识符(-rc.1、-beta.2),并沿用用户的惯例。
提出计算得出的版本和一句话理由(“3 个 feat,没有破坏性变更 → 次版本 → v1.3.0”)。让用户确认或修改。绝不要为用户尚未确认的版本打标签。
3. 起草发行说明
阅读 references/release-notes.md,了解三种策略及其选择方式。概要如下:
- 自动生成(
gh release create --generate-notes)——适用于通过 PR 合并且有.github/release.yml的仓库。GitHub 会根据标签,将已合并的 PR 归入配置的分类。成本最低;只要每项变更都通过带标签的 PR 合并,就能确保内容完整。 - 手动整理——适用于没有
.github/release.yml、以提交(而非 PR)作为变更单位,或发行版需要编辑性亮点的情况。按 Conventional Commit 类型分组;在开头加入 Highlights 部分;如果有任何破坏性变更,则加入 Upgrade notes 部分,并写明具体迁移步骤。assets/release-notes-template.md是起始模板。 - 混合方式——先生成,再手动编辑开头,加入亮点和升级说明。对于重要发行版,这是最常见的选择。
整理说明时,要依据提交日志生成条目,不能凭空编造——每条内容都必须对应一个真实提交。在适合读者进一步了解详情的地方,链接到 PR 或提交。
4. 更新 CHANGELOG.md(如果仓库中有)
如果存在 CHANGELOG.md,请确保它保持同步。大多数仓库都遵循 Keep a Changelog:将 ## [Unreleased] 下的条目移到新的 ## [VERSION] - YYYY-MM-DD 标题下,保留一个新的空 Unreleased,并更新底部的比较链接。如果没有变更日志,且用户也不需要,就跳过这一步——不要擅自添加用户未要求的变更日志。
标签必须包含变更日志条目。提交变更日志的修改,并通过仓库的常规合并流程将其合并到默认分支。只有获得用户明确批准后才能推送。然后,在默认分支的新最新提交上重复步骤 1-3。压缩合并会生成新的 SHA,因此请为步骤 1 检查的最新提交打标签,而不是为本地提交打标签。将 git log "${LAST_TAG:+$LAST_TAG..}HEAD" 与起草的说明进行比较。如果有变更日志提交以外的提交已合并,请停止并告知用户。
5. 打标签并推送
使用附注标签(包含消息、作者和日期;轻量标签不包含这些信息,且 git describe 对两者的处理方式不同)。为双方商定的提交打标签,然后只推送标签。
如果存在由标签触发的发布工作流(例如 .github/workflows/release.yml),请先查看其 gh release create 参数,再判断是否会生成说明。/gh-bootstrap 工作流只会发布自动生成的说明(--generate-notes)。如果工作流会发布自动生成的说明,而步骤 3 选择了定制或混合说明,请在推送标签前告知用户。
推送标签前,必须征得用户明确批准。
VERSION=v1.3.0
git tag -a "$VERSION" -m "$VERSION" # add -s to GPG-sign if the repo signs tags
git push origin "$VERSION"
如果存在由标签触发的发布工作流,请跳过步骤 6。等待工作流运行,然后使用 gh release edit "$VERSION" --notes-file NOTES.md 应用已批准的定制说明。只有获得用户批准后才能应用说明。报告工作流运行 URL。
6. 发布 GitHub 版本
仅当没有由标签触发的工作流代为发布时才执行。
运行 gh release create 前,必须征得用户明确批准。
# Auto-generated notes:
gh release create "$VERSION" --title "$VERSION" --generate-notes --latest
# Curated notes from a file:
gh release create "$VERSION" --title "$VERSION" --notes-file NOTES.md --latest
# Prerelease (rc/beta/alpha) — do NOT mark --latest:
gh release create "$VERSION" --title "$VERSION" --notes-file NOTES.md --prerelease
# Draft for review before going public:
gh release create "$VERSION" --title "$VERSION" --notes-file NOTES.md --draft
如果项目会发布二进制文件,请在标签后列出构建产物并将其附加(gh release create "$VERSION" ... dist/*.tar.gz)。
不可变发布
GitHub 不可变版本于 2025-10-28 开始全面推出。启用此功能的仓库中,已发布版本的资产和标签会保持固定,并附带已签名的 Sigstore 证明。你仍可编辑已发布不可变版本的标题和说明,但不能更改其资产或移动其标签。发布前,请核实附加的资产和打标签的提交。引用来源见 references/release-notes.md。
7. 验证并报告
读取已发布的状态进行确认——不要仅凭创建命令的退出代码就声称成功。
gh release view "$VERSION" --json tagName,isDraft,isPrerelease,url --jq .
gh release list --json tagName,isLatest --jq '.[] | select(.isLatest) | .tagName'
git ls-remote --tags origin "$VERSION"
向用户报告:版本及原因、采用的说明策略、发布 URL,以及发布是否为草稿、预发布或最新版本。说明任何跳过的操作(例如:“工作流正在发布——版本尚不可见”)及其原因。
此技能不适用于
- 搭建
.github/release.yml或发布工作流——这属于/gh-bootstrap(首次运行时执行一次)。 - 在发布流程之外查询原始
gh release命令参数——请直接查阅ghCLI 参考。 - 在发布流程开始前提交或推送分支代码。
- 发布到软件包注册表(npm / crates.io / PyPI)。此技能负责打标签并创建 GitHub 版本;发布到注册表是项目自己的
just/CI 步骤。 - 在采用独立发布节奏的单体仓库中按软件包分别管理版本——这超出此技能的范围;此技能只为一个版本线打一个标签。如果仓库是多软件包单体仓库,请说明这一点。
注意事项
- 绝不要重新指向已有标签。 使用
git tag -f和git push -f移动已发布的标签,会影响所有已获取该标签的使用者。如果标签指向了错误的提交,请改为发布新的补丁版本。 - 自动生成的说明只能识别已合并的 PR。 直接推送到默认分支的内容不会显示。如果仓库不通过 PR 合并(未启用分支保护),应手动整理说明,而不要依赖
--generate-notes。 --generate-notes需要.github/release.yml才能妥善分组;没有该文件时,内容会变成扁平的“变更内容”列表。如果分组有误,应该调整release.yml中的类别和标签——通过/gh-bootstrap修复,而不是在这里处理。- 预发布版本不能标记为
--latest。 将-rc版本标记为最新版本,会使其成为默认下载版本,并成为releases/latest的目标。请使用--prerelease,并省略--latest。 - 1.0 之前的 semver 规则不同。 在
0.x版本中,破坏性变更应提升次版本号,而不是主版本号。请参阅references/semver.md。 - 标签必须是默认分支的祖先提交。 为功能分支上的提交打标签会发布未经审查的代码。打标签前,请确认该提交位于默认分支上或已合并到默认分支。
- 签名标签——如果仓库会对发布进行签名(使用
git config tag.gpgSign true或遵循项目惯例),请使用git tag -s;在要求签名发布的仓库中使用未签名标签,会导致下游验证失败。