Mole Release Notes Skill:精选双语 Release Notes 的撰写规范、校验清单与发布命令全流程
本文以 Mole 仓库中的 release-notes Skill 文档 为主体,完整讲解在 release.yml 工作流完成之后,如何为既有 V<version> 标签撰写并手动补发精选 Release Notes:从六个前置输入项、五项 pre-flight 校验、严格的双语(English/中文)格式模板与十余条“踩坑后固化”的格式规则,到 gh release edit 发布命令与六枚 reaction 辅助脚本 post-reactions.sh 的逐行实现。读完本文,你可以按 Mole 项目自身的约定独立走完“草稿—用户确认—发布—发布后检查”的完整发布说明流程。
一、定位:为什么 Release Notes 是工作流之后的手动环节
release-notes/SKILL.md 的 description 字段把该 skill 的适用边界写得很明确:
- 只在明确要求“编辑或发布 Mole release notes”时使用;
- 不负责 release readiness(发布就绪检查)、打 tag 或代码评审——这些属于姊妹文档 release-flow/SKILL.md 的职责。
它驱动的是精选 notes 环节,运行在 release.yml 结束之后。从 release.yml 源码可以确认这条流水线的事实依据:
- 工作流只监听大写
V开头的 tag(release.yml#L5-L6 中tags: - 'V*')。小写v1.38.0这类 tag 不会触发工作流,往往意味着打 tag 环节出了问题。 - 工作流通过
softprops/action-gh-release创建 GitHub Release,且显式设置了generate_release_notes: false(release.yml#L110-L118):
- name: Create Release
uses: softprops/action-gh-release@... # v3.0.2
if: startsWith(github.ref, 'refs/tags/')
with:
name: ${{ github.ref_name }}
files: bin/*
generate_release_notes: false
draft: false
prerelease: false
也就是说:工作流已经创建了带资产的 Release,但没有 notes。因此后续补发说明只能用 gh release edit,绝不能用 gh release create——release 已存在,create 会直接冲突。这是该 skill 反复强调的第一原则。
二、动笔前必须收集的六个输入
SKILL.md 的 “Inputs to gather” 一节列出了动笔前必须逐项确认的输入,原文完整继承如下:
- 版本号(Version)。必须是大写
V,例如V1.38.0。小写v不会触发工作流,并且通常说明 tag 打错了。 - 代号(CodeName)+ emoji。向用户索要。标题格式固定为
V<version> <CodeName> <emoji>,例如 release-flow/SKILL.md 中给出的仓库惯例示例V1.45.0 Quiet 🤫。 - Release 提交区间。
git log <previous-tag>..V<version> --oneline提供原始素材。 - 用户可见的行为变化。扫描完整 commit message body(而不只是 subject 行),寻找收窄的检测范围、被移除的功能、受控的回归。这些即使不是 bug-fix 形态,也属于“用户在生产环境会撞上变化边界”的内容,必须写入 notes。
- 本周期的 Issue 报告者与 PR 贡献者。基于 release 区间内的 merged PRs 与 fixed issues。名单保持简短,格式如
Issue reporters and PR contributors this cycle: @a · @b.;排除tw93本人和 bot 账号。 - 确认 Release 已存在。执行
gh release view V<version> --repo tw93/Mole --json id,name,返回非空才算数。若为空,说明工作流还没跑完——等待,而不是手动gh release create。
其中第 6 点与 release-flow/SKILL.md 的 “Release-only pitfalls” 一节互相印证:工作流在 tag push 时就已创建 release,tag 之后的补发必须走 edit 通道。
三、Pre-flight:发布 notes 之前的五项交叉校验
SKILL.md 要求在发布前对照 AGENTS.md 的约定做交叉校验。正常情况下 tag 打得对,这些应该已经成立,但发布 notes 前仍要逐项确认:
| 校验项 | 命令/检查 | 当前仓库现状(佐证) |
|---|---|---|
| 主脚本内版本号 | grep '^VERSION=' mole 与 <version> 一致 |
mole 第 57 行为 VERSION="1.53.0" |
| 安全审计文档头部 | SECURITY_AUDIT.md 首行反映新版本与日期 | 其第三行为 ... updated for V1.53.0 on 2026-08-30. |
| 格式检查 | ./scripts/check.sh --format 通过 |
见 scripts/check.sh |
| Shell 测试套件 | MOLE_TEST_NO_AUTH=1 MOLE_TEST_JOBS=2 BATS_FORMATTER=tap ./scripts/test.sh 退出码 0 |
见 scripts/test.sh 与 tests/ 下的 bats 用例 |
| Go 侧构建 | go test ./cmd/... 与 make build 均通过 |
见 Makefile 的 build/release-* 目标 |
SKILL.md 对失败的处理只有一句话,但态度明确:“If any fail, stop. The notes can wait; a bad release tag cannot.”(任何一项失败就停下——notes 可以等,坏掉的 release tag 不行。)
四、格式规范:双语紧凑模板与“踩坑固化”的规则
4.1 唯一的格式基准:最近一次稳定 release 的正文
SKILL.md 要求动笔前先读取当前最新稳定 release 作为活的格式参考:
gh release view --repo tw93/Mole --json tagName,body
这对应 release-flow/SKILL.md 中 “Ritual anchors” 的说法:草稿前读取最近稳定 release 正文是“硬格式模板”(hard format template)。仓库中保留的 docs/release-notes/V1.42.0.md 是一份历史样本,可以看出格式的历史演变(它仍带 ### Thanks 💖 标题与尾部仓库链接,而现行 skill 明确规定这两者已不存在)。
4.2 结构模板(完整继承)
严格按当前紧凑形态组织:
<div align="center">
<img src="https://cdn.tw93.fun/pic/cole.png" alt="Mole Logo" width="120" height="120" style="border-radius:50%" />
<h1 style="margin: 12px 0 6px;">Mole</h1>
<p><em>Deep clean and optimize your Mac.</em></p>
</div>
### Changelog
1. **<English headline>**: <one-sentence English elaboration>.
2. ...
### 更新日志
1. **<中文 headline>**:<一句中文说明>。
2. ...
### Thanks
Issue reporters and PR contributors this cycle: @handle1 · @handle2.
### Mole Mac App
Prefer a GUI? [Mole Mac App](https://mole.fit/) brings cleaning, app management, maintenance, disk analysis, and live system status into one native app, with review before deletion and a customizable menu bar HUD. It is $19 once, with lifetime updates and a 14-day refund. [Download and try it](https://mole.fit/download). The CLI stays free and open source.
两条全局约定:章节之间不使用 --- 分隔线;文末不追加仓库链接——公开页面以 Mole Mac App 一段收尾。
4.3 格式规则:每一条都是“曾经真实出货过的 bug”
SKILL.md 特别强调,下列规则全部是曾经真实流出过的文档 bug,因此逐条固化:
- 正文 h1 只能是
Mole。版本号、代号、emoji 只出现在--title参数里(V<version> <CodeName> <emoji>);在正文头部重复它们是冗余,之前曾被明确驳回。 - 全文禁止 em dash(—)。用逗号、句号、冒号、分号或括号替代。
- 默认不放赞助商列表。当前公开风格只感谢本周期的 Issue 报告者与 PR 贡献者。
- 除 release 标题中的版本 emoji 外,正文禁止任何 emoji。章节标题保持朴素,包括
### Thanks(旧版Thanks 💖标题已从公开页面移除)。 - 正文不内联 PR 引用,不内联
@handle感谢。PR 与人名只允许出现在专门的 Thanks 区块。 - 英文块在前、中文块在后;两个块编号顺序一致、条目数量相同。
- 按用户可感知影响排序,而非 commit 时间顺序。headline 级变化放最前,内部安全加固、性能与 bug 修复随后。
- 不要描述已不存在的 overview 图标。Analyze 概览行是纯文本,因为 emoji 宽度与基线在不同终端表现不一;若日后图标回归,也不得暗示 iOS Backups、Xcode Archives、Old Downloads 这类用户数据可以安全删除。
- notes 中提到的每条命令都必须在 HEAD 上真实存在。被删除的
mo check/mo doctor命令曾在移除后险些作为“新特性”写进 notes——这正是做存在性验证的原因。 - 事故/排障类说明 = 一句症状 + 一条命令。不做原因分类,不逐分支给命令;用户需要的只是让他“解套”的那一行。并且对齐上一次 release 的语言处理:若上次 release 只用一种语言写了该条说明,这次不要补第二种。
- Mole Mac App 交叉链接保持为一个克制、事实可证的段落。发布前对照当前首页核验产品范围、价格、更新策略、退款窗口与下载 URL。
对照 docs/release-notes/V1.42.0.md 这份历史样本,可以更直观地理解规则演进:它的 ### Thanks 💖 标题、英文条目缺少一句话 elaboration、以及末尾的仓库链接,都恰好是现行规则要剔除的形态——现行模板要求每条 changelog 为“加粗 headline:一句话说明”,并移除了尾部链接与 emoji 标题。
五、发布:gh release edit 与六枚 reaction
5.1 编辑命令
用户批准草稿后,SKILL.md 给出的发布命令是:
gh release edit V<version> --repo tw93/Mole \
--title "V<version> <CodeName> <emoji>" \
--notes-file <path-to-draft>
再次强调:永远不要 gh release create,它会与工作流已创建的 release 冲突。
5.2 六枚 reaction 的辅助脚本
发布 notes 后,用该 skill 自带的辅助脚本补上标准六枚 reaction(+1、laugh、hooray、heart、rocket、eyes)。注意脚本路径是相对 SKILL.md 自身的 scripts/post-reactions.sh,而不是仓库根目录的 scripts/:
bash "$(dirname <this SKILL.md>)/scripts/post-reactions.sh" V<version>
post-reactions.sh 的完整实现如下,逻辑非常短平快,可逐行验证:
#!/bin/bash
# Add the standard six reactions (+1, laugh, hooray, heart, rocket, eyes) to a
# tw93/Mole release. Usage: post-reactions.sh V<version>
set -euo pipefail
TAG="${1:-}"
if [[ -z "$TAG" ]]; then
echo "Usage: $0 V<version>" >&2
exit 1
fi
if [[ "$TAG" != V* ]]; then
echo "Tag must start with capital V (release.yml ignores lowercase v): $TAG" >&2
exit 1
fi
if ! command -v gh > /dev/null 2>&1; then
echo "gh CLI is required" >&2
exit 1
fi
RELEASE_ID=$(gh api "repos/tw93/Mole/releases/tags/$TAG" --jq '.id')
if [[ -z "$RELEASE_ID" ]]; then
echo "Release not found for tag: $TAG" >&2
exit 1
fi
for r in +1 laugh hooray heart rocket eyes; do
gh api "repos/tw93/Mole/releases/$RELEASE_ID/reactions" \
-X POST -f content="$r" --silent
done
echo "Posted 6 reactions to $TAG (release id $RELEASE_ID)"
从源码看,脚本内置了三道护栏:
set -euo pipefail:任何一步失败立即中止;- tag 前缀大小写校验:
[[ "$TAG" != V* ]]直接拒绝小写 tag,错误信息里还顺带解释了原因(release.yml 忽略小写v)——与 release.yml 的'V*'过滤条件严格一致; - Release 存在性校验:先经
gh api .../releases/tags/$TAG取id,取不到就报错退出,不会盲发。
拿到 RELEASE_ID 后循环向 releases/$RELEASE_ID/reactions 逐枚 POST,最后打印确认行 Posted 6 reactions to $TAG (release id $RELEASE_ID)。release-flow/SKILL.md 还要求发布后重新读取 release 的 reactions 确认六枚全部落位。
六、发布后动作
SKILL.md 的 “After publish” 两项:
gh release view V<version> --repo tw93/Mole --web在浏览器中打开,让用户肉眼检查渲染效果;- 提醒用户:Homebrew Core 的版本 PR 由工作流驱动,此时应该已经在途;除非工作流日志显示失败,不要手动重跑。
这与 release.yml 中 build job 之后的 update-homebrew-core job 相印证:同一次 V* tag push 会串行触发构建、创建 Release 与 Homebrew PR,人工只需要在 notes 环节介入。
七、When NOT to act:调用边界与隐式调用禁用
该 skill 是纯用户可调用(user-invocable only)的,front matter 中 disable-model-invocation: true 声明了这一点,不允许被模型自行触发。具体行为边界:
- 用户只是顺带提到 release notes 时:只出草稿,不要调用
gh release edit; gh release view显示 release 尚不存在时:等待工作流,不要手动创建竞争的 release;- 用户没有给出明确的 “publish” / “提交” 信号时:草稿交付即止。
在 Codex 一侧,release-flow/SKILL.md 提到 .agents/skills/release-notes 是指向 .claude/skills/release-notes 的符号链接(供 Codex 发现机制使用),其专属调用策略存放在 agents/openai.yaml,内容为一行 policy: allow_implicit_invocation: false。该文档同时叮嘱:不要把符号链接替换成拷贝副本,且以 release-notes skill 作为 notes 格式的唯一事实来源(single source of truth),不要在 release-flow 中重复其格式细节。
八、与 release-flow skill 的分工小结
结合 release-flow/SKILL.md,两个 skill 的职责切分可以归纳为:
| 环节 | 归属 | 关键点 |
|---|---|---|
| 打 tag、资产构建、SHA256SUMS、Homebrew PR | release-flow | 大写 V tag;安装校验是 fail-closed,缺 SHA256SUMS 即发布阻断项 |
| 发布前的脚本自更新冒烟 | release-flow | 用旧版脚本安装 → mo update → 确认 mo --version 输出候选版本 |
notes 草稿格式、Thanks 区块、gh release edit |
release-notes(本文主体) | 只 edit 不 create;双语同序同数量 |
| 六枚 reaction 与发布后检查 | release-notes(本文主体) | post-reactions.sh 位于 skill 目录内 |
对维护者而言,这套文档的价值不在单条命令,而在于把“哪些坑流出过货”固化成了可执行的清单:大写 V、只 edit 不 create、命令存在性核验、影响排序、Thanks 区块的排他性——每一条背后都是一次真实事故的复盘,这也是 Mole 这类以 Shell 为主、发布流程高度自动化的项目能够保持 release notes 风格长期一致的原因。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00