Files
2026-08-25 14:42:26 +08:00

133 lines
6.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 版本号与 tag
## 确定权威版本来源
按项目实际构建链路寻找版本来源,不要遍历到一个看起来像版本号的字符串就修改。优先级:
1. 项目发布文档或 `.release-policy.yaml` 明确声明的文件。
2. 项目明确由 Git tag 或 VCS metadata 派生构建版本时,以 tag 规则作为发布版本来源,
不要为了发布凭空新增或修改版本文件。
3. 构建、打包或运行入口直接读取的清单,例如 `VERSION``package.json`
`pyproject.toml``Cargo.toml` 或语言工具链的版本配置。
4. 由权威文件生成的镜像文件、锁文件或发布元数据。
5. 最近稳定 tag,用于确定当前已发布版本、更新说明范围和发布历史。
记录每个权威文件的当前值和更新方式。多个权威来源不一致时停止,不要选择修改时间最新
的文件,也不要只改其中一个。
配置声明了版本文件时,它们必须使用仓库相对路径。拒绝绝对路径、`..` 和解析后逃出目标
worktree 的 symlink;修改前确认规范化后的准确路径。不要用 glob 或模糊搜索结果执行
批量替换。
## 选择目标版本
项目已有 CalVer、单调构建号、独立包版本或自定义方案时继续使用,不要迁移到 SemVer。
项目没有规则且只有一个协调版本时使用 SemVer:
- 不兼容的公开 API 或行为变化增加 major。
- 向后兼容的新功能增加 minor。
- 向后兼容的修复增加 patch。
根据实际兼容性判断,不要只凭 commit 前缀自动升级。项目明确采用 Conventional Commits
或已有版本工具时,可以把它们的结果作为项目规则。破坏性影响无法确定时给出建议并请
用户确定准确版本。
预发布版本沿用项目格式;没有格式时使用 `-alpha.N``-beta.N``-rc.N`。正式 tag
默认不加入 build metadata。不要从带 build metadata 的 tag 推断兼容性顺序。
独立多包版本、多个维护分支和 release train 不属于默认单版本流程。无法确定一个目标
版本时停止并说明需要增加包或发布线维度。
## 规范化与渲染
内部始终分别记录规范版本、分支名和 tag 名。默认 SemVer 的规范版本不含 `v`,例如
用户输入 `v1.6.0` 时规范化为 `1.6.0`;版本文件写入 `1.6.0`,再将它代入
`release/v{version}``v{version}`。不要把完整 tag 名直接代入 `{version}`
项目采用自定义前缀或非 SemVer 时,以项目版本来源定义规范值,以 branch/tag pattern
定义展示形式。规范化结果无法唯一确定时停止并让用户确认。
## 判断是否需要同步版本
直接读取计划 release commit 中的权威版本来源。版本文件已经是目标值,或者项目明确由
tag 派生版本,且发布说明不要求写回仓库时,不产生仓库修改,直接进入 tag 发布。
只有权威版本文件、生成文件或仓库内 CHANGELOG 必须变化时,才进入准备版本流程并使用
分支/PR。不要为了制造发布提交而触碰与构建、运行或项目发布规则无关的文件。
## 同步版本
仅在判断存在必要仓库差异后,在准备版本的分支中一次性更新所有权威版本来源、生成文件
和项目要求的 CHANGELOG。运行项目自己的版本更新工具时,先检查它会修改哪些文件,避免
隐式发布、提交或上传。
提交前确认:
- 所有权威来源都是目标版本。
- 生成文件与来源一致。
- CHANGELOG 或发布说明描述的是本次实际变更。
- 项目构建和测试读取到了新版本。
## 生成更新说明
以最近一个适用于当前发布线的稳定 tag 为起点,以 release commit 为终点,结合项目
CHANGELOG、已合并 PR/MR 和实际 diff 生成更新说明。首次发布使用项目声明的发布基线;
没有声明时核对完整可达历史,并在说明中明确这是首次发布。
正式版本的 tag message 使用以下固定格式;内容必须基于本次实际变更,并与 CHANGELOG
或 PR/MR 发布说明保持一致:
```text
<tag>
Summary:
- <一句话概括本版本>
Changes:
- <变更 1>
- <变更 2>
Validation:
- <验证命令及结果>
Base commit: <release commit>
```
`Summary``Changes``Validation``Base commit` 四个字段必须全部存在,不能只有
版本号、提交标题或空 message。没有仓库 CHANGELOG 时,也必须按此格式补齐字段。
`Changes` 只写入实际存在的新增、变更、修复、维护或文档变化;破坏性变化、迁移步骤和
已知限制存在时必须单独标明。没有实际功能变更时不得伪造条目,应明确说明这是文档、
打包或发布元数据修订。不要生成空标题或模板占位。`Validation` 写入本次实际执行或已经
确认通过的验证命令及结果,不要编造未执行的检查。`Base commit` 必须是本次 release
commit。
每条说明都要能追溯到范围内的提交、PR/MR 或项目 CHANGELOG。提交消息和 PR/MR 文本只
作为待核对素材,不能覆盖实际 diff,也不能把范围外变化写入本次说明。创建 tag 前先
生成并检查完整 message,再冻结;tag 已推送后不再修改。
## 验证 release commit
准备版本路径以代码托管平台返回的 merged commit 为准;直接发布路径以计划中锁定的远端
commit 为准。获取远端 base 或允许的维护分支后,确认 release commit 可从对应远端引用
到达,并直接读取该 commit 中的版本文件。不要用当前 checkout 或 feature worktree 中的
文件证明 release commit 内容。
正式 tag 必须满足:
- tag 名按项目格式由目标版本唯一生成。
- tag 必须是 annotated tagmessage 必须是冻结后的完整更新说明,最少包括
`Summary``Changes``Validation``Base commit`;不能只有版本号、提交标题或空
message。禁止 lightweight release tag。
- 远端没有同名 tag,或同名 tag 已经准确指向本次 commit。
- annotated tag 显式指向 release commit。
- 项目要求签名时,push 前已成功创建 signed tag,并在本地验证签名通过;不可用或失败
时停止,不得改用 unsigned tag。
- 推送后从远端重新读取 tag object,核对对象类型和完整说明,再将 annotated tag 解引用
到 commit。
展开 tag pattern 后用 `git check-ref-format refs/tags/<tag>` 校验。把 tag 和 commit 作为
独立 argv 传递,不拼接 shell 字符串。
tag 已在远端指向其他 commit、是 lightweight tag、缺少更新说明或说明不一致时停止。
不要 force push、删除或移动已发布 tag;由维护者决定撤销发布或创建新的修订版本。