cat-xierluo/legal-skills/release-workflow

Claude Code and agent skill by cat-xierluo/legal-skills

Trust tier 2
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

本技能应在 GitHub 项目发布新版本时使用,覆盖版本号管理、CHANGELOG 同步、Release Notes 撰写、tag 创建、CI 构建监控、发布验证和历史清理全流程。适用于桌面应用、CLI 工具、Web 应用、库/SDK 等任何基于 GitHub 的软件项目。当用户提到"发布"、"release"、"打 tag"、"新版本"、"更新版本号"、"写 release notes"、"发布失败了"、"CI 挂了"、"Actions 配额告急"、"短时间内多次发版"、"monorepo"、"批量打包"、"多 skill 发布"、"skill zip"、"专家套件 zip"时触发。也用于拒绝把 release 当作 CI 验证机制("打 tag 看一下")的反模式场景。不要用于非 GitHub 项目(如纯 GitLab / Gitea 项目)或无需 CI 的手动发布场景。

Install

npx vskill@latest install cat-xierluo/legal-skills/release-workflow

SKILL.md

Release Workflow

软件项目的全流程发布工作流。适用于 GitHub 上的任何类型项目。

适用场景

GitHub 项目的完整发布周期:从版本号确定到 CI 构建验证。CI 故障排查(references/ci-troubleshooting.md)和特定项目类型指南(references/ 下各文档)作为发布流程的补充参考。

与 git-workflow 的职责边界:本技能只负责发版流程内的 CI 构建监控(第 4 步)与发布成本约束(配额红灯)。日常 Actions 配额治理——CI 分钟耗尽停挂止血、workflow 停挂/恢复、workflow_dispatch 化、仓级总闸——由 git-workflow §11 负责。发版中出现 CI 故障:构建产物/签名/发布链路问题读本技能;账号级配额治理问题转 git-workflow。

项目配置

config/projects.yaml 集中管理各项目的发布配置(仓库、平台、自动更新、排除产物等)。发布时先读取对应项目配置,按配置决定构建矩阵和预期产物。模板见 config/projects.example.yaml。

带应用内更新的桌面项目,还必须读取 真实升级与热修门禁:验签、旧客户端能力、进程回收、数据恢复和实际安装路径分别验收。

发布前检查

检查项说明
工作区干净git status 无未提交变更
版本号一致所有版本号文件(package.json / Cargo.toml / pyproject.toml 等)与 CHANGELOG.md 最新条目一致
CHANGELOG 已更新包含目标版本的结构化条目
CI 工作流存在.github/workflows/ 中有 release 相关工作流且 tag 触发配置正确
本地测试门禁npm test(或项目对应单测命令)整体通过。单条失败先重跑确认是否偶发再定性:偶发 flaky(非本次改动引入的回归)修测试或单独跟进,不要因此阻塞发布;但若全量多次复现、指向真实回归,必须先修复再发版

任一条件不满足,先修复再继续。

⚠️ Release ≠ 测试 — 强制约束

打 tag / 创建 GitHub Release 是把版本号给真实用户,不是 CI 验证机制。把 release workflow 当作"看 CI 跑没跑通"或"我下载个 artifact 自己测一下"是反模式,必须禁止。

为什么是绝对规则
  • Actions 配额是有限共享资源。单次跨平台 release(macOS × N + Windows + Linux)通常消耗 300-600 配额分钟,macOS runner 是 10× 费率,贡献最大。
  • 错把 release 当测试的隐性成本:
  • GitHub Release 一旦创建(即使是 draft)就被计入资产历史,污染 release feed
  • tag 推送后 commit 被人看到会误以为已发布
  • 自动更新用户可能在升级检查时看到不稳定的版本
  • 配额快速耗尽,真正紧急的 hotfix 反而跑不动 CI
  • 过去能这么干不代表现在该这么干。GitHub 免费配额调整、macOS runner 涨价都发生过,使用模式必须随成本变化更新。
禁止的反模式
反模式表现为什么错
把 tag 当 smoke test"我改了一行,打个 tag 看看 CI 跑不跑得通"一次 release 吃掉 300+ 配额分钟,5 次测试 = 一月配额清零
用 release 验证构建产物"我想看 .dmg 长什么样,必须跑 release"应该用专门的 preview / draft build workflow(见下)
同一天 / 24h 内发多个 patchv0.3.16 / 17 / 18 一天内连发,各是同一个 bug 的连续小修全部攒到下次一起发,成本立省 60%+
draft release 当"先跑一次试试""我先 draft release 看 artifact 行不行"draft 一样跑完整 CI,一样消耗配额,一样污染 release 历史
单平台 dry-run 验构建"先跑 Linux dry-run 看看,不发全平台"dry-run 一样消耗 CI 时间,开了口子就停不下来;改走 preview workflow
小改动发 patch"我改了 typo / 改了一行文档,必须 vX.Y.Z"纯 typo / 文档小改 / 单文件改动不构成发版理由,合并到下个有实质内容的版本
"已经打 tag 了,跑都跑了""v0.3.22 tag 已经推上去了,CI 反正也在跑""已经做了"不是继续做的理由;记录这次浪费并阻止下次重复
正确做法

