| name | release |
| description | 为 STranslate 项目创建发布版本。当用户要发布新版本、打 tag 发版、更新 CHANGELOG、生成版本更新说明时使用。触发短语包括"发布版本"、"打 tag 发版"、"发版"、"更新 changelog"、"准备发布"、"release"、"发一个新版本"。即使用户只是想看看自上次发版后改了什么,也应触发此技能来整理变更。 |
Release — STranslate 版本发布
为 STranslate 项目准备一次正式发布:校验 tag、汇总自上一个 tag 以来的改动、按既定风格生成 CHANGELOG.md,并给出打 tag 推送以触发 GitHub Actions 自动打包发布的步骤。
背景事实(项目现状,开工前已核实)
- 发版触发:推送形如
v2.0.x(v + 三段语义化版本号,x 为占位符)的 tag → .github/workflows/dotnet.yml 在 windows-latest 上构建,并用 CHANGELOG.md 作为 GitHub Release 的 body(body_path: CHANGELOG.md),产物发布到 publish/*。无需 Token,permissions: contents: write。
- 版本号来源:tag 名即版本号。
build.ps1 会去掉 v 前缀并以 /p:Version= 传入 dotnet 构建,同时改写 src/SolutionAssemblyInfo.cs 后用 git restore 还原。不要手动改任何版本号文件。
- tag 形式:历史 tag 为带注释的 tag(
git cat-file -t v2.0.8 → tag),用 git tag -a 创建。
CHANGELOG.md 是整文件覆盖式发布说明,每次发版前重写为本次内容(GitHub Release body 就是它)。
- 插件 NuGet 包版本独立于应用 tag 版本:存在
src/STranslate.Plugin/STranslate.Plugin.csproj 的 <PackageVersion>,仅当 src/STranslate.Plugin/ 下公共 API 有变更时升 patch;版本记录累积在同目录 README.md 顶部。
发布流程
1. 确定版本号(严格校验)
- 取最新 tag:
git describe --tags --abbrev=0(取最新 vX.Y.Z tag)。
- tag 格式严格为
v + 三段语义化版本号,即 v主.次.修订,例如 v2.0.9、v2.1.1、v3.0.9 均合法。v 前缀不可省略,必须是恰好三段数字。
- 默认下一版本 = 当前 patch + 1(如
v2.0.8 → v2.0.9),用于纯 bugfix / 小幅优化发版。
- minor / major 跳级是允许的:若本次含较大新功能可由用户指定
v2.1.0,跨大版本重构可指定 v3.0.0。版本号段由用户决定,技能不替用户判断该跳 minor 还是 patch——但格式必须合规。
- 严禁:去掉
v 前缀、用 v2.0.x 这种字面占位符、四段号或带构建号后缀(如 v2.0.9.1、v2.0.9-beta)、只有两段(如 v2.0)。
- 历史上早期 tag 曾是
2.0.x(无 v)或 1.5.x.x 形式,但 v2.0.0 起统一为 v主.次.修订,新发版一律沿用此格式。
- 如果用户给定版本号,先校验:必须匹配正则
^v\d+\.\d+\.\d+$,否则停下来告知用户格式不符并给出正确建议,不要自行假设。
2. 汇总改动(核心)
- 获取自上个 tag 以来的提交:
git log <上一个tag>..HEAD --pretty=format:"%h %s" --no-merges
合并提交(Merge)默认用 --no-merges 过滤掉,因为它们不携带语义信息。
- 过滤规则(这是本技能的关键约束):
- 忽略纯发版/版本号提交:
chore: update version to v...、docs: update changelog and publish ...、chore: bump version、c1deb830 这类仅改 CHANGELOG / 版本号的提交一律不计入更新说明。
- 忽略新增功能的修复类提交不进 CHANGELOG:用户明确要求"忽略新增功能的修复 commit"。即:
- 修复的是本次开发周期内新增、尚未发布的特性所引入的 bug(提交信息通常是
fix(compact): ...、fix(placement): ...、fix(image-translate): ... 等,且该特性在同周期内才由 feat 引入)→ 不单独列条目,其效果并入对应特性的"添加/优化"条目即可,不单写"修复:xxx"。
- 修复的是既有功能、面向用户历史版本的回归 → 正常列入"修复:"。
- 判断不确定时,看该
fix 涉及的模块在 <上一个tag> 是否已存在:不存在→属于新功能自修,忽略;存在→面向用户的回归修复,列入。
- 忽略纯
chore:(除版本号外如 chore: revert ...、chore)、纯 docs:(设计文档、实现计划、规格说明)、纯内部 refactor: 无用户可见行为变化的提交——除非 refactor 带来了用户可感知的优化(则归入"优化:")。
feat: / perf: / 有用户可见效果的 refactor: / 面向用户的 fix: → 进入更新说明。
- 中文提交信息(如"更新软件&文档描述")按其真实语义归类,拿不准语义的琐碎提交宁可略去,保持更新说明清爽。
- 检测插件契约变更:用
git diff <上一个tag>..HEAD --stat -- src/STranslate.Plugin/ 看插件项目是否有改动;若有,进一步确认是否为公共 API 变更(判断标准见第 3 步)。这是是否执行第 3 步的依据。
3. 同步插件版本号与 README(仅当插件契约有变更)
第 2 步判定 src/STranslate.Plugin/ 下公共 API 有变更时执行本步;无变更则跳过。
什么是"插件契约变更":面向插件作者的公共契约发生变化——IOcrPlugin/ITranslatePlugin/ITtsPlugin/IVocabularyPlugin/IPluginContext 等接口、Service/PluginMetaData 等公共类、LangEnum 等枚举的公共成员被新增/修改/移除。纯 InternalsVisibleTo、纯 internal/private 实现、纯 .csproj 包引用调整不算。拿不准时用 git diff <上一个tag>..HEAD -- src/STranslate.Plugin/<文件>.cs 核实。
升版本号:改 src/STranslate.Plugin/STranslate.Plugin.csproj 的 <PackageVersion>,patch + 1(如 1.0.12 → 1.0.13)。插件 NuGet 包版本独立于应用 tag 版本,不跟 v2.0.x 走,按自身 patch 递增;仅当出现破坏性 API 变更才升 minor/major(罕见,需用户确认)。
迭代 README:在 src/STranslate.Plugin/README.md 顶部(首行介绍之后)新增一条版本记录,格式与历史一致:
## vX.Y.Z - YYYY-MM-DD
- <对插件作者可见的 API 变更,中文,一条一行>
日期取发版当日;变更说明聚焦插件作者视角的契约变化,不写应用层 UI/功能;只追加到顶部,不改历史记录。
本步确定的新插件版本号供第 5 步 CHANGELOG 的 ## 插件开发 区块引用。
4. 分类整理为 CHANGELOG 条目
按项目既有风格,统一用中文动词前缀,不要直接搬运 commit message:
添加:——新功能、新插件、新配置项、新语种等用户能用上的新东西。
优化:——改进既有行为、UI 调整、性能优化、逻辑完善、策略变更。
修复:——仅限面向用户历史版本的回归修复(见上方过滤规则)。
插件开发:——涉及 STranslate.Plugin 契约变更(新增接口方法、新增枚举、参数变更、版本号提升)时使用。可作为 ## 更新 下的内联条目(- 插件开发:...),也可在改动较多时单独成 ## 插件开发 区块。判断依据:是否改了 src/STranslate.Plugin/ 下的公共 API 或提升其版本。版本号由第 3 步提升,区块内首条用「STranslate.Plugin 更新至 1.0.x」开头,再列具体 API 变更。
条目写法要点:
- 一条 commit 可能合并/拆分;以用户视角的变更为粒度,而非 commit 粒度。多个相关 commit 合成一条,描述最终效果。
- 用词贴近既有 CHANGELOG(参见下方"格式模板"),避免出现"重构了代码内部结构"这类用户不关心的实现细节。
- 涉及贡献者在 commit 中提及的(如
@sean908、#711),保留 @用户名 #PR号 的引用写法。
- 涉及具体插件/服务名时用全称或与历史一致的简称(如"腾讯翻译(Transmart)"、"DeepL 插件")。
5. 写入 CHANGELOG.md
整文件覆盖写入,结构严格如下(顺序、标题层级、链接不可变):
## 更新
- 添加:...
- 添加:...
- 优化:...
- 修复:...
## 插件开发
- `STranslate.Plugin` 更新至 `1.0.x`
- ...
## 其他
- [插件市场](https://stranslate.zggsong.com/plugins.html)
- [使用说明](https://stranslate.zggsong.com/docs/)
- [集成调用](https://stranslate.zggsong.com/docs/invoke.html)
- [安装卸载](https://stranslate.zggsong.com/docs/(un)install.html)
- [FAQ](https://stranslate.zggsong.com/docs/faq.html)
**完整更新日志:** [v2.0.7...v2.0.8](https://github.com/STranslate/STranslate/compare/v2.0.7...v2.0.8)
规则:
## 更新 永远是第一行(文件开头无 # 标题、无空白)。条目内顺序:先 添加: 再 优化: 再 修复:,每类内按重要性/相关性排列。
## 插件开发 区块仅当本次确有插件 API / 插件版本变更时才写;没有则整个区块省略,不要留空区块。
## 其他 区块及其五条链接逐字照抄,永远不变。
- 最后一行
**完整更新日志:** 的链接:前一个 tag 和本次 tag 分别替换。仓庘认定为 STranslate/STranslate。
- 若某个分类本次没有任何条目,则该分类整段省略(例如纯 bugfix 版本可能只有
修复:)。
6. 提交并打 tag 发版
- 提交(沿用历史 commit 风格
chore: update version to vX.Y.Z)。除 CHANGELOG.md 外,若第 3 步执行了插件版本/README 更新,则一并 git add:
git add CHANGELOG.md src/STranslate.Plugin/STranslate.Plugin.csproj src/STranslate.Plugin/README.md
git commit -m "chore: update version to vX.Y.Z"
未改插件时只 git add CHANGELOG.md。
- 创建带注释的 tag(与历史一致):
git tag -a vX.Y.Z -m "vX.Y.Z"
- 推送触发自动打包发布(外向操作,推送前向用户确认):
git push origin main
git push origin vX.Y.Z
tag 推送后 .github/workflows/dotnet.yml 会自动构建并发布 GitHub Release,无需手动跑 build.ps1。
自检清单(写完 CHANGELOG、打 tag 前过一遍)
边界情况
- 当前 HEAD 已是某个 tag(即没有新提交):告诉用户自上个 tag 以来无改动,没有发版内容,不要硬凑条目。
- 跨多个特性分支合并:以最终合入 main 的 squash/merge 结果为准,按用户可见变更去重汇总,不要把同一特性的多步 commit 拆成多条。
- 用户只想预览不想发版:只整理 CHANGELOG 草稿展示给用户,不写文件、不打 tag、不推送,等用户确认。
- CHANGELOG 与 release body 的关系:
body_path: CHANGELOG.md 意味着发版时 CHANGELOG 当前内容会原样成为 Release 说明。所以每次发版前必须把 CHANGELOG 重写为本次的内容,历史版本的说明在 GitHub Releases 页面各自留存,无需在文件里累积。