From 5ff8899b480e79d53c70a3ef6e35ac7c85f5207f Mon Sep 17 00:00:00 2001 From: laily Date: Tue, 4 Aug 2026 13:55:16 +0800 Subject: [PATCH] feat: update manage-release --- skills/manage-release/README.md | 42 ++++--- skills/manage-release/SKILL.md | 113 ++++++++++++------ .../references/forge-adapters.md | 8 +- .../references/project-policy.md | 20 ++-- skills/manage-release/references/recovery.md | 9 +- .../manage-release/references/versioning.md | 54 ++++++--- .../templates/release-policy.template.yaml | 2 + 7 files changed, 168 insertions(+), 80 deletions(-) diff --git a/skills/manage-release/README.md b/skills/manage-release/README.md index 5d064d8..caf16cb 100644 --- a/skills/manage-release/README.md +++ b/skills/manage-release/README.md @@ -1,13 +1,13 @@ # manage-release -`manage-release` 帮助 Agent 管理从开发版本到发布的 Git 流程,包括 worktree、分支、 -版本号、PR/MR、合并和 release tag。它可以只处理其中一个阶段,也可以从准备开发目录 -一直执行到发布。 +`manage-release` 帮助 Agent 发布已经准备好的 Git commit,也能在发布前确有必要时管理 +版本文件、worktree、分支、PR/MR 和合并。普通发布优先走“更新说明 + annotated tag”的 +短路径;只有发布要求修改仓库内容时,才进入准备版本的分支流程。 ## 使用前准备 - 项目已经是 Git 仓库,并配置了可访问的远端。 -- 项目已有版本文件或发布约定;没有时可以让 Agent 先给出版本建议。 +- 项目已有版本来源或 tag 发布约定;没有时可以让 Agent 先给出版本建议。 - 创建或合并 PR/MR、创建 Forge Release 时,准备好 GitHub、GitLab、Gitea 或 Forgejo 对应的已认证 CLI。只发布 Git tag 时不要求 Forge CLI,但 Git remote 必须可读写。 - 请求里写清目标版本、基线分支,以及允许执行到哪一步。没有明确授权的远端写操作 @@ -54,11 +54,21 @@ Agent 只会在仓库要求全部满足后合并,不会使用管理员权限 ### 为已合并版本发布 tag ```text -使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。确认 tag 指向包含该版本号的 merged commit,不要创建 Forge Release。 +使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。根据 v1.5.0 到目标 commit 的实际变化生成更新说明,把说明写入 annotated tag,并验证远端 tag 的 commit 和说明。不要创建 Forge Release。 ``` -适合依靠 Git tag 触发后续 CI 发布的项目。Agent 会分别验证版本文件、目标 commit 和 -远端 tag,不会给未合并分支打正式 tag。 +这是无需修改仓库文件时的默认短路径,适合依靠 Git tag 触发后续 CI 发布的项目。Agent +会分别验证目标 commit、更新说明和远端 tag,不会创建 worktree、发布分支或 PR,也不会 +给未合并分支打正式 tag。 + +### 为已合并版本创建 Gitea Release + +```text +使用 manage-release,发布已经合并到 main 的 1.6.0:生成更新说明,创建并验证附带说明的 v1.6.0 annotated tag,然后在 Gitea 创建使用同一份说明的 Release。 +``` + +Agent 会先证明 tag 已存在、指向计划 commit 且包含更新说明,再创建 Gitea Release。 +Release 创建失败时保留正确的 tag,从 Release 阶段恢复。 ### 完成端到端发布 @@ -66,8 +76,9 @@ Agent 只会在仓库要求全部满足后合并,不会使用管理员权限 使用 manage-release 完成 1.6.0 发布:从 main 创建 worktree 和分支,完成版本更新和验证,创建 PR,检查通过后合并,推送 v1.6.0 tag,并创建 Forge Release。 ``` -这条请求授权完整流程。遇到 review 未通过、CI 失败、版本冲突或已有同名 tag 时, -Agent 会停止并说明卡在哪一步,不会绕过检查继续发布。 +只有版本文件或仓库内 CHANGELOG 必须随发布修改时才使用这条长路径。tag 仍必须附带更新 +说明,Forge Release 复用同一份说明。遇到 review 未通过、CI 失败、版本冲突或已有同名 +tag 时,Agent 会停止并说明卡在哪一步,不会绕过检查继续发布。 ### 发布紧急修复版本 @@ -89,18 +100,19 @@ Skill 会从 Git 和代码托管平台重新判断状态,再继续缺失的步 ## Agent 会做什么 -Agent 会先发现项目自己的版本、分支和发布规则,再检查本地 Git 与远端状态。它只执行 -请求中明确授权的阶段,并在合并、tag 或 release 条件不满足时停止。完整流程结束后, -结果中会分别列出 worktree、分支、版本、PR/MR、merged commit、tag 和 Forge Release -状态。 +Agent 会先发现项目自己的版本和发布规则、锁定远端目标 commit,再判断发布是否要求修改 +仓库内容。不需要修改时直接生成更新说明并发布 annotated tag;需要修改时才准备分支, +并只在隔离用户工作确有必要时创建 worktree。它只执行请求中明确授权的阶段,并在合并、 +tag 或 release 条件不满足时停止。 ## 如何判断完成 - 只分析版本时,结果包含建议版本及依据。 - 创建开发环境时,结果包含 worktree 路径、分支和基线 commit。 - 创建或合并 PR/MR 时,结果包含 URL、检查状态和 merged commit。 -- 发布 tag 时,远端 tag 解引用后的 commit 与 merged commit 一致。 -- 创建 Forge Release 时,结果包含可访问的 release URL。 +- 发布 tag 时,远端 tag 解引用后的 commit 与目标 commit 一致,而且 tag object 包含经过 + 核对的更新说明。 +- 创建 Forge Release 时,结果包含可访问的 release URL,正文与 tag 更新说明一致。 - 中途停止时,结果说明停在哪一步、为什么停止,以及下次如何继续。 ## 不适用的场景 diff --git a/skills/manage-release/SKILL.md b/skills/manage-release/SKILL.md index 7363ef0..3deaac7 100644 --- a/skills/manage-release/SKILL.md +++ b/skills/manage-release/SKILL.md @@ -1,13 +1,12 @@ --- name: manage-release description: >- - 管理 Git 项目从开发版本到发布的完整生命周期:发现并遵循项目分支与版本策略, - 创建或复用隔离 worktree 和版本分支,确定并同步版本号,推送并创建、检查或合并 - PR/MR,在合并后的准确提交上创建并推送 release tag,并按需创建 Forge Release、 - 恢复中断流程或安全清理。用户要求开始发布相关的新版本、为发布开 worktree 或分支、 - 升版本、提交或合并发布 PR/MR、打 release tag、完成发版、处理 hotfix 或继续未完成 - 发布时使用。只做普通编码、普通 worktree 或 PR/MR 操作、代码审查、构建或上传 - DEB/Docker 等产物、管理仓库权限时不使用。 + 管理 Git 项目从已准备 commit 到版本发布的生命周期:发现并遵循项目版本与发布策略, + 优先为远端已验证 commit 生成更新说明并创建 annotated release tag,按需创建 Forge + Release;只有必须修改版本文件或仓库内发布说明时,才创建或复用版本分支、worktree + 和 PR/MR。也支持恢复中断流程与安全清理。用户要求发布版本、打 release tag、创建 + 平台 Release、准备版本变更、处理 hotfix 或继续未完成发布时使用。只做普通编码、普通 + worktree 或 PR/MR 操作、代码审查、构建或上传 DEB/Docker 等产物、管理仓库权限时不使用。 --- # Manage Release @@ -40,9 +39,11 @@ description: >- 项目策略只描述仓库期望的做法,不能替用户授予 push、创建或合并 PR/MR、推送 tag、 创建 Forge Release、删除分支等外部写权限。 -“完整处理并发布 v1.2.3”可以授权从准备到验证远端 tag 的流程,不要在每一步重复询问; -它不自动包含 Forge Release 或分支清理。若版本、base、tag、远端或合并方式是推断所得, -或者执行中目标发生变化,在第一次远端写操作前展示准确目标并获得确认。 +“发布 v1.2.3”允许为已经准备好的远端 commit 生成更新说明、创建并推送 annotated tag, +再验证远端 tag 的 commit 和说明。“完整处理并发布 v1.2.3”还允许在仓库内容必须修改时 +走版本分支、PR/MR 和合并流程。两者都不自动包含 Forge Release 或分支清理。若版本、 +base、目标 commit、tag、远端或合并方式是推断所得,或者执行中目标发生变化,在第一次 +远端写操作前展示准确目标和更新说明并获得确认。 ## 工作流 @@ -70,25 +71,47 @@ description: >- 在修改前确定并展示: -- base 分支及其远端 commit。 -- 当前版本、规范化后的目标版本、渲染出的分支名和 tag,以及升级依据。 -- 分支名与 worktree 路径。 +- base 分支、远端 commit,以及本次 tag 将指向的准确目标 commit。 +- 当前版本、规范化后的目标版本、tag,以及升级依据;需要准备仓库修改时再渲染分支名。 +- 从上一个稳定 tag 到目标 commit 的更新说明范围、来源和拟发布内容。 +- 是否需要修改仓库内容;若需要,再列出分支名与 worktree 路径。 - 需要执行的本地验证和远端检查。 - 合并方式、tag、是否创建 Forge Release。 - 用户已授权的最远阶段和清理范围。 -项目没有约定时,单一协调版本使用 SemVer、`release/v` 分支、 -`v` annotated tag。仓库只启用一种合并方式时使用该方式;存在多种方式且没有 -项目规则时默认 squash。默认不删除远端分支,不自动创建 Forge Release。 +项目没有约定时,单一协调版本使用 SemVer 和 `v` annotated tag。只有发布前 +必须修改仓库内容时才使用 `release/v` 分支;仓库只启用一种合并方式时使用该 +方式,存在多种方式且没有项目规则时默认 squash。默认不删除远端分支,不自动创建 +Forge Release。 把用户输入拆成“规范版本”和“展示名称”:默认 SemVer 的规范版本是无 `v` 前缀的 `1.6.0`,版本文件和 `{version}` 都使用该值;分支与 tag 再分别按 pattern 渲染为 `release/v1.6.0` 和 `v1.6.0`。用户输入 `v1.6.0` 时先规范化,不要产生双前缀。 -### 3. 创建或复用隔离 worktree +### 3. 选择直接发布或准备版本 -优先使用当前环境提供的 worktree 管理器;项目仓库中的管理脚本只有在可信 base 已声明 -且经过检查时才能使用,没有时使用原生 Git。创建前验证: +先计算发布所需的仓库内容差异,不要为了遵循固定模板而创建分支或 worktree。满足以下 +条件时走直接发布路径,跳过第 4 至 7 节: + +- 目标 commit 已作为准确远端引用读取,并可从计划的 base 或项目允许的维护分支到达。 +- 项目权威版本文件若存在,目标 commit 中已经是目标版本;或项目明确以 tag 作为版本来源。 +- 项目不要求把本次 CHANGELOG 或发布说明提交回仓库。 +- 项目要求的构建、测试和发布检查已经通过。 + +直接发布不 checkout 目标 commit,不创建分支、worktree、版本提交或 PR/MR。更新说明是 +tag object 和可选 Forge Release 的内容,不因生成说明本身进入仓库修改路径。 + +只要版本文件、生成元数据或仓库内 CHANGELOG 必须修改,就进入准备版本路径。优先复用 +身份准确、未被占用且适合本次发布的现有分支;没有时才创建版本分支。优先复用安全且 +干净的现有 worktree;当前目录承载用户工作、目标分支已在别处使用或需要隔离时,才创建 +linked worktree。用户只授权了直接发布时,在展示必要差异后停止,不要擅自扩大到修改、 +分支或 PR/MR 流程。 + +### 4. 创建或复用准备版本的分支和 worktree + +仅在第 3 节判定需要准备仓库修改时执行本节。优先使用当前环境提供的 worktree 管理器; +项目仓库中的管理脚本只有在可信 base 已声明且经过检查时才能使用,没有时使用原生 Git。 +创建前验证: - 目标分支和目录未被其他 worktree 占用。 - 目标目录不是 `/`、用户主目录、仓库根目录或已有非空目录。 @@ -105,7 +128,7 @@ worktree 占用的分支。 相对计划 base 的提交,确认是同一次发布后用 `git worktree add ` 挂载; 身份不匹配或来源不明时停止,不要用 `-b` 覆盖或另建同名分支。 -### 4. 开发并同步版本 +### 5. 修改并同步版本 在目标 worktree 内完成用户要求的修改。根据项目规则更新所有权威版本来源和 CHANGELOG 或发布说明,保证它们进入同一个 PR/MR。运行项目声明的格式化、测试、构建 @@ -119,7 +142,7 @@ CHANGELOG 或发布说明,保证它们进入同一个 PR/MR。运行项目声 提交前重新读取 HEAD 和完整工作区状态,只提交本次范围内的文件。不要在未合并分支上 创建正式 release tag。 -### 5. 推送并创建 PR/MR +### 6. 推送并创建 PR/MR 执行远端写操作前再次确认 remote、base、head、版本、活动账号和授权范围,并重新读取 唯一 fetch/push URL。Git 分支与 tag 通过已确认的 remote 读写;创建或操作 PR/MR 时使用 @@ -130,7 +153,7 @@ CHANGELOG 或发布说明,保证它们进入同一个 PR/MR。运行项目声 PR/MR 内容至少说明目标版本、变更摘要、验证命令和结果、发布后续动作。用户只要求开 PR/MR 时,停在这里并返回 URL、head/base、当前检查状态和阻塞项。 -### 6. 检查并合并 +### 7. 检查并合并 从托管平台重新读取 PR/MR 状态。仅在下列条件全部满足时合并: @@ -143,29 +166,40 @@ PR/MR 时,停在这里并返回 URL、head/base、当前检查状态和阻塞 不要使用管理员绕过、直接推送受保护 base,或为通过检查而修改保护规则。合并后获取 平台确认的 merged commit,更新远端 base,并验证该 commit 可从远端 base 到达。 -### 7. 创建并发布 tag +### 8. 创建并发布带更新说明的 tag -在 merged commit 上核对目标版本后,再查询一次远端同名 tag。tag 不存在时创建 -annotated tag;项目要求签名时,必须先确认签名工具和密钥可用,创建 signed tag,并在 -本地验证签名成功后才允许 push。签名不可用或验证失败时停止,不得降级为 unsigned tag。 -显式指定 merged commit,并只推送这个 tag。 +准备版本路径使用平台确认且可从远端 base 到达的 merged commit;直接发布路径使用计划 +中锁定且重新验证过的远端目标 commit。两者统一记为 release commit。核对目标版本后, +再查询一次远端同名 tag。 + +创建 tag 前,根据上一个稳定 tag 到 release commit 的实际差异生成更新说明;首次发布则 +使用项目声明的发布基线,没有声明时核对完整可达历史并明确标记首次发布。说明概括实际 +存在的新增、变更、修复、维护或文档变化;存在破坏性变化、迁移步骤或已知限制时必须明确 +列出。每项内容都应能追溯到本次提交、PR/MR 或项目 CHANGELOG。空说明、只重复版本号、 +模板占位文字或无法由实际变化支持的内容都不能发布。 + +tag 不存在时,使用完整更新说明创建 annotated tag;项目要求签名时,必须先确认签名 +工具和密钥可用,创建 signed annotated tag,并在本地验证签名成功后才允许 push。使用 +文件输入完整的多行说明,显式指定 release commit,并只推送这个 tag。禁止创建 lightweight +release tag。签名不可用或验证失败时停止,不得降级为 unsigned tag。 同名远端 tag 已存在且指向其他 commit 时立即停止。不要覆盖、删除或移动已经发布的 -tag。推送后读取远端 tag,并将 annotated tag 解引用到 commit,确认它与 merged commit -完全相同。 +tag。同名 tag 即使指向 release commit,只要它是 lightweight tag、缺少更新说明或说明与 +计划不一致,也视为身份不匹配并停止。推送后读取远端 tag object,确认它是 annotated +tag,将它解引用到 commit 并核对完整更新说明;commit 和说明必须都与发布计划完全一致。 仅当用户本次请求明确要求时创建 Forge Release;项目策略只能说明创建方式,不能授予 外部写权限。必须引用已经存在并验证过的 tag,禁止让平台从默认分支隐式创建 tag。 -发布说明中的每项变化都应能追溯到本次 PR/MR、提交或项目 CHANGELOG。 +Forge Release 正文复用 tag 中经过验证的更新说明,不维护第二份相互独立的发布内容。 -### 8. 验证、恢复和清理 +### 9. 验证、恢复和清理 分别报告以下状态,不要用“发布成功”掩盖其中某一步未完成: - 版本文件和本地验证。 - PR/MR URL、合并状态和 merged commit。 -- 远端 tag 及其解引用后的 commit。 -- Forge Release URL 和可见性,若本次要求创建。 +- 远端 tag 的对象类型、完整更新说明及其解引用后的 commit。 +- Forge Release URL、可见性及正文一致性,若本次要求创建。 - worktree、本地分支和远端分支是否保留。 清理时只移除干净且已确认不再使用的 linked worktree,不使用强制删除。删除本地或远端 @@ -176,12 +210,15 @@ tag。推送后读取远端 tag,并将 annotated tag 解引用到 commit,确 遇到以下任一情况时停止相应写操作并说明恢复路径: - base、目标版本、版本来源、remote,或请求阶段所需的托管平台无法唯一确定。 +- 直接发布的目标 commit 无法从计划远端分支到达,或项目要求的发布检查未通过。 - 项目策略包含未知字段、错误类型、仓库外路径或不安全 ref。 - 多个权威版本来源不一致。 - 目标分支、worktree、PR/MR、tag 或 release 已存在但身份不匹配。 - required checks、review 或冲突状态不满足合并规则。 - 合并结果的准确 commit 无法从平台确认,或无法从远端 base 到达。 - 远端 tag 已指向其他 commit。 +- 更新说明为空、只有版本号、包含占位内容、无法追溯到实际变化,或远端 tag 不是包含 + 计划说明的 annotated tag。 - 请求的 PR/MR、合并或 Forge Release 阶段所需的平台 CLI 缺失、未认证或无法读取状态。 - 项目要求 tag 签名,但签名能力不可用或本地签名验证失败。 - 操作需要 force push、管理员绕过、移动已发布 tag 或覆盖用户工作。 @@ -192,7 +229,9 @@ tag。推送后读取远端 tag,并将 annotated tag 解引用到 commit,确 ## 完成标准 -只分析时,给出当前状态、建议版本、依据和下一步。开始版本时,给出 worktree 路径、 -分支和基线 commit。创建 PR/MR 时,给出 URL 与检查状态。合并时,给出 merged commit。 -发布 tag 时,证明远端 tag 解引用到该 commit。创建 Forge Release 时,再给出 release URL -与可见性。任何部分未完成都要标明阻塞阶段和可恢复动作。 +只分析时,给出当前状态、建议版本、依据和下一步。直接发布时,给出目标 commit 和更新 +说明,不得虚构 worktree 或分支步骤。开始准备版本时,给出所用 worktree、分支和基线 +commit;未新建 worktree 时明确说明复用了哪个安全工作区。创建 PR/MR 时,给出 URL 与 +检查状态。合并时,给出 merged commit。发布 tag 时,证明远端 tag 是包含计划更新说明的 +annotated tag,并解引用到 release commit。创建 Forge Release 时,再给出 release URL、 +可见性与正文一致性。任何部分未完成都要标明阻塞阶段和可恢复动作。 diff --git a/skills/manage-release/references/forge-adapters.md b/skills/manage-release/references/forge-adapters.md index 41142f6..4c593f5 100644 --- a/skills/manage-release/references/forge-adapters.md +++ b/skills/manage-release/references/forge-adapters.md @@ -68,14 +68,16 @@ commit 已进入远端 base。只看到本地 merge commit 或分支关闭不足 ## 创建 Forge Release -把 Git tag 和 Forge Release 当成两个独立状态。先创建、推送并验证 tag,再创建 release。 +把 Git tag 和 Forge Release 当成两个独立状态。先创建、推送并验证包含完整更新说明的 +annotated tag,再创建 release。Forge Release 正文复用已经冻结并验证的 tag 更新说明, +不要重新生成另一份内容。 - GitHub 创建 release 时使用能够拒绝缺失 tag 的选项,例如当前 CLI 支持的 `--verify-tag`。 - GitLab、Gitea 或 Forgejo 创建 release 前,先用只读命令证明 tag 已存在并指向计划的 - commit;不要使用会顺便创建 tag 的默认行为。 + commit、tag object 包含计划的更新说明;不要使用会顺便创建 tag 的默认行为。 - 预发布版本按项目规则标记 prerelease,不要自动把它标为 latest 或 stable。 -- 发布后重新读取 release URL、tag 和可见性。 +- 发布后重新读取 release URL、tag、正文和可见性,确认正文与 tag 更新说明一致。 Forge Release 创建失败但 tag 已成功推送时,保留 tag 并从 release 阶段恢复,不要重新 合并或创建另一个 tag。 diff --git a/skills/manage-release/references/project-policy.md b/skills/manage-release/references/project-policy.md index d6fcf12..7591b24 100644 --- a/skills/manage-release/references/project-policy.md +++ b/skills/manage-release/references/project-policy.md @@ -28,9 +28,11 @@ - `schema`:配置结构版本,当前为 `1`。 - `base_branch`:发布 PR/MR 的目标分支。 -- `branch_pattern`:版本分支格式,支持无展示前缀的规范 `{version}`。 +- `branch_pattern`:需要准备仓库修改时使用的版本分支格式,支持无展示前缀的规范 + `{version}`;直接发布不因此创建分支。 - `version.scheme`:`semver` 或项目已经使用的其他方案。 -- `version.sources`:构建和运行实际读取的权威版本文件。 +- `version.sources`:构建和运行实际读取的权威版本文件;项目明确从 Git tag 派生版本时 + 可以省略,不要为了发布新增无消费方的版本文件。 - `tag_pattern`:release tag 格式,支持无展示前缀的规范 `{version}`。 - `merge_method`:`squash`、`merge` 或 `rebase`。 - `forge_release`:项目是否建议在 tag 后创建 Forge Release;它不授予创建权限。 @@ -54,18 +56,20 @@ symlink 后,目标必须仍在当前 worktree 内;权威来源通常还应 1. 从 remote HEAD 和平台信息确定默认 base,不能确定时询问。 2. 从项目文档、CI 和构建入口找版本文件及更新方式。 -3. 从已有分支和已合并 PR/MR 识别命名与合并方式。 -4. 从稳定 tag 识别前缀和版本方案,只把 tag 当作交叉验证。 -5. 无项目约定时使用 `release/v`、SemVer、`v` annotated tag 和 - squash merge;默认不创建 Forge Release,不删除远端分支。 +3. 仅当发布需要修改仓库内容时,从已有分支和已合并 PR/MR 识别命名与合并方式。 +4. 从稳定 tag 识别前缀、版本方案和更新说明范围;项目由 tag 派生版本时,把实际构建 + 入口和 tag 历史共同作为版本来源证据,否则只把 tag 当作交叉验证。 +5. 无项目约定时使用 SemVer 和 `v` annotated tag;需要准备仓库修改时再使用 + `release/v` 和 squash merge。默认不创建 Forge Release,不删除远端分支。 ## 每次执行的计划快照 在第一次写操作前列出以下事实: -- base 分支和远端 commit。 +- base 分支、远端 commit 和 tag 将指向的目标 commit。 - 当前版本、目标版本、版本来源和升级依据。 -- worktree 路径与分支名。 +- 更新说明的提交范围、来源和拟发布内容。 +- 是否需要修改仓库内容;需要时再列出 worktree 路径与分支名。 - PR/MR 托管平台和合并方式。 - tag 与 Forge Release 计划。 - 用户授权的最远阶段和清理范围。 diff --git a/skills/manage-release/references/recovery.md b/skills/manage-release/references/recovery.md index 036bb16..a22ad00 100644 --- a/skills/manage-release/references/recovery.md +++ b/skills/manage-release/references/recovery.md @@ -12,12 +12,15 @@ base、head、PR/MR、merged commit、tag 和 release,再执行唯一缺失的 | 当前状态 | 继续方式 | 禁止事项 | |---|---|---| +| 远端 release commit 已准备,没有 tag | 核对版本与更新说明后直接创建 annotated tag | 不创建无必要的分支或 worktree | +| 本地 annotated tag 已创建但未推送 | 核对对象类型、commit 和完整说明后只推送该 tag | 不因重入重复创建或改写 tag | | worktree 已创建,无改动 | 继续开发,或经授权移除干净 worktree | 不使用强制删除 | | 本地发布分支已存在,没有 worktree | 核对版本身份、tip、upstream 和 base 后挂载现有分支 | 不用 `-b` 覆盖分支 | | 分支已推送,没有 PR/MR | 确认 head/base 后创建一次 PR/MR | 不重复推送新分支 | | PR/MR 已存在,未合并 | 复用 URL,刷新 checks、review 和冲突状态 | 不创建第二个 PR/MR | -| PR/MR 已合并,没有 tag | 获取 merged commit,在该 commit 上继续发布 | 不重新合并 | -| tag 已推送,没有 release | 验证 tag 后创建 Forge Release | 不创建替代 tag | +| PR/MR 已合并,没有 tag | 获取 merged commit,生成并确认更新说明后继续发布 | 不重新合并 | +| tag 已推送,没有 release | 验证 tag 的 commit 和更新说明后创建 Forge Release | 不创建替代 tag | +| tag 指向正确 commit 但为 lightweight 或说明不符 | 停止并交由维护者决定撤销或发布修订版本 | 不移动、覆盖或补写远端 tag | | release 已创建,验证未完成 | 读回 release、tag 和可见性 | 不直接声称发布完成 | | 同名资源身份不匹配 | 停止并报告差异 | 不覆盖、关闭或删除未知资源 | @@ -35,7 +38,7 @@ merge queue 和 auto-merge。任何 force push 都是硬停止条件。 - 未推送的本地版本提交可以在用户授权下修改或放弃,但不要覆盖其他工作。 - 已推送但未合并的 PR/MR 可以关闭,分支默认保留。 - 已合并变更通过新的 revert PR/MR 回滚,不重写 base 历史。 -- 已发布 tag 默认不可变。tag 错误时停止,由维护者决定撤销发布或发布新版本。 +- 已发布 tag 默认不可变。commit 或更新说明错误时停止,由维护者决定撤销发布或发布新版本。 - Forge Release 失败不回滚已经正确推送的 tag;从 release 阶段恢复。 ## 清理规则 diff --git a/skills/manage-release/references/versioning.md b/skills/manage-release/references/versioning.md index 0234b65..54ddffa 100644 --- a/skills/manage-release/references/versioning.md +++ b/skills/manage-release/references/versioning.md @@ -5,15 +5,17 @@ 按项目实际构建链路寻找版本来源,不要遍历到一个看起来像版本号的字符串就修改。优先级: 1. 项目发布文档或 `.release-policy.yaml` 明确声明的文件。 -2. 构建、打包或运行入口直接读取的清单,例如 `VERSION`、`package.json`、 +2. 项目明确由 Git tag 或 VCS metadata 派生构建版本时,以 tag 规则作为发布版本来源, + 不要为了发布凭空新增或修改版本文件。 +3. 构建、打包或运行入口直接读取的清单,例如 `VERSION`、`package.json`、 `pyproject.toml`、`Cargo.toml` 或语言工具链的版本配置。 -3. 由权威文件生成的镜像文件、锁文件或发布元数据。 -4. 最近稳定 tag,只用于验证当前版本和发布历史。 +4. 由权威文件生成的镜像文件、锁文件或发布元数据。 +5. 最近稳定 tag,用于确定当前已发布版本、更新说明范围和发布历史。 记录每个权威文件的当前值和更新方式。多个权威来源不一致时停止,不要选择修改时间最新 的文件,也不要只改其中一个。 -配置声明的版本文件必须使用仓库相对路径。拒绝绝对路径、`..` 和解析后逃出目标 +配置声明了版本文件时,它们必须使用仓库相对路径。拒绝绝对路径、`..` 和解析后逃出目标 worktree 的 symlink;修改前确认规范化后的准确路径。不要用 glob 或模糊搜索结果执行 批量替换。 @@ -45,10 +47,19 @@ worktree 的 symlink;修改前确认规范化后的准确路径。不要用 gl 项目采用自定义前缀或非 SemVer 时,以项目版本来源定义规范值,以 branch/tag pattern 定义展示形式。规范化结果无法唯一确定时停止并让用户确认。 +## 判断是否需要同步版本 + +直接读取计划 release commit 中的权威版本来源。版本文件已经是目标值,或者项目明确由 +tag 派生版本,且发布说明不要求写回仓库时,不产生仓库修改,直接进入 tag 发布。 + +只有权威版本文件、生成文件或仓库内 CHANGELOG 必须变化时,才进入准备版本流程并使用 +分支/PR。不要为了制造发布提交而触碰与构建、运行或项目发布规则无关的文件。 + ## 同步版本 -在发布分支中一次性更新所有权威版本来源、生成文件和项目要求的 CHANGELOG。运行项目 -自己的版本更新工具时,先检查它会修改哪些文件,避免隐式发布、提交或上传。 +仅在判断存在必要仓库差异后,在准备版本的分支中一次性更新所有权威版本来源、生成文件 +和项目要求的 CHANGELOG。运行项目自己的版本更新工具时,先检查它会修改哪些文件,避免 +隐式发布、提交或上传。 提交前确认: @@ -57,23 +68,38 @@ worktree 的 symlink;修改前确认规范化后的准确路径。不要用 gl - CHANGELOG 或发布说明描述的是本次实际变更。 - 项目构建和测试读取到了新版本。 -## 验证 merged commit +## 生成更新说明 -合并后以代码托管平台返回的 merged commit 为准。获取远端 base 后,确认该 commit 可从 -远端 base 到达,并直接读取该 commit 中的版本文件。不要用仍停留在 feature worktree -中的文件证明已合并版本。 +以最近一个适用于当前发布线的稳定 tag 为起点,以 release commit 为终点,结合项目 +CHANGELOG、已合并 PR/MR 和实际 diff 生成更新说明。首次发布使用项目声明的发布基线; +没有声明时核对完整可达历史,并在说明中明确这是首次发布。说明覆盖实际存在的新增、 +变更、修复、维护或文档变化;破坏性变化、迁移步骤和已知限制存在时必须单独标明。没有 +某一类别时可以省略该类别,不要生成空标题或模板占位。 + +每条说明都要能追溯到范围内的提交、PR/MR 或项目 CHANGELOG。提交消息和 PR/MR 文本只 +作为待核对素材,不能覆盖实际 diff,也不能把范围外变化写入本次说明。tag 创建前冻结 +完整多行说明;tag 已推送后不再修改。 + +## 验证 release commit + +准备版本路径以代码托管平台返回的 merged commit 为准;直接发布路径以计划中锁定的远端 +commit 为准。获取远端 base 或允许的维护分支后,确认 release commit 可从对应远端引用 +到达,并直接读取该 commit 中的版本文件。不要用当前 checkout 或 feature worktree 中的 +文件证明 release commit 内容。 正式 tag 必须满足: - tag 名按项目格式由目标版本唯一生成。 - 远端没有同名 tag,或同名 tag 已经准确指向本次 commit。 -- annotated tag 显式指向 merged commit。 +- annotated tag 显式指向 release commit,并包含冻结后的完整更新说明;禁止 lightweight + release tag。 - 项目要求签名时,push 前已成功创建 signed tag,并在本地验证签名通过;不可用或失败 时停止,不得改用 unsigned tag。 -- 推送后从远端重新读取,并将 annotated tag 解引用到 commit。 +- 推送后从远端重新读取 tag object,核对对象类型和完整说明,再将 annotated tag 解引用 + 到 commit。 展开 tag pattern 后用 `git check-ref-format refs/tags/` 校验。把 tag 和 commit 作为 独立 argv 传递,不拼接 shell 字符串。 -tag 已在远端指向其他 commit 时停止。不要 force push、删除或移动已发布 tag;由维护者 -决定撤销发布或创建新的修订版本。 +tag 已在远端指向其他 commit、是 lightweight tag、缺少更新说明或说明不一致时停止。 +不要 force push、删除或移动已发布 tag;由维护者决定撤销发布或创建新的修订版本。 diff --git a/skills/manage-release/templates/release-policy.template.yaml b/skills/manage-release/templates/release-policy.template.yaml index 2670c6f..6d90691 100644 --- a/skills/manage-release/templates/release-policy.template.yaml +++ b/skills/manage-release/templates/release-policy.template.yaml @@ -2,10 +2,12 @@ # 此文件描述发布策略,不授予任何远端写操作权限。 schema: 1 base_branch: main +# 仅在发布必须修改仓库内容时使用;直接发布不会因此创建分支。 # {version} 是规范版本,例如 1.6.0;前缀由 pattern 添加。 branch_pattern: release/v{version} version: scheme: semver + # 项目明确从 Git tag 派生版本时可以省略 sources。 sources: - VERSION tag_pattern: v{version}