A. 想验证 CI 跑不跑得通 / 看构建产物长什么样?

  • 用 pull_request 触发的 preview workflow(可只跑 ubuntu / 单一平台,几十分钟完成)
  • 或在 main 上用 workflow_dispatch 手动触发 dry build,不触发 release workflow
  • 这两种都不消耗 macOS 高倍率配额,artifact 只对自己可见

B. 真的有用户能拿到的修复要发?

  • 等攒到 3-5 个实质修复(bug fix / feature / 性能 / 兼容性改动)
  • 一次性打 tag 发版,只发一次
  • CHANGELOG 必须有结构化条目,不能空
  • 常规发布距离上次 tag 至少 24 小时;真实用户的安装/更新阻断 hotfix 可按下方例外提前发布(防止把同一问题的试错拆成多个 patch)
打 tag 前强制自检(AI 不得跳过)

打 tag 之前,必须回答下面 5 个问题。AI 代理被请求发布新版本时,必须主动逐条打印最终候选自检结果;缺少该版本的明确发布授权时再请用户确认,不得跳过验证直接打 tag。

  1. 这是给真实用户装的,还是只给自己看 artifact?
  2. CHANGELOG 已经有结构化的本版本条目(不是空、不是单行 typo)?
  3. 距上次 tag ≥ 24 小时?
  4. 本次累计有 ≥ 1 个实质修复 / 特性 / 改动(纯文档 / typo / 单行 README 修改不算)?
  5. 如果上述任一不满足:能合并到下次发版吗?

第 1、2、4 问答“否”或关键证据未知:不要打 tag。第 3 问不足 24 小时,只有已复现的真实安装/更新阻断且用户明确授权的 hotfix 才可例外;说明原因、独立审查和完整候选验证结果,禁止用例外进行发行试错。

AI 代理实操规则:打 tag 前显式列出五问答案,并绑定最终候选与验证。用户已明确授权该版本及 hotfix 范围时,沿用授权,不重复索取同一确认;未获授权时先完成可审阅候选再确认。授权不代替验证,禁止通过反复移动同一个 tag 排查问题。

借口反驳表
借口现实
"我就看一眼,tag 一下马上回滚"tag 推送已经触发了完整 CI,回滚 tag 不能退款 Actions 分钟
"用户催着要"用户不知道你的 Actions 配额,告诉 ta 合并到明天的成本和时间,让 ta 选
"反正之前都这么干"之前能用不等于现在合理,这正是 91% 配额的直接成因
"只有 release workflow 跑完整矩阵"加一个 preview workflow(成本是 release 的 10-20%),不要用 release 凑合
"draft release 不算正式发布"draft 一样跑完整 CI、一样消耗配额、一样污染 release 历史
"小改动发 patch 很常见"纯 typo / 文档 / 单行不构成发版理由,合并到下个有实质内容的版本
"我已经打 tag 了,跑都跑了""已经做了"不是继续做的理由;记录这次浪费,阻止下次重复
"单平台先 dry-run 一下"dry-run 一样消耗 CI 时间,开了口子就停不下来;改走 preview workflow
"这次不一样,这次真的需要发"SemVer 的 patch 版本本来就允许累积;下次发版不是更优解吗
红灯(看到任一就停)
  • 同一工作日内想发第二次 tag
  • 距上次 tag < 24 小时
  • CHANGELOG 没有本版本的结构化条目就想发
  • 想用 "draft release" 当测试
  • 想用 workflow_dispatch 触发 release workflow 当测试(应该触发独立的 preview workflow)
  • 本次只有 typo / 文档 / 单行修改
  • macOS 10× 配额当月累计用量已 > 70%

出现红灯先停止发行副作用并核对原因。真实 hotfix 频率例外见上文;保留失败证据,不自动删除或移动 tag,已公开版本不得覆写。

🔥 修复 hotfix 与 CI retry 边界(关键)

patch 版本(X.Y.Z+1)可以是 新功能累积,也可以是 hotfix 单一修复。区分清楚才能避免「把 release 当测试」反模式。

何时属于「hotfix 真实修复」(发布新的 patch 版本)
  • 第一次 release 后用户实际收到 broken build(自动更新坏 / 安装失败 / 启动崩溃)
  • 根因明确指向代码或配置 bug,已有可复现失败和修复验证;只有 CI 构建失败但尚无用户收到的版本,不以 hotfix 理由对外发行
  • 每个新版本都有可验证的 commit 推进(修一行、改一个配置、新增测试)

判定信号:gh run view --log-failed 输出包含具体 error line(不是单纯的 Timeout / Resource exhausted 这种 transient 错误)。

何时属于「把 release 当测试」(禁止发行试错)
  • 单纯想看 CI 跑没跑通、看 artifact 长什么样
  • 上一次 build 失败但没看失败原因就直接重打
  • 第三次以上重打同一个版本号(按成本曲线,超过 3 次几乎都在反复折腾 transient)
transient vs 真实 bug 的快速判定
build job 失败:
- 输出含 E0599 / Cargo compile error / 链接错误 → 真实代码 bug,修代码再重打
- 输出含 "Timeout" / "Resource exceeded" / "Killed" → transient,可直接重试
publish job 失败:
- 输出 "Missing signatures" + 产物清单缺 sig → 检查 includeUpdaterJson + bundle.targets(详见 tauri-release.md 红线 8)
- 输出 "Signature not found for the updater JSON. Skipping upload..." → tauri-action 跳过整批 updater,检查 build 产物目录
- 输出 "Unable to download" / "rate limit" → transient
本地单测(vitest / jest)失败,发布前门禁:
- 单条 "Timed out waiting for condition" 超时失败 → 大概率 flaky(轮询式 waitUntil + 动态 import 的异步链在测试环境下偶发跑不完),先重跑该文件确认;连跑仍偶发则修测试(轮询预算给足),不属于本次改动引入的回归,不阻塞发布
- 多条/全量复现、或错误指向具体代码行为 → 真实回归,先修代码再发版

最佳实践:先 gh release view <tag> --json assets,isDraft,targetCommitish 看产物与状态,再决定修代码或重跑固定候选构建。

修复 hotfix 的标准动作序列
  1. 复现失败发生在哪个旧版本、哪个阶段,区分验签、准备、安装、重启和恢复;读取日志,不用新 Release 试错。
  2. 在独立工作树修复并同步版本/CHANGELOG,完成固定候选独立审查、项目检查及真实升级验证。
  3. 已公开版本使用新的 patch 版本,禁止移动原 tag 或覆盖原二进制、签名、manifest。仅 Draft 重传也须先确认仍为 Draft、冻结候选并重新验收,不能 upload 后才检查状态。
  4. 五问自检通过(或已授权且有证据的 hotfix 频率例外)后,给最终已验 commit 打新 tag,生成 Draft。
  5. 核对安装包、updater、标准验签、manifest 与实际运行版本;明确旧客户端是否需先手动覆盖一次,最后按既有授权公开。完整合同见 真实升级与热修门禁。

模式 B:monorepo 多组件批量发布

适用:一个仓库下有 N 个独立可发布的子项目(skill 集、CLI 工具集、npm 包集等),希望一次 tag 同时发布所有子项目的 zip;也支持由仓库内符号链接定义、Release 时展开为真实目录的专家套件 zip。

前置:对应项目需在 config/projects.yaml 有 type: monorepo-skills 条目,并配套 scripts/build-zips.sh + scripts/release-monorepo.sh。启用专家套件时,再配置 expert_suites_root 并使用 validate-expert-suites.py + build-suite-zips.sh;完整 SOP 见 references/monorepo-release.md。

与模式 A 的关键差异(相对单仓库单应用):

维度模式 A(单应用)模式 B(monorepo)
tag 频率每应用 1 tag每发布轮次 1 tag(常用 CalVer)
zip 命名<App>-<ver>.<ext><skill>-<semver>.zip;套件为 suite-<id>-<semver>.zip
Release Notes单应用 changelogN 个 skill changelog 合并
验证平台矩阵(win/mac/linux)子项目数量清单 + 关键项抽查
回写 README不适用是(把 latest URL 写进表格)

核心流程(详见 references/monorepo-release.md):

  1. 读 projects.yaml 的 <project-key> 条目,获取 skills_root、expert_suites_root、output_dir、exclude_globs
  2. 跑 build-zips.sh <tag> 生成单 Skill ZIP;存在专家套件时,再跑静态校验与 build-suite-zips.sh <tag>
  3. 打 tag、推 tag
  4. GitHub Actions(release.yml)自动:上传单 Skill ZIP + 专家套件 ZIP + 生成 Release Notes(含「专家套件」清单节) + 内嵌 README 回写(checkout main → 调 scripts/update-readme.py 同步根 README 与 expert-suites/*/README.md 的下载链接 → commit + push)
  5. 验证 release 页 assets 数量 = 单 Skill ZIP 数 + 套件 ZIP 数;Release Notes 里的 skill 总数取自产物目录但排除 suite-* 前缀,套件数用 {suites} 单独渲染
README 回写不依赖 on: release 事件——GITHUB_TOKEN 创建的 Release 受 GitHub 防递归机制限制,不会级联触发其他 workflow(实际从未生效过)。update-readme.yml 以 workflow_run(Release workflow 成功后)+ workflow_dispatch 作兜底,与 release.yml 调用同一份 scripts/update-readme.py,不存在第二份逻辑;workflow_run 触发时 checkout 显式 ref: main(默认会 checkout 到 tag SHA 的 detached HEAD,push 失败)。

下载链接检查必须匹配实际下载列 href 的完整资产路径,不能用正文里的正确 URL 掩盖错误链接。源码版本取当前 CHANGELOG,下载列取真实资产版本;部分热补保留其他组件已发布的固定 tag 链接,不把源码版本改成旧 ZIP 版本。首次发布后自动为已有行补下载链接、按源码与资产差异更新待发布标记;没有资产时只写未发布,不生成未来 URL。行顺序由 README 策展维护,自动回写不排序。源码检查不联网证明资产存在;保留的公开链接应先对照真实 Release 资产核实,不要用 align-suite-links.py 把源码 README 改成尚不存在的新版本下载。

  • 严格默认:validate-expert-suites.py 不带模式仍要求当前版本下载入口;--mode release 为相同严格检查。
  • 源码/prebuild:显式 --mode source 允许真实旧版入口,但成员作用列须准确写 ;源码 v<当前版本> 待发布;尚无公开成员包时,下载列写 尚无公开下载。已有整套旧包使用独立行 > 整套源码 v<当前版本> 待发布;首次未发布套件使用 > 整套源码 v<当前版本> 待首次发布(尚无公开下载),不得另加未来 ZIP 占位 URL。成员、许可证、Git 跟踪、name、版本和链接边界检查不降级。
  • Preview:SUITE_BUILD_MODE=preview bash scripts/build-suite-zips.sh pr-<编号>,展开同一源码快照并保留真实公开链接/待发布说明;不把 PR 预览说成 GitHub Release 下载。
  • 本地 Release staging:先生成当前成员 ZIP,再以默认 release 模式构建套件。staging renderer 核对成员 ZIP 的完整文件集合及逐文件字节、拒绝 symlink/重复文件,随后只在临时目录重写本次 tag 和实际成员版本。源码工作树及 .gitattributes 必须与 SOURCE_REF 一致;失败不覆盖上一批套件包。此本地构建不执行上传或发布,正式发布仍按原授权门禁。

专家套件成员以 expert-suites/<id>/skills/* 的相对符号链接为唯一构建清单,不增加 suite.yaml。构建器先校验链接未逃逸、README 成员表一致、成员许可证齐全,再从指定 Git tree 导出真实 Skill 目录;Release ZIP 中不得保留符号链接。

README 结构性同步(发版必查,回写覆盖不了的部分):自动回写只处理已有表行的链接与版本列;加行、分节归属、描述是结构性维护,必须在发版环节人工/AI 完成——

  1. 跑 scripts/check-readme-coverage.py:Release 每个资产在 README 技能表必须有行、有下载链接(独立仓库行豁免);缺行说明新技能/迁移技能没同步 README,先补行再发版或发版后立即补
  2. 分节归属自查:行的分节与技能性质一致——通用工具类(报销整理、签到、复盘等)不进「法律专业应用」节;分类标签(第 2 列)与许可证、SKILL.md description 相互印证
  3. 描述与 skills/<name>/SKILL.md frontmatter 一致,不得凭空编写

不要用于:单应用桌面/CLI/Web 项目(用模式 A 上文 7 步流程)、跨仓库分发(用 subtree-publish skill)。


所需权限与副作用

  • 本地 Preview 只读取当前 Git tree,并在仓库 pack-skills/ 写入 ZIP;不会创建 tag、联网、安装依赖或修改 README。
  • 正式发布会读取 Git 状态、执行 git fetch、创建 annotated tag、把已核验的不可变 tag OID 推送到 origin,并通过 gh 读取 Actions 与 Release 状态。执行前必须完成 Release 五问并设置 RELEASE_CONFIRMED=1。
  • 正式发布只允许从干净、非 detached、且 HEAD 与 origin/main 一致的 main 工作树执行;已有同名本地或远端 tag、身份缺失、CI 失败或资产数不一致均 fail-closed。
  • RELEASE_GIT_NAME 与 RELEASE_GIT_EMAIL 可显式绑定 tagger 身份;未设置时读取当前 Git 身份,但字段为空会阻断。
  • 下载链接回写由权限仅为 contents: write 的 update-readme.yml 在 release workflow 成功后执行;本地发布脚本不提交或推送分支。
  • 脚本仅访问 GitHub 当前仓库及其 Actions/Release API,不读取云服务凭证内容;Token 由 GitHub Actions 或 gh 自身管理,不写入产物和日志。

发布流程

第 1 步:确定版本号

从用户处获取或从 CHANGELOG.md 读取目标版本号。

统一所有版本号文件(按项目类型选取):

  • Node.js 项目:package.json → version
  • Rust 项目:Cargo.toml → version
  • Python 项目:pyproject.toml → version
  • 桌面应用:对应配置文件(如 Tauri 的 tauri.conf.json)
  • CHANGELOG.md → 最新 ## [x.y.z] 条目

版本号规则(SemVer):

类型示例适用场景
PATCH0.3.7 → 0.3.8Bug 修复、小改进
MINOR0.3.x → 0.4.0新功能、向后兼容
MAJOR0.x → 1.0.0重大架构变更、破坏性改动
第 2 步:生成 Release Notes

信息来源有两个,必须综合使用:

来源 1 — `CHANGELOG.md`:结构化的变更分类(Added / Changed / Fixed 等)

来源 2 — `git log`:两个 tag 之间的 commit 历史,补充上下文和细节

bash
# 获取上一个 tag
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
# 查看 commit 历史
git log ${PREV_TAG}..HEAD --oneline
# 查看详细变更(含 PR 链接)
git log ${PREV_TAG}..HEAD --format="- %s (%h)"

来源 3 — PR 作者信息(外部贡献者识别):

bash
# 本版本区间合入的 PR 与作者(识别需要致谢的外部贡献者)
gh pr list --state merged --limit 50 --json number,title,author \
--jq '.[] | "\(.number)\t\(.author.login)\t\(.title)"'

外部贡献者(非维护者)的 PR——包括被「承接 #N」重做的原始 PR——必须在 Release Notes 中致谢:条目行内 (#N, @user) + 文末「贡献者」节。识别方法与格式细则见 references/release-notes-guide.md「贡献者致谢」。

综合三个来源,按模板组织 Release Notes。模板和格式指南见 references/release-notes-guide.md。如果 config/projects.yaml 中存在 release_notes.profile,优先使用项目配置指定的结构;未配置时按项目类型选择默认结构。

第 3 步:提交并打 Tag
bash
# 确保所有变更已提交
git status
# 打 tag
git tag "vX.Y.Z"
# ⚠️ 必须校验:tag 指向的 commit 包含版本号同步 commit。
# 重打 hotfix 时常见坑:只改了 release.yml 没把 4 处版本号文件也升到 X.Y.Z,
# 导致产物文件名仍带旧版本号(如 Folia_0.4.0_* 但 tag 是 v0.4.1)。
git show vX.Y.Z --stat | head -20
# 确认 package.json / Cargo.toml / tauri.conf.json / CHANGELOG.md 都在 commit 里
# 推送 tag 触发 CI
git push origin "vX.Y.Z"

若同名 tag 已存在,先核其完整 OID、Release 状态及用户可见性。不得删除并重打已公开 tag。代码修复使用新 patch;固定候选的 transient 构建故障可重跑同一 workflow,仍须保留证据。未公开 Draft 的资产重传按 热修门禁 执行。

第 4 步:监控 CI 构建
bash
# 查看构建状态
gh run list --limit 3
# 各平台 job 状态
gh run view <RUN_ID> --json jobs --jq '.jobs[] | "\(.name): \(.conclusion)"'
# 失败日志
gh run view <RUN_ID> --log-failed

项目类型的特定构建产物和验证方法,见 references/ 下对应文档。

第 5 步:更新 Release Notes

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 86 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
707
Repository forks
106
7-day trend score
33

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/cat-xierluo/legal-skills/release-workflow/badge)](https://verified-skill.com/skills/cat-xierluo/legal-skills/release-workflow)

Something wrong with this skill or its page? Tell us.