Merge branch 'main' of https://git.yumee.top/laily/.pouch
This commit is contained in:
@@ -56,11 +56,15 @@ AGENTS.md # 本文档
|
|||||||
| [draw-prototype-flow](skills/draw-prototype-flow/README.md) | 把产品想法画成可编辑的 Draw.io 低保真原型和用户动线 |
|
| [draw-prototype-flow](skills/draw-prototype-flow/README.md) | 把产品想法画成可编辑的 Draw.io 低保真原型和用户动线 |
|
||||||
| [eli5](skills/eli5/README.md) | 用大图少字的单页 HTML 把话题讲给完全没背景的人听 |
|
| [eli5](skills/eli5/README.md) | 用大图少字的单页 HTML 把话题讲给完全没背景的人听 |
|
||||||
| [host-sec-check](skills/host-sec-check/README.md) | 对 Linux/VPS 做入侵取向的安全检查,默认只出报告 |
|
| [host-sec-check](skills/host-sec-check/README.md) | 对 Linux/VPS 做入侵取向的安全检查,默认只出报告 |
|
||||||
| [manage-release](skills/manage-release/README.md) | 给已准备好的 commit 发版本:更新说明、tag、可选 Forge Release |
|
|
||||||
| [memory-distill](skills/memory-distill/README.md) | 任务结束后把可复用结论写入通用记忆和项目记忆 |
|
| [memory-distill](skills/memory-distill/README.md) | 任务结束后把可复用结论写入通用记忆和项目记忆 |
|
||||||
| [note-style](skills/note-style/README.md) | 把材料整理成可长期查阅的知识笔记 |
|
| [note-style](skills/note-style/README.md) | 把材料整理成可长期查阅的知识笔记 |
|
||||||
| [orc](skills/orc/README.md) | 把开发、发版、DEB / Docker 意图编排成阶段,按档位分发给对应 skill |
|
| [orc](skills/orc/README.md) | 把开发、发版、DEB / Docker 意图编排成阶段,按档位分发给对应 skill |
|
||||||
| [pouch](skills/pouch/README.md) | 创建、校验、安装和维护 builtin skill |
|
| [pouch](skills/pouch/README.md) | 创建、校验、安装和维护 builtin skill |
|
||||||
|
| [releaser](skills/releaser/README.md) | 给已准备好的 commit 发版本:更新说明、tag、可选 Forge Release |
|
||||||
|
| [manage-release](skills/manage-release/README.md) | 已弃用:`releaser` 的旧名兼容占位,不含流程 |
|
||||||
|
|
||||||
|
改名后旧名保留一个纯占位 skill,避免已装软链悬空和旧项目 `.pouch.yaml` 失效。确认没有
|
||||||
|
项目再按 `manage-release` 启用后,删除 `skills/manage-release/` 即可,不丢任何内容。
|
||||||
|
|
||||||
|
|
||||||
新建 skill:优先 `pouch create`;或复制 `skills/_template/` → `skills/<name>/`,编辑 `SKILL.md` 和 `README.md`,在本仓库 commit。
|
新建 skill:优先 `pouch create`;或复制 `skills/_template/` → `skills/<name>/`,编辑 `SKILL.md` 和 `README.md`,在本仓库 commit。
|
||||||
|
|||||||
@@ -92,11 +92,12 @@ AGENTS.md # 详细规范与架构说明
|
|||||||
| [draw-prototype-flow](skills/draw-prototype-flow/README.md) | 把产品想法画成可编辑的 Draw.io 低保真原型和用户动线 |
|
| [draw-prototype-flow](skills/draw-prototype-flow/README.md) | 把产品想法画成可编辑的 Draw.io 低保真原型和用户动线 |
|
||||||
| [eli5](skills/eli5/README.md) | 用大图少字的单页 HTML 把话题讲给完全没背景的人听 |
|
| [eli5](skills/eli5/README.md) | 用大图少字的单页 HTML 把话题讲给完全没背景的人听 |
|
||||||
| [host-sec-check](skills/host-sec-check/README.md) | 对 Linux/VPS 做入侵取向的安全检查,默认只出报告 |
|
| [host-sec-check](skills/host-sec-check/README.md) | 对 Linux/VPS 做入侵取向的安全检查,默认只出报告 |
|
||||||
| [manage-release](skills/manage-release/README.md) | 给已准备好的 commit 发版本:更新说明、tag、可选 Forge Release |
|
|
||||||
| [memory-distill](skills/memory-distill/README.md) | 任务结束后把可复用结论写入通用记忆和项目记忆 |
|
| [memory-distill](skills/memory-distill/README.md) | 任务结束后把可复用结论写入通用记忆和项目记忆 |
|
||||||
| [note-style](skills/note-style/README.md) | 把材料整理成可长期查阅的知识笔记 |
|
| [note-style](skills/note-style/README.md) | 把材料整理成可长期查阅的知识笔记 |
|
||||||
| [orc](skills/orc/README.md) | 把开发、发版、DEB / Docker 意图编排成阶段,按档位分发给对应 skill |
|
| [orc](skills/orc/README.md) | 把开发、发版、DEB / Docker 意图编排成阶段,按档位分发给对应 skill |
|
||||||
| [pouch](skills/pouch/README.md) | 创建、校验、安装和维护 builtin skill |
|
| [pouch](skills/pouch/README.md) | 创建、校验、安装和维护 builtin skill |
|
||||||
|
| [releaser](skills/releaser/README.md) | 给已准备好的 commit 发版本:更新说明、tag、可选 Forge Release |
|
||||||
|
| [manage-release](skills/manage-release/README.md) | 已弃用:`releaser` 的旧名兼容占位,不含流程 |
|
||||||
|
|
||||||
|
|
||||||
ACK 是包含规范、模板与校验脚本的完整 Skill。安装后可初始化当前项目状态:
|
ACK 是包含规范、模板与校验脚本的完整 Skill。安装后可初始化当前项目状态:
|
||||||
|
|||||||
+17
-17
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pouch 是团队自研 skill 的仓库和安装工具。Skill 是给 Agent 看的工作说明书。你对着 Cursor、Claude Code 或 Codex 说话,Agent 按说明书干活。这份仓库里还有 CLI,用来把 skill 装到各 Agent。
|
pouch 是团队自研 skill 的仓库和安装工具。Skill 是给 Agent 看的工作说明书。你对着 Cursor、Claude Code 或 Codex 说话,Agent 按说明书干活。这份仓库里还有 CLI,用来把 skill 装到各 Agent。
|
||||||
|
|
||||||
这篇只讲日常会碰到的三件事:把 pouch 装上、用 manage-release 打正式版本、用 builder 构建 DEB 或 Docker 镜像。其它 skill 装上就能喊,需要时对 Agent 说「有哪些自研 skill」。
|
这篇只讲日常会碰到的三件事:把 pouch 装上、用 releaser 打正式版本、用 builder 构建 DEB 或 Docker 镜像。其它 skill 装上就能喊,需要时对 Agent 说「有哪些自研 skill」。
|
||||||
|
|
||||||
## pouch 怎么工作
|
## pouch 怎么工作
|
||||||
|
|
||||||
@@ -13,11 +13,11 @@ Skill 的正文只存在一份,在 `~/.pouch/skills/<name>/`。装到 Cursor
|
|||||||
|
|
||||||
| 你想做的 | 对谁说 | 不要 |
|
| 你想做的 | 对谁说 | 不要 |
|
||||||
| ------------------- | -------------- | ----------------------- |
|
| ------------------- | -------------- | ----------------------- |
|
||||||
| 打正式版本、annotated tag | manage-release | 让 builder 选下一个 SemVer |
|
| 打正式版本、annotated tag | releaser | 让 builder 选下一个 SemVer |
|
||||||
| 打 DEB 或 Docker 镜像 | builder | 让 manage-release 去构建或上传 |
|
| 打 DEB 或 Docker 镜像 | builder | 让 releaser 去构建或上传 |
|
||||||
|
|
||||||
|
|
||||||
manage-release 选定正式 SemVer 并打 annotated tag。builder 只读当前 HEAD:HEAD 恰好落在 `vX.Y.Z` 上就打正式包,否则打测试包。
|
releaser 选定正式 SemVer 并打 annotated tag。builder 只读当前 HEAD:HEAD 恰好落在 `vX.Y.Z` 上就打正式包,否则打测试包。
|
||||||
|
|
||||||
## 安装 pouch
|
## 安装 pouch
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ pouch doctor
|
|||||||
发版本和构建这两个,全局装一次,所有项目都能喊:
|
发版本和构建这两个,全局装一次,所有项目都能喊:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pouch add manage-release -g -y
|
pouch add releaser -g -y
|
||||||
pouch add builder -g -y
|
pouch add builder -g -y
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ pouch add builder -g -y
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/code/my-app
|
cd ~/code/my-app
|
||||||
pouch add manage-release -y
|
pouch add releaser -y
|
||||||
pouch add builder -y
|
pouch add builder -y
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -77,21 +77,21 @@ pouch add builder -y
|
|||||||
打开已安装目标的 Agent。项目级安装要打开那个项目再说话;全局安装任意项目都可以。请求里写清 skill 名、目标和授权范围。
|
打开已安装目标的 Agent。项目级安装要打开那个项目再说话;全局安装任意项目都可以。请求里写清 skill 名、目标和授权范围。
|
||||||
|
|
||||||
```text
|
```text
|
||||||
使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。不要创建 Forge Release。
|
使用 releaser,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。不要创建 Forge Release。
|
||||||
用 builder 初始化这个项目。
|
用 builder 初始化这个项目。
|
||||||
用 builder 构建当前版本的 DEB,先不要上传。
|
用 builder 构建当前版本的 DEB,先不要上传。
|
||||||
```
|
```
|
||||||
|
|
||||||
人看各 skill 目录下的 `README.md`。`SKILL.md` 是给 Agent 的指令,不必通读。
|
人看各 skill 目录下的 `README.md`。`SKILL.md` 是给 Agent 的指令,不必通读。
|
||||||
|
|
||||||
## 用 manage-release 打新版本
|
## 用 releaser 打新版本
|
||||||
|
|
||||||
代码已经合进默认分支、测试过了,要打正式 tag 时用它。它不构建 DEB,也不推镜像。
|
代码已经合进默认分支、测试过了,要打正式 tag 时用它。它不构建 DEB,也不推镜像。
|
||||||
|
|
||||||
### 还没决定版本号
|
### 还没决定版本号
|
||||||
|
|
||||||
```text
|
```text
|
||||||
使用 manage-release 检查当前版本和这次改动,建议下一个版本号。只分析,不修改文件。
|
使用 releaser 检查当前版本和这次改动,建议下一个版本号。只分析,不修改文件。
|
||||||
```
|
```
|
||||||
|
|
||||||
Agent 会读项目版本规则、现有 tag 和实际改动,给出建议和依据。没有项目约定时,单一协调版本默认 SemVer,tag 形如 `v1.6.0`。用户输入 `v1.6.0` 时规范版本是 `1.6.0`,不要产生双前缀。
|
Agent 会读项目版本规则、现有 tag 和实际改动,给出建议和依据。没有项目约定时,单一协调版本默认 SemVer,tag 形如 `v1.6.0`。用户输入 `v1.6.0` 时规范版本是 `1.6.0`,不要产生双前缀。
|
||||||
@@ -101,7 +101,7 @@ Agent 会读项目版本规则、现有 tag 和实际改动,给出建议和依
|
|||||||
项目以 Git tag 作为版本来源,且不需要改 VERSION 文件或把 CHANGELOG 写回仓库时,走这条:
|
项目以 Git tag 作为版本来源,且不需要改 VERSION 文件或把 CHANGELOG 写回仓库时,走这条:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。根据上一个稳定 tag 到目标 commit 的实际变化生成更新说明,把说明写入 annotated tag,并验证远端 tag 的 commit 和说明。不要创建 Forge Release。
|
使用 releaser,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。根据上一个稳定 tag 到目标 commit 的实际变化生成更新说明,把说明写入 annotated tag,并验证远端 tag 的 commit 和说明。不要创建 Forge Release。
|
||||||
```
|
```
|
||||||
|
|
||||||
请求里写清目标版本、基线分支、打到哪一步。没写 push、没写创建平台 Release,Agent 就不会做。只发 Git tag 时不要求 GitHub / GitLab / Gitea CLI,但 Git remote 必须可读写。
|
请求里写清目标版本、基线分支、打到哪一步。没写 push、没写创建平台 Release,Agent 就不会做。只发 Git tag 时不要求 GitHub / GitLab / Gitea CLI,但 Git remote 必须可读写。
|
||||||
@@ -113,10 +113,10 @@ Agent 会锁定远端目标 commit,生成带 Summary、Changes、Validation、
|
|||||||
权威版本文件或仓库内 CHANGELOG 必须随发布改掉时,才创建 `release/v1.6.0` 这类分支和 PR。可以一次说完,也可以拆开授权:
|
权威版本文件或仓库内 CHANGELOG 必须随发布改掉时,才创建 `release/v1.6.0` 这类分支和 PR。可以一次说完,也可以拆开授权:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
使用 manage-release 完成 1.6.0 发布:从 main 创建分支,完成版本更新和验证,创建 PR,检查通过后合并,推送 v1.6.0 tag。不要创建 Forge Release。
|
使用 releaser 完成 1.6.0 发布:从 main 创建分支,完成版本更新和验证,创建 PR,检查通过后合并,推送 v1.6.0 tag。不要创建 Forge Release。
|
||||||
```
|
```
|
||||||
|
|
||||||
中途停了,下次说「使用 manage-release 检查 v1.6.0 当前发布状态,从尚未完成的步骤继续。不要重复创建分支、PR、tag 或 release。」
|
中途停了,下次说「使用 releaser 检查 v1.6.0 当前发布状态,从尚未完成的步骤继续。不要重复创建分支、PR、tag 或 release。」
|
||||||
|
|
||||||
要在 Gitea / GitHub 上建平台 Release 时,在请求里写明。没写就不会建。Forge Release 复用 tag 里同一份说明。
|
要在 Gitea / GitHub 上建平台 Release 时,在请求里写明。没写就不会建。Forge Release 复用 tag 里同一份说明。
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ Agent 会锁定远端目标 commit,生成带 Summary、Changes、Validation、
|
|||||||
|
|
||||||
builder 按统一契约打 DEB 和 Docker 镜像。项目根会多两个文件:`makefile.builder`(构建入口)和 `.env.builder`(发布凭据,不进 git)。它不改你已有的 `Makefile` 或 `.env`。
|
builder 按统一契约打 DEB 和 Docker 镜像。项目根会多两个文件:`makefile.builder`(构建入口)和 `.env.builder`(发布凭据,不进 git)。它不改你已有的 `Makefile` 或 `.env`。
|
||||||
|
|
||||||
正式版本号仍由 manage-release 打 tag。builder 只读当前 HEAD,不调用 manage-release。
|
正式版本号仍由 releaser 打 tag。builder 只读当前 HEAD,不调用 releaser。
|
||||||
|
|
||||||
### 接入一个项目
|
### 接入一个项目
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ Docker 只有点名镜像时 Agent 才走。脏工作树默认拒绝发布。可
|
|||||||
|
|
||||||
代码合进 `main` 且检查通过之后,按这个顺序:
|
代码合进 `main` 且检查通过之后,按这个顺序:
|
||||||
|
|
||||||
1. 对 Agent:`使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。不要创建 Forge Release。`
|
1. 对 Agent:`使用 releaser,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。不要创建 Forge Release。`
|
||||||
2. 确认远端 `v1.6.0` 指向那次 commit。
|
2. 确认远端 `v1.6.0` 指向那次 commit。
|
||||||
3. checkout 到该 tag,或确保当前 HEAD 就是它。
|
3. checkout 到该 tag,或确保当前 HEAD 就是它。
|
||||||
4. 对 Agent:`用 builder 构建当前版本的 DEB,先不要上传。`
|
4. 对 Agent:`用 builder 构建当前版本的 DEB,先不要上传。`
|
||||||
@@ -220,15 +220,15 @@ Docker 只有点名镜像时 Agent 才走。脏工作树默认拒绝发布。可
|
|||||||
- 在 `~/.cursor/skills/` 里直接改文件:改的是软链目标,应该改 `~/.pouch/skills/`。Claude Code 有时会把软链替换成普通文件,用 `pouch doctor --fix` 重建。
|
- 在 `~/.cursor/skills/` 里直接改文件:改的是软链目标,应该改 `~/.pouch/skills/`。Claude Code 有时会把软链替换成普通文件,用 `pouch doctor --fix` 重建。
|
||||||
- `pouch init builder` 这条路径不存在:对 Agent 说「用 builder 初始化」。
|
- `pouch init builder` 这条路径不存在:对 Agent 说「用 builder 初始化」。
|
||||||
- 请求里没写清授权:Agent 会分析或只做到本地,不会擅自 push tag 或上传包。
|
- 请求里没写清授权:Agent 会分析或只做到本地,不会擅自 push tag 或上传包。
|
||||||
- 工作区有未提交修改:builder 默认拒绝发布;manage-release 不会 stash 或覆盖你的文件。
|
- 工作区有未提交修改:builder 默认拒绝发布;releaser 不会 stash 或覆盖你的文件。
|
||||||
- 同名 tag 已在远端指向别的 commit:manage-release 会停,不会 force push。
|
- 同名 tag 已在远端指向别的 commit:releaser 会停,不会 force push。
|
||||||
- HEAD 不在稳定 tag 上却想打正式包:先打 tag,再构建。
|
- HEAD 不在稳定 tag 上却想打正式包:先打 tag,再构建。
|
||||||
|
|
||||||
## 还想看什么
|
## 还想看什么
|
||||||
|
|
||||||
- 仓库总览:[README.md](../README.md)
|
- 仓库总览:[README.md](../README.md)
|
||||||
- CLI 命令:[pouch/README.md](../pouch/README.md)
|
- CLI 命令:[pouch/README.md](../pouch/README.md)
|
||||||
- manage-release:[skills/manage-release/README.md](../skills/manage-release/README.md)
|
- releaser:[skills/releaser/README.md](../skills/releaser/README.md)
|
||||||
- builder:[skills/builder/README.md](../skills/builder/README.md)
|
- builder:[skills/builder/README.md](../skills/builder/README.md)
|
||||||
- 设计原则和编写规范:[AGENTS.md](../AGENTS.md)
|
- 设计原则和编写规范:[AGENTS.md](../AGENTS.md)
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ intents:
|
|||||||
- `verify`:运行指定 entrypoint,失败即停止。
|
- `verify`:运行指定 entrypoint,失败即停止。
|
||||||
- `pull-request`:在精确 source revision 上提交、推送任务分支并创建或复用 Draft
|
- `pull-request`:在精确 source revision 上提交、推送任务分支并创建或复用 Draft
|
||||||
PR/MR。普通任务使用项目已确认的 Forge 流程;只有本次是版本发布生命周期且用户
|
PR/MR。普通任务使用项目已确认的 Forge 流程;只有本次是版本发布生命周期且用户
|
||||||
明确要求时才调用独立的 `manage-release`。没有对应能力或认证时标记 blocked,不用
|
明确要求时才调用独立的 `releaser`。没有对应能力或认证时标记 blocked,不用
|
||||||
带 token 的临时 curl 兜底。remote 与 base branch 必须来自该步骤,不能临时猜测。
|
带 token 的临时 curl 兜底。remote 与 base branch 必须来自该步骤,不能临时猜测。
|
||||||
- `build`:调用 artifact 的 build entrypoint。DEB 必须记录包名、版本、架构和
|
- `build`:调用 artifact 的 build entrypoint。DEB 必须记录包名、版本、架构和
|
||||||
SHA-256;OCI image 必须记录完整引用、platform 和 digest。产物必须绑定当前 source
|
SHA-256;OCI image 必须记录完整引用、platform 和 digest。产物必须绑定当前 source
|
||||||
@@ -153,9 +153,9 @@ ID 指向不同 commit、digest 或目标时停止,不覆盖或另建伪装成
|
|||||||
## 7. 与低层 Skill 的边界
|
## 7. 与低层 Skill 的边界
|
||||||
|
|
||||||
ACK 只负责读取项目交付契约、编排顺序、守住审批点并汇总证据,不复制低层 skill 的
|
ACK 只负责读取项目交付契约、编排顺序、守住审批点并汇总证据,不复制低层 skill 的
|
||||||
上传、镜像、Git 发布或远程 Compose 实现。`builder`、`manage-release` 和
|
上传、镜像、Git 发布或远程 Compose 实现。`builder`、`releaser` 和
|
||||||
`deployer` 仍是可独立使用、独立安装的能力。运行测试环境时 ACK 必须加载
|
`deployer` 仍是可独立使用、独立安装的能力。运行测试环境时 ACK 必须加载
|
||||||
deployer skill,不能把 compose/rsync/远程 docker 命令写进 ACK。发版步骤缺失
|
deployer skill,不能把 compose/rsync/远程 docker 命令写进 ACK。发版步骤缺失
|
||||||
builder 或 manage-release 时,ACK 使用契约中已审查的项目 entrypoint,二者都不可用
|
builder 或 releaser 时,ACK 使用契约中已审查的项目 entrypoint,二者都不可用
|
||||||
时把对应步骤标为 `blocked`。低层 skill 自身要求显式调用时,ACK 不能绕过它的
|
时把对应步骤标为 `blocked`。低层 skill 自身要求显式调用时,ACK 不能绕过它的
|
||||||
触发与授权边界;ACK 内部调用 deployer 布测试环境是该 skill 的合法调用路径。
|
触发与授权边界;ACK 内部调用 deployer 布测试环境是该 skill 的合法调用路径。
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ pouch add builder -g # 全局
|
|||||||
- Python 3 和 `make`。
|
- Python 3 和 `make`。
|
||||||
- DEB 轨道需要 `dpkg-deb`;Docker 轨道需要 Docker 和 buildx。
|
- DEB 轨道需要 `dpkg-deb`;Docker 轨道需要 Docker 和 buildx。
|
||||||
- 发布时在项目根 `.env.builder` 填写仓库地址和 token(不要写进 `.env`,也不要进 git)。
|
- 发布时在项目根 `.env.builder` 填写仓库地址和 token(不要写进 `.env`,也不要进 git)。
|
||||||
- 正式版本号由 [manage-release](../manage-release/README.md) 打 annotated tag;builder 只读当前 HEAD。
|
- 正式版本号由 [releaser](../releaser/README.md) 打 annotated tag;builder 只读当前 HEAD。
|
||||||
- 脏工作树默认拒绝发布。
|
- 脏工作树默认拒绝发布。
|
||||||
|
|
||||||
## 项目接入契约
|
## 项目接入契约
|
||||||
@@ -106,13 +106,13 @@ dist/<name>_<version>_arm64.deb
|
|||||||
|
|
||||||
## 版本号
|
## 版本号
|
||||||
|
|
||||||
产物版本从 **当前 HEAD 的 Git 祖先** 推导,不调用 manage-release。
|
产物版本从 **当前 HEAD 的 Git 祖先** 推导,不调用 releaser。
|
||||||
正式 tag 仍由 manage-release 创建;builder 只读取。完整规则见
|
正式 tag 仍由 releaser 创建;builder 只读取。完整规则见
|
||||||
[contract.md「版本号」](references/contract.md#版本号)。
|
[contract.md「版本号」](references/contract.md#版本号)。
|
||||||
|
|
||||||
| 谁 | 做什么 |
|
| 谁 | 做什么 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| manage-release | 选定下一个正式 SemVer,打 annotated tag `vX.Y.Z` |
|
| releaser | 选定下一个正式 SemVer,打 annotated tag `vX.Y.Z` |
|
||||||
| builder | 读 HEAD:落在稳定 tag 上则打正式产物,否则打测试产物 |
|
| builder | 读 HEAD:落在稳定 tag 上则打正式产物,否则打测试产物 |
|
||||||
| `make -f makefile.builder version` | 输出一行规范版本(无 `v` 前缀),DEB / Docker 都从它渲染 |
|
| `make -f makefile.builder version` | 输出一行规范版本(无 `v` 前缀),DEB / Docker 都从它渲染 |
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ COPY_AS=latest.apk
|
|||||||
|
|
||||||
1. 跑 `check.py <project-dir>`;需要工具链与发布键时加 `--ready`;要实构 deb 时加 `--build`。契约 FAIL 或轨道工具缺失:停下,转入「初始化」,不要绕过校验,不要改用户 Makefile。只缺发布键:允许构建,禁止上传。未接契约的存量项目按 contract.md §6 发现已有入口,上传仍用 builder 脚本;成功交付一次后引导迁到 `makefile.builder`。
|
1. 跑 `check.py <project-dir>`;需要工具链与发布键时加 `--ready`;要实构 deb 时加 `--build`。契约 FAIL 或轨道工具缺失:停下,转入「初始化」,不要绕过校验,不要改用户 Makefile。只缺发布键:允许构建,禁止上传。未接契约的存量项目按 contract.md §6 发现已有入口,上传仍用 builder 脚本;成功交付一次后引导迁到 `makefile.builder`。
|
||||||
2. 仅当用户明确要求发布、上传或提交时才上传。不猜测生产端点;不把 token 写入输出、文件、提交或回复;不用 `set -x` 跑含凭据的命令。可能覆盖同版本时先问。脏工作树默认拒绝发布;用户明确接受时设 `ALLOW_UNCOMMITTED=1` 并注明未提交修改。
|
2. 仅当用户明确要求发布、上传或提交时才上传。不猜测生产端点;不把 token 写入输出、文件、提交或回复;不用 `set -x` 跑含凭据的命令。可能覆盖同版本时先问。脏工作树默认拒绝发布;用户明确接受时设 `ALLOW_UNCOMMITTED=1` 并注明未提交修改。
|
||||||
3. 构建:用户指定了架构才传 `ARCH=`;否则不要传,让 makefile 按 `ARCHES` 展开(`make -s -f makefile.builder arches`)。`make -f makefile.builder build` 始终单架构;DEB 用 `make -f makefile.builder deb`。版本按契约从 Git 祖先稳定 tag 推导,不要调用 manage-release,不要用全仓库最新 tag。仅获构建授权时不要走会自动上传的目标。脚本含 `rm -rf` 时先确认为受限构建目录。
|
3. 构建:用户指定了架构才传 `ARCH=`;否则不要传,让 makefile 按 `ARCHES` 展开(`make -s -f makefile.builder arches`)。`make -f makefile.builder build` 始终单架构;DEB 用 `make -f makefile.builder deb`。版本按契约从 Git 祖先稳定 tag 推导,不要调用 releaser,不要用全仓库最新 tag。仅获构建授权时不要走会自动上传的目标。脚本含 `rm -rf` 时先确认为受限构建目录。
|
||||||
4. DEB 上传前:对每个包 `verify_deb.sh <exact-package-path.deb> <version> <arch>`。多个包时不凭文件时间猜测。镜像轨道由 `publish_docker.sh` 自带远端 inspect。
|
4. DEB 上传前:对每个包 `verify_deb.sh <exact-package-path.deb> <version> <arch>`。多个包时不凭文件时间猜测。镜像轨道由 `publish_docker.sh` 自带远端 inspect。
|
||||||
5. 发布优先 `make -f makefile.builder push[-deb|-docker|-copy]`,或直接调 `upload_deb.sh` / `publish_docker.sh` / `copy_artifact.sh`。未指定 `ARCH=` 时 `push-deb` 上传清单里每一个 `.deb`。拷贝轨道要 `COPY_DEST`(本地目录或 `container:/dir`);`COPY_AS` 给第一份文件额外名字。脚本缺环境变量时加载 `.env.builder`(shell 显式值优先),不读 `.env`。不把 token 当命令行参数;不把脚本复制进项目。多平台镜像只能走 `publish_docker.sh`,不能拆进 make;不要把项目架构清单写进 `.env.builder`。`build` 里禁止 `docker cp`。
|
5. 发布优先 `make -f makefile.builder push[-deb|-docker|-copy]`,或直接调 `upload_deb.sh` / `publish_docker.sh` / `copy_artifact.sh`。未指定 `ARCH=` 时 `push-deb` 上传清单里每一个 `.deb`。拷贝轨道要 `COPY_DEST`(本地目录或 `container:/dir`);`COPY_AS` 给第一份文件额外名字。脚本缺环境变量时加载 `.env.builder`(shell 显式值优先),不读 `.env`。不把 token 当命令行参数;不把脚本复制进项目。多平台镜像只能走 `publish_docker.sh`,不能拆进 make;不要把项目架构清单写进 `.env.builder`。`build` 里禁止 `docker cp`。
|
||||||
6. 发布成功不能只看「curl/push 已执行」。要有退出码、HTTP 成功或远端 digest;索引异步时报告「上传已接受,索引尚待更新」。最终回复给出包名/镜像引用、版本、架构、SHA-256 或 digest、源 commit、工作区状态和未完成项。
|
6. 发布成功不能只看「curl/push 已执行」。要有退出码、HTTP 成功或远端 digest;索引异步时报告「上传已接受,索引尚待更新」。最终回复给出包名/镜像引用、版本、架构、SHA-256 或 digest、源 commit、工作区状态和未完成项。
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ make -f makefile.builder <target>
|
|||||||
`make -f makefile.builder version` 输出一行规范版本(无 `v` 前缀)。DEB 的
|
`make -f makefile.builder version` 输出一行规范版本(无 `v` 前缀)。DEB 的
|
||||||
`Version` 与文件名直接用它;Docker tag 由它渲染。推导入口是 `scripts/version.sh`
|
`Version` 与文件名直接用它;Docker tag 由它渲染。推导入口是 `scripts/version.sh`
|
||||||
(`makefile.builder` 通过 `scripts/version.mk` 引用);Builder 只读取 Git 状态,不调用
|
(`makefile.builder` 通过 `scripts/version.mk` 引用);Builder 只读取 Git 状态,不调用
|
||||||
manage-release 选定下一正式 SemVer。测试号把祖先基线的 patch 机械 +1 作为排序键
|
releaser 选定下一正式 SemVer。测试号把祖先基线的 patch 机械 +1 作为排序键
|
||||||
(`v1.4.2` 之后 → `1.4.3~…`),不是在宣布下一正式号就是 1.4.3。正式 tag 由
|
(`v1.4.2` 之后 → `1.4.3~…`),不是在宣布下一正式号就是 1.4.3。正式 tag 由
|
||||||
manage-release 事先打好。`version.sh` 不执行 `git fetch`。
|
releaser 事先打好。`version.sh` 不执行 `git fetch`。
|
||||||
|
|
||||||
推导前 `git fetch --tags`(本地 linked worktree 共享 tags,不必再 fetch 才
|
推导前 `git fetch --tags`(本地 linked worktree 共享 tags,不必再 fetch 才
|
||||||
能看见其它 worktree 新打的 tag)。基线是 **HEAD 祖先上最近的稳定 tag**,
|
能看见其它 worktree 新打的 tag)。基线是 **HEAD 祖先上最近的稳定 tag**,
|
||||||
|
|||||||
+13
-124
@@ -1,135 +1,24 @@
|
|||||||
# manage-release
|
# manage-release(已弃用)
|
||||||
|
|
||||||
`manage-release` 帮助 Agent 发布已经准备好的 Git commit,也能在发布前确有必要时管理
|
`manage-release` 已改名为 [releaser](../releaser/README.md)。本目录只是兼容占位,
|
||||||
版本文件、worktree、分支、PR/MR 和合并。普通发布优先走“更新说明 + annotated tag”的
|
让旧项目里的 `.pouch.yaml`、已经装好的旧软链和旧说法不至于失效;真正的说明和流程都在
|
||||||
短路径;只有发布要求修改仓库内容时,才进入准备版本的分支流程。
|
`releaser/`。
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pouch add manage-release # 当前项目
|
|
||||||
pouch add manage-release -g # 全局
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用前准备
|
|
||||||
|
|
||||||
- 项目已经是 Git 仓库,并配置了可访问的远端。
|
|
||||||
- 项目已有版本来源或 tag 发布约定;没有时可以让 Agent 先给出版本建议。
|
|
||||||
- 创建或合并 PR/MR、创建 Forge Release 时,准备好 GitHub、GitLab、Gitea 或 Forgejo
|
|
||||||
对应的已认证 CLI。只发布 Git tag 时不要求 Forge CLI,但 Git remote 必须可读写。
|
|
||||||
- 请求里写清目标版本、基线分支,以及允许执行到哪一步。没有明确授权的远端写操作
|
|
||||||
不会执行。
|
|
||||||
|
|
||||||
## 使用示例
|
## 使用示例
|
||||||
|
|
||||||
```text
|
```text
|
||||||
使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。不要创建 Forge Release。
|
使用 manage-release,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。
|
||||||
```
|
```
|
||||||
|
|
||||||
## 常见用法
|
Agent 命中后会立刻转到 `releaser`,按同一套规则执行。新请求建议直接用新名。
|
||||||
|
|
||||||
### 确定下一个版本号
|
## 迁移
|
||||||
|
|
||||||
```text
|
```bash
|
||||||
使用 manage-release 检查当前版本和这次改动,建议下一个版本号。只分析,不修改文件。
|
pouch add releaser # 新名,当前项目
|
||||||
|
pouch add releaser -g # 新名,全局
|
||||||
```
|
```
|
||||||
|
|
||||||
适合还没决定该发 patch、minor 还是 major 时使用。Agent 会读取项目版本规则、现有 tag
|
- 旧软链保持有效,不需要先删除。
|
||||||
和实际改动,给出建议及依据。
|
- 各项目 `.pouch.yaml` 里的 `manage-release` 可以分批改成 `releaser`。
|
||||||
|
- 确认没有项目再按旧名启用后,删除本目录即可;它是纯占位,删除不丢内容。
|
||||||
### 开始开发新版本
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 manage-release,从 main 为 1.6.0 创建独立 worktree 和分支。先不要 push,也不要创建 PR。
|
|
||||||
```
|
|
||||||
|
|
||||||
Agent 会检查已有 worktree、分支和 tag,确认没有冲突后准备开发目录。这个请求只授权
|
|
||||||
本地操作。
|
|
||||||
|
|
||||||
### 把开发分支提交为 PR
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 manage-release 检查当前分支,更新版本号和 CHANGELOG,运行项目测试,然后 push 并创建指向 main 的 PR。不要合并。
|
|
||||||
```
|
|
||||||
|
|
||||||
适合开发已经完成,只需要整理版本信息并送审。Agent 会停在 PR 创建成功的位置,返回
|
|
||||||
PR 地址、测试结果和待处理项。
|
|
||||||
|
|
||||||
### 合并通过检查的 PR
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 manage-release 检查当前 PR。如果 CI、review 和冲突检查都通过,就按项目规则合并;不要打 tag。
|
|
||||||
```
|
|
||||||
|
|
||||||
Agent 只会在仓库要求全部满足后合并,不会使用管理员权限绕过保护规则。合并完成后会
|
|
||||||
返回准确的 merged commit。
|
|
||||||
|
|
||||||
### 为已合并版本发布 tag
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 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,不会创建 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 阶段恢复。
|
|
||||||
|
|
||||||
### 完成端到端发布
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 manage-release 完成 1.6.0 发布:从 main 创建 worktree 和分支,完成版本更新和验证,创建 PR,检查通过后合并,推送 v1.6.0 tag,并创建 Forge Release。
|
|
||||||
```
|
|
||||||
|
|
||||||
只有版本文件或仓库内 CHANGELOG 必须随发布修改时才使用这条长路径。tag 仍必须附带更新
|
|
||||||
说明,Forge Release 复用同一份说明。遇到 review 未通过、CI 失败、版本冲突或已有同名
|
|
||||||
tag 时,Agent 会停止并说明卡在哪一步,不会绕过检查继续发布。
|
|
||||||
|
|
||||||
### 发布紧急修复版本
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 manage-release 从 main 准备 1.6.1 hotfix。创建独立 worktree,完成修复后开 PR;检查通过就合并并发布 v1.6.1。
|
|
||||||
```
|
|
||||||
|
|
||||||
适合线上问题修复。Skill 仍走正常 PR 和保护分支流程,不会因为是 hotfix 就直接推送
|
|
||||||
main 或覆盖已有 tag。
|
|
||||||
|
|
||||||
### 从中断位置继续
|
|
||||||
|
|
||||||
```text
|
|
||||||
使用 manage-release 检查 v1.6.0 当前发布状态,从尚未完成的步骤继续。不要重复创建分支、PR、tag 或 release。
|
|
||||||
```
|
|
||||||
|
|
||||||
适合合并后打 tag 失败、tag 已推送但 release 未创建,或者 Agent 会话中断的情况。
|
|
||||||
Skill 会从 Git 和代码托管平台重新判断状态,再继续缺失的步骤。
|
|
||||||
|
|
||||||
## Agent 会做什么
|
|
||||||
|
|
||||||
Agent 会先发现项目自己的版本和发布规则、锁定远端目标 commit,再判断发布是否要求修改
|
|
||||||
仓库内容。不需要修改时直接生成更新说明并发布 annotated tag;需要修改时才准备分支,
|
|
||||||
并只在隔离用户工作确有必要时创建 worktree。它只执行请求中明确授权的阶段,并在合并、
|
|
||||||
tag 或 release 条件不满足时停止。
|
|
||||||
|
|
||||||
## 如何判断完成
|
|
||||||
|
|
||||||
- 只分析版本时,结果包含建议版本及依据。
|
|
||||||
- 创建开发环境时,结果包含 worktree 路径、分支和基线 commit。
|
|
||||||
- 创建或合并 PR/MR 时,结果包含 URL、检查状态和 merged commit。
|
|
||||||
- 发布 tag 时,远端 tag 解引用后的 commit 与目标 commit 一致,而且 tag object 包含经过
|
|
||||||
核对的更新说明。
|
|
||||||
- 创建 Forge Release 时,结果包含可访问的 release URL,正文与 tag 更新说明一致。
|
|
||||||
- 中途停止时,结果说明停在哪一步、为什么停止,以及下次如何继续。
|
|
||||||
|
|
||||||
## 不适用的场景
|
|
||||||
|
|
||||||
普通功能开发、普通 worktree 或 PR/MR 操作、代码审查、构建 Docker 镜像或上传 DEB 包
|
|
||||||
不需要触发 `manage-release`。只有任务明确涉及版本发布、发布分支、版本号、发布 PR/MR
|
|
||||||
或 release tag 时,才交给这个 Skill。
|
|
||||||
|
|||||||
+12
-232
@@ -1,239 +1,19 @@
|
|||||||
---
|
---
|
||||||
name: manage-release
|
name: manage-release
|
||||||
description: >-
|
description: >-
|
||||||
管理 Git 项目从已准备 commit 到版本发布的生命周期:发现并遵循项目版本与发布策略,
|
【已弃用,兼容占位】manage-release 已改名为 releaser。命中本 skill 时不要在此执行任何
|
||||||
优先为远端已验证 commit 生成更新说明并创建 annotated release tag,按需创建 Forge
|
流程,直接读取 ../releaser/SKILL.md 并按其执行。发布版本、打 release tag、创建平台
|
||||||
Release;只有必须修改版本文件或仓库内发布说明时,才创建或复用版本分支、worktree
|
Release、准备版本变更、hotfix、继续未完成发布等请求都属于 releaser。
|
||||||
和 PR/MR。也支持恢复中断流程与安全清理。用户要求发布版本、打 release tag、创建
|
|
||||||
平台 Release、准备版本变更、处理 hotfix 或继续未完成发布时使用。只做普通编码、普通
|
|
||||||
worktree 或 PR/MR 操作、代码审查、构建或上传 DEB/Docker 等产物、管理仓库权限时不使用。
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Manage Release
|
# manage-release(已弃用)
|
||||||
|
|
||||||
根据项目现有规则管理源码版本生命周期。把项目策略当作规则来源,把 Git 与代码托管
|
本 skill 已改名为 [releaser](../releaser/SKILL.md)。这里只是兼容占位,**没有流程内容**。
|
||||||
平台的实时状态当作运行状态;不要创建另一份会与分支、PR/MR 或 tag 分叉的状态文件。
|
|
||||||
|
|
||||||
## 按需读取参考资料
|
- 用户提到 `manage-release`、`/manage-release` 或 `$manage-release` 时:读取
|
||||||
|
[../releaser/SKILL.md](../releaser/SKILL.md),按其内容与授权边界执行,不要在本目录
|
||||||
- 开始任何流程时读取 [project-policy.md](references/project-policy.md),确定策略来源和默认值。
|
里寻找步骤、references 或 templates。
|
||||||
- 需要选择、更新或核对版本号,或生成 tag 更新说明时读取
|
- 本目录不保留 `references/` 和 `templates/`,正文只有一份,在 `releaser/`。
|
||||||
[versioning.md](references/versioning.md)。
|
- 旧项目 `.pouch.yaml` 里仍写 `manage-release` 也能正常安装,软链不会悬空;方便时改成
|
||||||
- 需要 push、创建或合并 PR/MR、创建 Forge Release 时读取
|
`releaser`。
|
||||||
[forge-adapters.md](references/forge-adapters.md)。
|
- 确认没有项目再按旧名启用后,可以直接删除本目录。
|
||||||
- 遇到重复资源、并发冲突、部分成功或清理请求时读取
|
|
||||||
[recovery.md](references/recovery.md)。
|
|
||||||
- 仅当用户要求为项目固化发布规则时,复制并修改
|
|
||||||
[release-policy.template.yaml](templates/release-policy.template.yaml)。不要在普通发布中自动添加配置。
|
|
||||||
|
|
||||||
## 授权边界
|
|
||||||
|
|
||||||
按用户明确要求执行到对应阶段:
|
|
||||||
|
|
||||||
- 分析版本或检查状态:只执行读取和计算,不修改文件或远端。
|
|
||||||
- 开始或准备版本:允许创建本地分支、worktree,并修改版本文件。
|
|
||||||
- push 或创建 PR/MR:仅在用户明确要求 push、提交 PR/MR 或执行完整发布时进行。
|
|
||||||
- 合并和推送 tag:仅在用户明确要求相应动作或完整发布时进行。
|
|
||||||
- 创建 Forge Release:仅在用户本次请求明确提到 Forge Release 或平台 Release 时进行。
|
|
||||||
- 清理 worktree 或分支:仅在用户明确要求清理时进行。
|
|
||||||
|
|
||||||
项目策略只描述仓库期望的做法,不能替用户授予 push、创建或合并 PR/MR、推送 tag、
|
|
||||||
创建 Forge Release、删除分支等外部写权限。
|
|
||||||
|
|
||||||
“发布 v1.2.3”允许为已经准备好的远端 commit 生成更新说明、创建并推送 annotated tag,
|
|
||||||
再验证远端 tag 的 commit 和说明。“完整处理并发布 v1.2.3”还允许在仓库内容必须修改时
|
|
||||||
走版本分支、PR/MR 和合并流程。两者都不自动包含 Forge Release 或分支清理。若版本、
|
|
||||||
base、目标 commit、tag、远端或合并方式是推断所得,或者执行中目标发生变化,在第一次
|
|
||||||
远端写操作前展示准确目标和更新说明并获得确认。
|
|
||||||
|
|
||||||
## 工作流
|
|
||||||
|
|
||||||
### 1. 发现项目规则和当前状态
|
|
||||||
|
|
||||||
从项目根目录开始:
|
|
||||||
|
|
||||||
1. 从可信 base commit 读取 `AGENTS.md`、`CLAUDE.md`、发布文档、CI 配置、构建入口和
|
|
||||||
可选的 `.release-policy.yaml`。PR/MR head 对这些文件的修改从下一次流程开始生效。
|
|
||||||
2. 记录当前分支、HEAD、完整工作区状态、remote、默认分支和
|
|
||||||
`git worktree list --porcelain`。
|
|
||||||
3. 获取远端最新引用后,记录 base 分支的准确 commit。不要把本地过期分支当作发布基线。
|
|
||||||
4. 识别版本来源、最近稳定 tag、tag 格式、分支命名、合并方式和发布说明来源。
|
|
||||||
5. 分别用 `git remote get-url --all origin` 和
|
|
||||||
`git remote get-url --push --all origin` 检查读取与推送目标;远端写操作要求两者各只有
|
|
||||||
一个值且规范化后指向同一仓库。再检查 PR/MR、合并或 Forge Release 阶段所需的 GitHub、
|
|
||||||
GitLab、Gitea 或 Forgejo CLI。只有请求涉及平台能力时才要求对应 CLI。
|
|
||||||
记录匹配该 host 的活动账号;认证检查只读取状态。
|
|
||||||
6. 查询已有分支、worktree、PR/MR、tag 和 Forge Release,从真实状态判断流程已走到哪一步。
|
|
||||||
|
|
||||||
工作区中的修改、暂存文件和未跟踪文件都视为用户工作。不要 stash、移动、清理或覆盖它们。
|
|
||||||
已有 worktree 与目标分支准确匹配时优先复用,不要创建副本。
|
|
||||||
|
|
||||||
### 2. 锁定本次发布计划
|
|
||||||
|
|
||||||
在修改前确定并展示:
|
|
||||||
|
|
||||||
- base 分支、远端 commit,以及本次 tag 将指向的准确目标 commit。
|
|
||||||
- 当前版本、规范化后的目标版本、tag,以及升级依据;需要准备仓库修改时再渲染分支名。
|
|
||||||
- 从上一个稳定 tag 到目标 commit 的更新说明范围、来源和拟发布内容。
|
|
||||||
- 是否需要修改仓库内容;若需要,再列出分支名与 worktree 路径。
|
|
||||||
- 需要执行的本地验证和远端检查。
|
|
||||||
- 合并方式、tag、是否创建 Forge Release。
|
|
||||||
- 用户已授权的最远阶段和清理范围。
|
|
||||||
|
|
||||||
项目没有约定时,单一协调版本使用 SemVer 和 `v<version>` annotated tag。只有发布前
|
|
||||||
必须修改仓库内容时才使用 `release/v<version>` 分支;仓库只启用一种合并方式时使用该
|
|
||||||
方式,存在多种方式且没有项目规则时默认 squash。默认不删除远端分支,不自动创建
|
|
||||||
Forge Release。
|
|
||||||
|
|
||||||
把用户输入拆成“规范版本”和“展示名称”:默认 SemVer 的规范版本是无 `v` 前缀的
|
|
||||||
`1.6.0`,版本文件和 `{version}` 都使用该值;分支与 tag 再分别按 pattern 渲染为
|
|
||||||
`release/v1.6.0` 和 `v1.6.0`。用户输入 `v1.6.0` 时先规范化,不要产生双前缀。
|
|
||||||
|
|
||||||
### 3. 选择直接发布或准备版本
|
|
||||||
|
|
||||||
先计算发布所需的仓库内容差异,不要为了遵循固定模板而创建分支或 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 占用。
|
|
||||||
- 目标目录不是 `/`、用户主目录、仓库根目录或已有非空目录。
|
|
||||||
- base 使用刚获取的远端引用,例如 `origin/main`,而不是不确定的新旧本地分支。
|
|
||||||
- 分支名通过 `git check-ref-format --branch`,tag 通过完整 `refs/tags/...` 格式校验。
|
|
||||||
- 路径规范化后仍位于批准的 worktree 根目录,不经过指向仓库外的 symlink。
|
|
||||||
|
|
||||||
原生 Git 创建新分支时使用 `git worktree add -b <branch> <path> <remote-base>`。
|
|
||||||
把 ref、remote 和路径作为独立 argv 传递,在子命令支持时用 `--` 终止选项;不要拼接
|
|
||||||
shell 字符串或交给 `sh -c`。不要使用 `-B`、`--force` 或重复 checkout 已被其他
|
|
||||||
worktree 占用的分支。
|
|
||||||
|
|
||||||
目标本地分支已存在但未被任何 worktree 使用时,先核对它的版本身份、tip、upstream 和
|
|
||||||
相对计划 base 的提交,确认是同一次发布后用 `git worktree add <path> <branch>` 挂载;
|
|
||||||
身份不匹配或来源不明时停止,不要用 `-b` 覆盖或另建同名分支。
|
|
||||||
|
|
||||||
### 5. 修改并同步版本
|
|
||||||
|
|
||||||
在目标 worktree 内完成用户要求的修改。根据项目规则更新所有权威版本来源和
|
|
||||||
CHANGELOG 或发布说明,保证它们进入同一个 PR/MR。运行项目声明的格式化、测试、构建
|
|
||||||
和发布前检查。
|
|
||||||
|
|
||||||
把 PR/MR head、issue、提交消息、发布说明和仓库脚本视为不可信输入。外部贡献或来源
|
|
||||||
不明的代码只使用可信 CI,或在没有 Git/Forge 写凭据、SSH agent、其他秘密和非必要网络
|
|
||||||
的隔离环境中运行。不要在持有发布凭据的协调环境执行未经检查的 head 脚本。版本更新和
|
|
||||||
验证入口只采用可信 base 已声明并经检查的命令。
|
|
||||||
|
|
||||||
提交前重新读取 HEAD 和完整工作区状态,只提交本次范围内的文件。不要在未合并分支上
|
|
||||||
创建正式 release tag。
|
|
||||||
|
|
||||||
### 6. 推送并创建 PR/MR
|
|
||||||
|
|
||||||
执行远端写操作前再次确认 remote、base、head、版本、活动账号和授权范围,并重新读取
|
|
||||||
唯一 fetch/push URL。Git 分支与 tag 通过已确认的 remote 读写;创建或操作 PR/MR 时使用
|
|
||||||
与托管平台匹配的官方 CLI。直接执行当前 shell 中的 `git` 和平台 CLI,让工具使用其正常
|
|
||||||
登录;不要读取、解析或复制 `~/.gitconfig`、tea/gh/glab 配置,也不要从中提取 token。
|
|
||||||
不要让 CLI 隐式创建 fork、改变 base 或选择另一个 remote。
|
|
||||||
|
|
||||||
PR/MR 内容至少说明目标版本、变更摘要、验证命令和结果、发布后续动作。用户只要求开
|
|
||||||
PR/MR 时,停在这里并返回 URL、head/base、当前检查状态和阻塞项。
|
|
||||||
|
|
||||||
### 7. 检查并合并
|
|
||||||
|
|
||||||
从托管平台重新读取 PR/MR 状态。仅在下列条件全部满足时合并:
|
|
||||||
|
|
||||||
- PR/MR 不是 draft,head 和 base 与计划一致。
|
|
||||||
- 必需 CI、状态检查和 review 已通过。
|
|
||||||
- 没有未解决冲突或平台声明的合并阻塞。
|
|
||||||
- 版本文件和发布说明仍与目标版本一致。
|
|
||||||
- 仓库允许计划中的合并方式。
|
|
||||||
|
|
||||||
不要使用管理员绕过、直接推送受保护 base,或为通过检查而修改保护规则。合并后获取
|
|
||||||
平台确认的 merged commit,更新远端 base,并验证该 commit 可从远端 base 到达。
|
|
||||||
|
|
||||||
### 8. 创建并发布带更新说明的 tag
|
|
||||||
|
|
||||||
准备版本路径使用平台确认且可从远端 base 到达的 merged commit;直接发布路径使用计划
|
|
||||||
中锁定且重新验证过的远端目标 commit。两者统一记为 release commit。核对目标版本后,
|
|
||||||
再查询一次远端同名 tag。
|
|
||||||
|
|
||||||
创建 tag 前,按 [versioning.md](references/versioning.md) 生成并检查 tag message:根据
|
|
||||||
上一个稳定 tag 到 release commit 的实际差异填写 `Summary`、`Changes`、`Validation`
|
|
||||||
和 `Base commit`;首次发布则使用项目声明的发布基线,没有声明时核对完整可达历史并明确
|
|
||||||
标记首次发布。空说明、只重复版本号或提交标题、缺少规定字段、模板占位文字、伪造变更
|
|
||||||
或无法由实际变化支持的内容都不能发布。
|
|
||||||
|
|
||||||
tag 不存在时,把检查通过的完整 message 写入文件,再用
|
|
||||||
`git tag -a <tag> <release-commit> -F <release-notes-file>` 创建 annotated tag;项目
|
|
||||||
要求签名时,必须先确认签名工具和密钥可用,创建 signed annotated tag,并在本地验证签名
|
|
||||||
成功后才允许 push。显式指定 release commit,并只推送这个 tag。禁止使用简短 `-m` 或
|
|
||||||
创建 lightweight release tag。签名不可用或验证失败时停止,不得降级为 unsigned tag。
|
|
||||||
|
|
||||||
同名远端 tag 已存在且指向其他 commit 时立即停止。不要覆盖、删除或移动已经发布的
|
|
||||||
tag。同名 tag 即使指向 release commit,只要它是 lightweight tag、缺少更新说明或说明与
|
|
||||||
计划不一致,也视为身份不匹配并停止。推送后读取远端 tag object,确认它是 annotated
|
|
||||||
tag,将它解引用到 commit 并核对完整更新说明;commit 和说明必须都与发布计划完全一致。
|
|
||||||
|
|
||||||
仅当用户本次请求明确要求时创建 Forge Release;项目策略只能说明创建方式,不能授予
|
|
||||||
外部写权限。必须引用已经存在并验证过的 tag,禁止让平台从默认分支隐式创建 tag。
|
|
||||||
Forge Release 正文复用 tag 中经过验证的更新说明,不维护第二份相互独立的发布内容。
|
|
||||||
|
|
||||||
### 9. 验证、恢复和清理
|
|
||||||
|
|
||||||
分别报告以下状态,不要用“发布成功”掩盖其中某一步未完成:
|
|
||||||
|
|
||||||
- 版本文件和本地验证。
|
|
||||||
- PR/MR URL、合并状态和 merged commit。
|
|
||||||
- 远端 tag 的对象类型、完整更新说明及其解引用后的 commit。
|
|
||||||
- Forge Release URL、可见性及正文一致性,若本次要求创建。
|
|
||||||
- worktree、本地分支和远端分支是否保留。
|
|
||||||
|
|
||||||
清理时只移除干净且已确认不再使用的 linked worktree,不使用强制删除。删除本地或远端
|
|
||||||
分支前确认其提交已合并且可从 base 或 tag 到达;本地和远端分支删除都必须有明确授权。
|
|
||||||
|
|
||||||
## 硬停止条件
|
|
||||||
|
|
||||||
遇到以下任一情况时停止相应写操作并说明恢复路径:
|
|
||||||
|
|
||||||
- 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 或覆盖用户工作。
|
|
||||||
- 不可信代码只能在带仓库写凭据、SSH agent、秘密或非必要网络的环境中运行。
|
|
||||||
|
|
||||||
不要在命令参数、文件、提交、PR/MR、日志或最终回复中暴露 token、密码、私钥路径或
|
|
||||||
认证配置。CLI 不可用时给出人工交接信息,不要擅自改用带 token 的 `curl`。
|
|
||||||
|
|
||||||
## 完成标准
|
|
||||||
|
|
||||||
只分析时,给出当前状态、建议版本、依据和下一步。直接发布时,给出目标 commit 和更新
|
|
||||||
说明,不得虚构 worktree 或分支步骤。开始准备版本时,给出所用 worktree、分支和基线
|
|
||||||
commit;未新建 worktree 时明确说明复用了哪个安全工作区。创建 PR/MR 时,给出 URL 与
|
|
||||||
检查状态。合并时,给出 merged commit。发布 tag 时,证明远端 tag 是包含计划更新说明的
|
|
||||||
annotated tag,并解引用到 release commit。创建 Forge Release 时,再给出 release URL、
|
|
||||||
可见性与正文一致性。任何部分未完成都要标明阻塞阶段和可恢复动作。
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ description: >-
|
|||||||
|
|
||||||
| 缺什么 | 怎么补 |
|
| 缺什么 | 怎么补 |
|
||||||
|--------|--------|
|
|--------|--------|
|
||||||
| 目标 skill | 从话语里的名字/别名解析(`ack`、`manage-release`、发布、测试…);对不上再问一次 |
|
| 目标 skill | 从话语里的名字/别名解析(`ack`、`releaser`、发布、测试…);对不上再问一次 |
|
||||||
| 目标 skill 职责 | 读其 `SKILL.md` 开头 / description |
|
| 目标 skill 职责 | 读其 `SKILL.md` 开头 / description |
|
||||||
| 通用 / 项目记忆目录 | 读目标 skill 的 `memories/manifest.md`(见 [references/manifest.md](references/manifest.md)) |
|
| 通用 / 项目记忆目录 | 读目标 skill 的 `memories/manifest.md`(见 [references/manifest.md](references/manifest.md)) |
|
||||||
| 会话材料 | 默认当前对话里与该次任务相关的回合;用户点名 CLI 会话时再按 id/路径查找 |
|
| 会话材料 | 默认当前对话里与该次任务相关的回合;用户点名 CLI 会话时再按 id/路径查找 |
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ pouch add orc # 当前项目
|
|||||||
pouch add orc -g # 全局
|
pouch add orc -g # 全局
|
||||||
```
|
```
|
||||||
|
|
||||||
`$orc` / `/orc` 只在显式调用时运行。下游阶段还需要已安装 `$ack`、`$manage-release` 或 `$builder`。
|
`$orc` / `/orc` 只在显式调用时运行。下游阶段还需要已安装 `$ack`、`$releaser` 或 `$builder`。
|
||||||
|
|
||||||
## 使用前准备
|
## 使用前准备
|
||||||
|
|
||||||
- Orca 正在运行并启用了 orchestration。
|
- Orca 正在运行并启用了 orchestration。
|
||||||
- 安装本次需要的 `$ack`、`$manage-release` 或 `$builder`(DEB 与 Docker 共用)。
|
- 安装本次需要的 `$ack`、`$releaser` 或 `$builder`(DEB 与 Docker 共用)。
|
||||||
- ORC 直接使用 skill 内共享的 `config.yaml`,不需要在每个项目初始化配置。修改这份
|
- ORC 直接使用 skill 内共享的 `config.yaml`,不需要在每个项目初始化配置。修改这份
|
||||||
配置会影响所有项目;旧的项目级 `docs/orc/config.yaml` 不再参与解析。
|
配置会影响所有项目;旧的项目级 `docs/orc/config.yaml` 不再参与解析。
|
||||||
- `/usr/bin/python3`;ORC v2 配置必须保持为 JSON-compatible YAML。
|
- `/usr/bin/python3`;ORC v2 配置必须保持为 JSON-compatible YAML。
|
||||||
|
|||||||
+4
-4
@@ -73,7 +73,7 @@ JSON-compatible YAML,并由隔离的 Python 标准库解析。它固定包含
|
|||||||
`cursor-agent`。身份不明确时停止,不从用户任务文本、默认值或已安装 executable 猜测。
|
`cursor-agent`。身份不明确时停止,不从用户任务文本、默认值或已安装 executable 猜测。
|
||||||
确认宿主 CLI 可用;在 Cursor 中还要用 `cursor-agent --list-models`
|
确认宿主 CLI 可用;在 Cursor 中还要用 `cursor-agent --list-models`
|
||||||
核对精确模型 ID 对当前账号可见。
|
核对精确模型 ID 对当前账号可见。
|
||||||
4. 确认本次所需下游 Skill 已安装:`ack`、`manage-release`、`builder`。只检查实际
|
4. 确认本次所需下游 Skill 已安装:`ack`、`releaser`、`builder`。只检查实际
|
||||||
会用到的项;`deb` 与 `docker` 阶段都由 `$builder` 承载。
|
会用到的项;`deb` 与 `docker` 阶段都由 `$builder` 承载。
|
||||||
5. 解析 profile 时把项目根和目标 worktree 一并交给 resolver;只有 resolver 验证目标是
|
5. 解析 profile 时把项目根和目标 worktree 一并交给 resolver;只有 resolver 验证目标是
|
||||||
当前 Git 仓库已注册的 worktree 且身份稳定后才可创建终端。不得只做文本比较或跳过
|
当前 Git 仓库已注册的 worktree 且身份稳定后才可创建终端。不得只做文本比较或跳过
|
||||||
@@ -100,7 +100,7 @@ JSON-compatible YAML,并由隔离的 Python 标准库解析。它固定包含
|
|||||||
`codex-login`,Cursor 默认复用 `cursor-login`;只有明确使用环境凭据时才分别选择
|
`codex-login`,Cursor 默认复用 `cursor-login`;只有明确使用环境凭据时才分别选择
|
||||||
`openai`、`azure-openai` 或 `cursor-api-key`。远端认证默认 `none`。release worker 作为
|
`openai`、`azure-openai` 或 `cursor-api-key`。远端认证默认 `none`。release worker 作为
|
||||||
受信任发布角色,直接调用当前 shell 中已认证的 `git` 与 Forge CLI;Gitea/Forgejo 由
|
受信任发布角色,直接调用当前 shell 中已认证的 `git` 与 Forge CLI;Gitea/Forgejo 由
|
||||||
`$manage-release` 在目标 worktree 中运行 `tea`,resolver 不读取 tea 配置、不注入
|
`$releaser` 在目标 worktree 中运行 `tea`,resolver 不读取 tea 配置、不注入
|
||||||
credential helper,也不把 tea token 转成环境变量。只有明确改用环境 token 或 SSH
|
credential helper,也不把 tea token 转成环境变量。只有明确改用环境 token 或 SSH
|
||||||
agent 时,才选择一个精确的 `github-token`、`gitlab-token`、`gitea-token`、
|
agent 时,才选择一个精确的 `github-token`、`gitlab-token`、`gitea-token`、
|
||||||
`forgejo-token`、`ssh-agent` 或 `deb-token`,不得同时交给 worker 多组环境凭据。resolver
|
`forgejo-token`、`ssh-agent` 或 `deb-token`,不得同时交给 worker 多组环境凭据。resolver
|
||||||
@@ -131,7 +131,7 @@ JSON-compatible YAML,并由隔离的 Python 标准库解析。它固定包含
|
|||||||
|
|
||||||
- 功能、缺陷、重构与验证闭环交给 `$ack`。
|
- 功能、缺陷、重构与验证闭环交给 `$ack`。
|
||||||
- 发布版本、release 分支/PR/MR、合并、tag 与 Forge Release 交给
|
- 发布版本、release 分支/PR/MR、合并、tag 与 Forge Release 交给
|
||||||
`$manage-release`。
|
`$releaser`。
|
||||||
- DEB 构建或上传交给 `$builder`(deb 阶段);Docker/OCI 镜像构建或上传也交给
|
- DEB 构建或上传交给 `$builder`(deb 阶段);Docker/OCI 镜像构建或上传也交给
|
||||||
`$builder`(docker 阶段)。
|
`$builder`(docker 阶段)。
|
||||||
- 普通非发布 PR/MR 不伪装成版本发布;只有 ACK 已验证交付或明确的 release 流程才
|
- 普通非发布 PR/MR 不伪装成版本发布;只有 ACK 已验证交付或明确的 release 流程才
|
||||||
@@ -165,7 +165,7 @@ JSON-compatible YAML,并由隔离的 Python 标准库解析。它固定包含
|
|||||||
- resolver 只读取 skill 内有大小上限的普通共享配置文件,拒绝 symlink/special file;
|
- resolver 只读取 skill 内有大小上限的普通共享配置文件,拒绝 symlink/special file;
|
||||||
启动计划绑定配置快照、root-owned 隔离 Python、可信绝对 Agent/Orca executable、Git
|
启动计划绑定配置快照、root-owned 隔离 Python、可信绝对 Agent/Orca executable、Git
|
||||||
worktree identity、release remote identity、精确环境认证选择和固定 argv。实际启动会
|
worktree identity、release remote identity、精确环境认证选择和固定 argv。实际启动会
|
||||||
重新校验 fingerprint;release 阶段允许受信任的 `$manage-release` 直接使用当前 shell
|
重新校验 fingerprint;release 阶段允许受信任的 `$releaser` 直接使用当前 shell
|
||||||
已有的 Git/Forge 登录,resolver 不检查或复制认证文件。显式 token/SSH 认证仍只注入所选
|
已有的 Git/Forge 登录,resolver 不检查或复制认证文件。显式 token/SSH 认证仍只注入所选
|
||||||
环境变量。不得改写 resolver 返回的 worker argv,也不得把终端创建 argv 的绝对 Orca
|
环境变量。不得改写 resolver 返回的 worker argv,也不得把终端创建 argv 的绝对 Orca
|
||||||
路径换成项目 `PATH` 解析。
|
路径换成项目 `PATH` 解析。
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ ORC 是薄路由器,只负责意图映射、依赖、静态档位和结构化
|
|||||||
| 阶段 | 下游 Skill | 包含 | 不包含 |
|
| 阶段 | 下游 Skill | 包含 | 不包含 |
|
||||||
|------|------------|------|--------|
|
|------|------------|------|--------|
|
||||||
| `code` | `$ack` | 功能、缺陷、重构、测试、三角色验证闭环,以及用户明确要求的普通非发布 PR/MR | 版本发布、单独上传产物 |
|
| `code` | `$ack` | 功能、缺陷、重构、测试、三角色验证闭环,以及用户明确要求的普通非发布 PR/MR | 版本发布、单独上传产物 |
|
||||||
| `release` | `$manage-release` | 版本号、release worktree/分支、release PR/MR、合并、tag、Forge Release、恢复发布 | 普通非发布 PR/MR、构建或上传 DEB/Docker |
|
| `release` | `$releaser` | 版本号、release worktree/分支、release PR/MR、合并、tag、Forge Release、恢复发布 | 普通非发布 PR/MR、构建或上传 DEB/Docker |
|
||||||
| `deb` | `$builder` | DEB 构建、契约校验、上传与仓库可见性 | 源码 tag、Docker 镜像 |
|
| `deb` | `$builder` | DEB 构建、契约校验、上传与仓库可见性 | 源码 tag、Docker 镜像 |
|
||||||
| `docker` | `$builder` | Docker/OCI 构建、push、digest 与平台验证 | 源码版本生命周期、DEB |
|
| `docker` | `$builder` | Docker/OCI 构建、push、digest 与平台验证 | 源码版本生命周期、DEB |
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ decision gate。不得为了填满 worker prompt 而分析代码、推断版本
|
|||||||
2. 为每个阶段锁定输入:项目、worktree、源 commit/tag、版本、目标和用户授权的最远
|
2. 为每个阶段锁定输入:项目、worktree、源 commit/tag、版本、目标和用户授权的最远
|
||||||
写操作。
|
写操作。
|
||||||
3. 同一领域的连续动作保留在一个下游任务中。例如版本号、release PR、合并和 tag
|
3. 同一领域的连续动作保留在一个下游任务中。例如版本号、release PR、合并和 tag
|
||||||
属于一个 `manage-release` 生命周期,不拆成多个互相争抢状态的 worker。
|
属于一个 `releaser` 生命周期,不拆成多个互相争抢状态的 worker。
|
||||||
4. 只有输入 revision 完全相同且互不修改同一工作树时,才并行执行 DEB 与 Docker。
|
4. 只有输入 revision 完全相同且互不修改同一工作树时,才并行执行 DEB 与 Docker。
|
||||||
5. 普通代码改动进入 ACK。若项目尚未初始化 ACK,`code` 阶段停在前置条件,不由 ORC
|
5. 普通代码改动进入 ACK。若项目尚未初始化 ACK,`code` 阶段停在前置条件,不由 ORC
|
||||||
静默初始化。
|
静默初始化。
|
||||||
@@ -39,7 +39,7 @@ decision gate。不得为了填满 worker prompt 而分析代码、推断版本
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
code ($ack)
|
code ($ack)
|
||||||
-> release ($manage-release)
|
-> release ($releaser)
|
||||||
-> deb ($builder)
|
-> deb ($builder)
|
||||||
-> docker ($builder)
|
-> docker ($builder)
|
||||||
```
|
```
|
||||||
@@ -53,10 +53,10 @@ deb ($builder) || docker ($builder)
|
|||||||
仅发布源码版本:
|
仅发布源码版本:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
release ($manage-release)
|
release ($releaser)
|
||||||
```
|
```
|
||||||
|
|
||||||
依赖不是固定模板,但 ORC v2 不拆分一个 `manage-release` 生命周期。若项目要求在打开
|
依赖不是固定模板,但 ORC v2 不拆分一个 `releaser` 生命周期。若项目要求在打开
|
||||||
release PR 与合并之间插入 DEB/Docker gate,当前 task 粒度无法安全表达该中间里程碑;
|
release PR 与合并之间插入 DEB/Docker gate,当前 task 粒度无法安全表达该中间里程碑;
|
||||||
在打开 PR 前建立 decision gate 并报告该流程暂不支持,不得用循环依赖或两个 release
|
在打开 PR 前建立 decision gate 并报告该流程暂不支持,不得用循环依赖或两个 release
|
||||||
worker 临时拼接。
|
worker 临时拼接。
|
||||||
@@ -65,7 +65,7 @@ worker 临时拼接。
|
|||||||
|
|
||||||
每个 worker prompt 至少包含:
|
每个 worker prompt 至少包含:
|
||||||
|
|
||||||
- 第一条指令显式调用唯一的下游 Skill,例如 `Use $manage-release ...`。
|
- 第一条指令显式调用唯一的下游 Skill,例如 `Use $releaser ...`。
|
||||||
- 阶段目标与明确的非目标。
|
- 阶段目标与明确的非目标。
|
||||||
- 项目/worktree、输入 commit/tag 和前置阶段的可核对结果。
|
- 项目/worktree、输入 commit/tag 和前置阶段的可核对结果。
|
||||||
- 用户已经授予的最远动作;未授权动作明确禁止。
|
- 用户已经授予的最远动作;未授权动作明确禁止。
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pouch add <name> -a cursor -a claude -a codex -a agents -y
|
|||||||
一次问清要初始化哪些。用户没点名不要自己跑初始化。ACK 初始化**不会**自动初始化
|
一次问清要初始化哪些。用户没点名不要自己跑初始化。ACK 初始化**不会**自动初始化
|
||||||
deployer / builder,需要的话要另说。
|
deployer / builder,需要的话要另说。
|
||||||
|
|
||||||
orc、manage-release 和其余 builtin 装上就能用,不必项目初始化。
|
orc、releaser 和其余 builtin 装上就能用,不必项目初始化。
|
||||||
|
|
||||||
## 4. 介绍怎么喊
|
## 4. 介绍怎么喊
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ FILE_SIGNALS: dict[str, tuple[str, ...]] = {
|
|||||||
"k8s",
|
"k8s",
|
||||||
"helm",
|
"helm",
|
||||||
),
|
),
|
||||||
"manage-release": ("CHANGELOG.md", "CHANGELOG", "VERSION"),
|
"releaser": ("CHANGELOG.md", "CHANGELOG", "VERSION"),
|
||||||
"declarative-openspec-loop": ("openspec", ".openspec"),
|
"declarative-openspec-loop": ("openspec", ".openspec"),
|
||||||
"discussion-notes": ("000inbox",),
|
"discussion-notes": ("000inbox",),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# releaser
|
||||||
|
|
||||||
|
`releaser` 帮助 Agent 发布已经准备好的 Git commit,也能在发布前确有必要时管理
|
||||||
|
版本文件、worktree、分支、PR/MR 和合并。普通发布优先走“更新说明 + annotated tag”的
|
||||||
|
短路径;只有发布要求修改仓库内容时,才进入准备版本的分支流程。
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pouch add releaser # 当前项目
|
||||||
|
pouch add releaser -g # 全局
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用前准备
|
||||||
|
|
||||||
|
- 项目已经是 Git 仓库,并配置了可访问的远端。
|
||||||
|
- 项目已有版本来源或 tag 发布约定;没有时可以让 Agent 先给出版本建议。
|
||||||
|
- 创建或合并 PR/MR、创建 Forge Release 时,准备好 GitHub、GitLab、Gitea 或 Forgejo
|
||||||
|
对应的已认证 CLI。只发布 Git tag 时不要求 Forge CLI,但 Git remote 必须可读写。
|
||||||
|
- 请求里写清目标版本、基线分支,以及允许执行到哪一步。没有明确授权的远端写操作
|
||||||
|
不会执行。
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。不要创建 Forge Release。
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见用法
|
||||||
|
|
||||||
|
### 确定下一个版本号
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser 检查当前版本和这次改动,建议下一个版本号。只分析,不修改文件。
|
||||||
|
```
|
||||||
|
|
||||||
|
适合还没决定该发 patch、minor 还是 major 时使用。Agent 会读取项目版本规则、现有 tag
|
||||||
|
和实际改动,给出建议及依据。
|
||||||
|
|
||||||
|
### 开始开发新版本
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser,从 main 为 1.6.0 创建独立 worktree 和分支。先不要 push,也不要创建 PR。
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 会检查已有 worktree、分支和 tag,确认没有冲突后准备开发目录。这个请求只授权
|
||||||
|
本地操作。
|
||||||
|
|
||||||
|
### 把开发分支提交为 PR
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser 检查当前分支,更新版本号和 CHANGELOG,运行项目测试,然后 push 并创建指向 main 的 PR。不要合并。
|
||||||
|
```
|
||||||
|
|
||||||
|
适合开发已经完成,只需要整理版本信息并送审。Agent 会停在 PR 创建成功的位置,返回
|
||||||
|
PR 地址、测试结果和待处理项。
|
||||||
|
|
||||||
|
### 合并通过检查的 PR
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser 检查当前 PR。如果 CI、review 和冲突检查都通过,就按项目规则合并;不要打 tag。
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 只会在仓库要求全部满足后合并,不会使用管理员权限绕过保护规则。合并完成后会
|
||||||
|
返回准确的 merged commit。
|
||||||
|
|
||||||
|
### 为已合并版本发布 tag
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser,为已经合并到 main 的 1.6.0 发布 v1.6.0 tag。根据 v1.5.0 到目标 commit 的实际变化生成更新说明,把说明写入 annotated tag,并验证远端 tag 的 commit 和说明。不要创建 Forge Release。
|
||||||
|
```
|
||||||
|
|
||||||
|
这是无需修改仓库文件时的默认短路径,适合依靠 Git tag 触发后续 CI 发布的项目。Agent
|
||||||
|
会分别验证目标 commit、更新说明和远端 tag,不会创建 worktree、发布分支或 PR,也不会
|
||||||
|
给未合并分支打正式 tag。
|
||||||
|
|
||||||
|
### 为已合并版本创建 Gitea Release
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser,发布已经合并到 main 的 1.6.0:生成更新说明,创建并验证附带说明的 v1.6.0 annotated tag,然后在 Gitea 创建使用同一份说明的 Release。
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 会先证明 tag 已存在、指向计划 commit 且包含更新说明,再创建 Gitea Release。
|
||||||
|
Release 创建失败时保留正确的 tag,从 Release 阶段恢复。
|
||||||
|
|
||||||
|
### 完成端到端发布
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser 完成 1.6.0 发布:从 main 创建 worktree 和分支,完成版本更新和验证,创建 PR,检查通过后合并,推送 v1.6.0 tag,并创建 Forge Release。
|
||||||
|
```
|
||||||
|
|
||||||
|
只有版本文件或仓库内 CHANGELOG 必须随发布修改时才使用这条长路径。tag 仍必须附带更新
|
||||||
|
说明,Forge Release 复用同一份说明。遇到 review 未通过、CI 失败、版本冲突或已有同名
|
||||||
|
tag 时,Agent 会停止并说明卡在哪一步,不会绕过检查继续发布。
|
||||||
|
|
||||||
|
### 发布紧急修复版本
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser 从 main 准备 1.6.1 hotfix。创建独立 worktree,完成修复后开 PR;检查通过就合并并发布 v1.6.1。
|
||||||
|
```
|
||||||
|
|
||||||
|
适合线上问题修复。Skill 仍走正常 PR 和保护分支流程,不会因为是 hotfix 就直接推送
|
||||||
|
main 或覆盖已有 tag。
|
||||||
|
|
||||||
|
### 从中断位置继续
|
||||||
|
|
||||||
|
```text
|
||||||
|
使用 releaser 检查 v1.6.0 当前发布状态,从尚未完成的步骤继续。不要重复创建分支、PR、tag 或 release。
|
||||||
|
```
|
||||||
|
|
||||||
|
适合合并后打 tag 失败、tag 已推送但 release 未创建,或者 Agent 会话中断的情况。
|
||||||
|
Skill 会从 Git 和代码托管平台重新判断状态,再继续缺失的步骤。
|
||||||
|
|
||||||
|
## Agent 会做什么
|
||||||
|
|
||||||
|
Agent 会先发现项目自己的版本和发布规则、锁定远端目标 commit,再判断发布是否要求修改
|
||||||
|
仓库内容。不需要修改时直接生成更新说明并发布 annotated tag;需要修改时才准备分支,
|
||||||
|
并只在隔离用户工作确有必要时创建 worktree。它只执行请求中明确授权的阶段,并在合并、
|
||||||
|
tag 或 release 条件不满足时停止。
|
||||||
|
|
||||||
|
## 如何判断完成
|
||||||
|
|
||||||
|
- 只分析版本时,结果包含建议版本及依据。
|
||||||
|
- 创建开发环境时,结果包含 worktree 路径、分支和基线 commit。
|
||||||
|
- 创建或合并 PR/MR 时,结果包含 URL、检查状态和 merged commit。
|
||||||
|
- 发布 tag 时,远端 tag 解引用后的 commit 与目标 commit 一致,而且 tag object 包含经过
|
||||||
|
核对的更新说明。
|
||||||
|
- 创建 Forge Release 时,结果包含可访问的 release URL,正文与 tag 更新说明一致。
|
||||||
|
- 中途停止时,结果说明停在哪一步、为什么停止,以及下次如何继续。
|
||||||
|
|
||||||
|
## 不适用的场景
|
||||||
|
|
||||||
|
普通功能开发、普通 worktree 或 PR/MR 操作、代码审查、构建 Docker 镜像或上传 DEB 包
|
||||||
|
不需要触发 `releaser`。只有任务明确涉及版本发布、发布分支、版本号、发布 PR/MR
|
||||||
|
或 release tag 时,才交给这个 Skill。
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
---
|
||||||
|
name: releaser
|
||||||
|
description: >-
|
||||||
|
管理 Git 项目从已准备 commit 到版本发布的生命周期:发现并遵循项目版本与发布策略,
|
||||||
|
优先为远端已验证 commit 生成更新说明并创建 annotated release tag,按需创建 Forge
|
||||||
|
Release;只有必须修改版本文件或仓库内发布说明时,才创建或复用版本分支、worktree
|
||||||
|
和 PR/MR。也支持恢复中断流程与安全清理。用户要求发布版本、打 release tag、创建
|
||||||
|
平台 Release、准备版本变更、处理 hotfix 或继续未完成发布时使用。只做普通编码、普通
|
||||||
|
worktree 或 PR/MR 操作、代码审查、构建或上传 DEB/Docker 等产物、管理仓库权限时不使用。
|
||||||
|
用户提到旧名 manage-release 时同样使用本 skill。
|
||||||
|
---
|
||||||
|
|
||||||
|
# Releaser(原 manage-release)
|
||||||
|
|
||||||
|
根据项目现有规则管理源码版本生命周期。把项目策略当作规则来源,把 Git 与代码托管
|
||||||
|
平台的实时状态当作运行状态;不要创建另一份会与分支、PR/MR 或 tag 分叉的状态文件。
|
||||||
|
|
||||||
|
## 按需读取参考资料
|
||||||
|
|
||||||
|
- 开始任何流程时读取 [project-policy.md](references/project-policy.md),确定策略来源和默认值。
|
||||||
|
- 需要选择、更新或核对版本号,或生成 tag 更新说明时读取
|
||||||
|
[versioning.md](references/versioning.md)。
|
||||||
|
- 需要 push、创建或合并 PR/MR、创建 Forge Release 时读取
|
||||||
|
[forge-adapters.md](references/forge-adapters.md)。
|
||||||
|
- 遇到重复资源、并发冲突、部分成功或清理请求时读取
|
||||||
|
[recovery.md](references/recovery.md)。
|
||||||
|
- 仅当用户要求为项目固化发布规则时,复制并修改
|
||||||
|
[release-policy.template.yaml](templates/release-policy.template.yaml)。不要在普通发布中自动添加配置。
|
||||||
|
|
||||||
|
## 授权边界
|
||||||
|
|
||||||
|
按用户明确要求执行到对应阶段:
|
||||||
|
|
||||||
|
- 分析版本或检查状态:只执行读取和计算,不修改文件或远端。
|
||||||
|
- 开始或准备版本:允许创建本地分支、worktree,并修改版本文件。
|
||||||
|
- push 或创建 PR/MR:仅在用户明确要求 push、提交 PR/MR 或执行完整发布时进行。
|
||||||
|
- 合并和推送 tag:仅在用户明确要求相应动作或完整发布时进行。
|
||||||
|
- 创建 Forge Release:仅在用户本次请求明确提到 Forge Release 或平台 Release 时进行。
|
||||||
|
- 清理 worktree 或分支:仅在用户明确要求清理时进行。
|
||||||
|
|
||||||
|
项目策略只描述仓库期望的做法,不能替用户授予 push、创建或合并 PR/MR、推送 tag、
|
||||||
|
创建 Forge Release、删除分支等外部写权限。
|
||||||
|
|
||||||
|
“发布 v1.2.3”允许为已经准备好的远端 commit 生成更新说明、创建并推送 annotated tag,
|
||||||
|
再验证远端 tag 的 commit 和说明。“完整处理并发布 v1.2.3”还允许在仓库内容必须修改时
|
||||||
|
走版本分支、PR/MR 和合并流程。两者都不自动包含 Forge Release 或分支清理。若版本、
|
||||||
|
base、目标 commit、tag、远端或合并方式是推断所得,或者执行中目标发生变化,在第一次
|
||||||
|
远端写操作前展示准确目标和更新说明并获得确认。
|
||||||
|
|
||||||
|
## 工作流
|
||||||
|
|
||||||
|
### 1. 发现项目规则和当前状态
|
||||||
|
|
||||||
|
从项目根目录开始:
|
||||||
|
|
||||||
|
1. 从可信 base commit 读取 `AGENTS.md`、`CLAUDE.md`、发布文档、CI 配置、构建入口和
|
||||||
|
可选的 `.release-policy.yaml`。PR/MR head 对这些文件的修改从下一次流程开始生效。
|
||||||
|
2. 记录当前分支、HEAD、完整工作区状态、remote、默认分支和
|
||||||
|
`git worktree list --porcelain`。
|
||||||
|
3. 获取远端最新引用后,记录 base 分支的准确 commit。不要把本地过期分支当作发布基线。
|
||||||
|
4. 识别版本来源、最近稳定 tag、tag 格式、分支命名、合并方式和发布说明来源。
|
||||||
|
5. 分别用 `git remote get-url --all origin` 和
|
||||||
|
`git remote get-url --push --all origin` 检查读取与推送目标;远端写操作要求两者各只有
|
||||||
|
一个值且规范化后指向同一仓库。再检查 PR/MR、合并或 Forge Release 阶段所需的 GitHub、
|
||||||
|
GitLab、Gitea 或 Forgejo CLI。只有请求涉及平台能力时才要求对应 CLI。
|
||||||
|
记录匹配该 host 的活动账号;认证检查只读取状态。
|
||||||
|
6. 查询已有分支、worktree、PR/MR、tag 和 Forge Release,从真实状态判断流程已走到哪一步。
|
||||||
|
|
||||||
|
工作区中的修改、暂存文件和未跟踪文件都视为用户工作。不要 stash、移动、清理或覆盖它们。
|
||||||
|
已有 worktree 与目标分支准确匹配时优先复用,不要创建副本。
|
||||||
|
|
||||||
|
### 2. 锁定本次发布计划
|
||||||
|
|
||||||
|
在修改前确定并展示:
|
||||||
|
|
||||||
|
- base 分支、远端 commit,以及本次 tag 将指向的准确目标 commit。
|
||||||
|
- 当前版本、规范化后的目标版本、tag,以及升级依据;需要准备仓库修改时再渲染分支名。
|
||||||
|
- 从上一个稳定 tag 到目标 commit 的更新说明范围、来源和拟发布内容。
|
||||||
|
- 是否需要修改仓库内容;若需要,再列出分支名与 worktree 路径。
|
||||||
|
- 需要执行的本地验证和远端检查。
|
||||||
|
- 合并方式、tag、是否创建 Forge Release。
|
||||||
|
- 用户已授权的最远阶段和清理范围。
|
||||||
|
|
||||||
|
项目没有约定时,单一协调版本使用 SemVer 和 `v<version>` annotated tag。只有发布前
|
||||||
|
必须修改仓库内容时才使用 `release/v<version>` 分支;仓库只启用一种合并方式时使用该
|
||||||
|
方式,存在多种方式且没有项目规则时默认 squash。默认不删除远端分支,不自动创建
|
||||||
|
Forge Release。
|
||||||
|
|
||||||
|
把用户输入拆成“规范版本”和“展示名称”:默认 SemVer 的规范版本是无 `v` 前缀的
|
||||||
|
`1.6.0`,版本文件和 `{version}` 都使用该值;分支与 tag 再分别按 pattern 渲染为
|
||||||
|
`release/v1.6.0` 和 `v1.6.0`。用户输入 `v1.6.0` 时先规范化,不要产生双前缀。
|
||||||
|
|
||||||
|
### 3. 选择直接发布或准备版本
|
||||||
|
|
||||||
|
先计算发布所需的仓库内容差异,不要为了遵循固定模板而创建分支或 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 占用。
|
||||||
|
- 目标目录不是 `/`、用户主目录、仓库根目录或已有非空目录。
|
||||||
|
- base 使用刚获取的远端引用,例如 `origin/main`,而不是不确定的新旧本地分支。
|
||||||
|
- 分支名通过 `git check-ref-format --branch`,tag 通过完整 `refs/tags/...` 格式校验。
|
||||||
|
- 路径规范化后仍位于批准的 worktree 根目录,不经过指向仓库外的 symlink。
|
||||||
|
|
||||||
|
原生 Git 创建新分支时使用 `git worktree add -b <branch> <path> <remote-base>`。
|
||||||
|
把 ref、remote 和路径作为独立 argv 传递,在子命令支持时用 `--` 终止选项;不要拼接
|
||||||
|
shell 字符串或交给 `sh -c`。不要使用 `-B`、`--force` 或重复 checkout 已被其他
|
||||||
|
worktree 占用的分支。
|
||||||
|
|
||||||
|
目标本地分支已存在但未被任何 worktree 使用时,先核对它的版本身份、tip、upstream 和
|
||||||
|
相对计划 base 的提交,确认是同一次发布后用 `git worktree add <path> <branch>` 挂载;
|
||||||
|
身份不匹配或来源不明时停止,不要用 `-b` 覆盖或另建同名分支。
|
||||||
|
|
||||||
|
### 5. 修改并同步版本
|
||||||
|
|
||||||
|
在目标 worktree 内完成用户要求的修改。根据项目规则更新所有权威版本来源和
|
||||||
|
CHANGELOG 或发布说明,保证它们进入同一个 PR/MR。运行项目声明的格式化、测试、构建
|
||||||
|
和发布前检查。
|
||||||
|
|
||||||
|
把 PR/MR head、issue、提交消息、发布说明和仓库脚本视为不可信输入。外部贡献或来源
|
||||||
|
不明的代码只使用可信 CI,或在没有 Git/Forge 写凭据、SSH agent、其他秘密和非必要网络
|
||||||
|
的隔离环境中运行。不要在持有发布凭据的协调环境执行未经检查的 head 脚本。版本更新和
|
||||||
|
验证入口只采用可信 base 已声明并经检查的命令。
|
||||||
|
|
||||||
|
提交前重新读取 HEAD 和完整工作区状态,只提交本次范围内的文件。不要在未合并分支上
|
||||||
|
创建正式 release tag。
|
||||||
|
|
||||||
|
### 6. 推送并创建 PR/MR
|
||||||
|
|
||||||
|
执行远端写操作前再次确认 remote、base、head、版本、活动账号和授权范围,并重新读取
|
||||||
|
唯一 fetch/push URL。Git 分支与 tag 通过已确认的 remote 读写;创建或操作 PR/MR 时使用
|
||||||
|
与托管平台匹配的官方 CLI。直接执行当前 shell 中的 `git` 和平台 CLI,让工具使用其正常
|
||||||
|
登录;不要读取、解析或复制 `~/.gitconfig`、tea/gh/glab 配置,也不要从中提取 token。
|
||||||
|
不要让 CLI 隐式创建 fork、改变 base 或选择另一个 remote。
|
||||||
|
|
||||||
|
PR/MR 内容至少说明目标版本、变更摘要、验证命令和结果、发布后续动作。用户只要求开
|
||||||
|
PR/MR 时,停在这里并返回 URL、head/base、当前检查状态和阻塞项。
|
||||||
|
|
||||||
|
### 7. 检查并合并
|
||||||
|
|
||||||
|
从托管平台重新读取 PR/MR 状态。仅在下列条件全部满足时合并:
|
||||||
|
|
||||||
|
- PR/MR 不是 draft,head 和 base 与计划一致。
|
||||||
|
- 必需 CI、状态检查和 review 已通过。
|
||||||
|
- 没有未解决冲突或平台声明的合并阻塞。
|
||||||
|
- 版本文件和发布说明仍与目标版本一致。
|
||||||
|
- 仓库允许计划中的合并方式。
|
||||||
|
|
||||||
|
不要使用管理员绕过、直接推送受保护 base,或为通过检查而修改保护规则。合并后获取
|
||||||
|
平台确认的 merged commit,更新远端 base,并验证该 commit 可从远端 base 到达。
|
||||||
|
|
||||||
|
### 8. 创建并发布带更新说明的 tag
|
||||||
|
|
||||||
|
准备版本路径使用平台确认且可从远端 base 到达的 merged commit;直接发布路径使用计划
|
||||||
|
中锁定且重新验证过的远端目标 commit。两者统一记为 release commit。核对目标版本后,
|
||||||
|
再查询一次远端同名 tag。
|
||||||
|
|
||||||
|
创建 tag 前,按 [versioning.md](references/versioning.md) 生成并检查 tag message:根据
|
||||||
|
上一个稳定 tag 到 release commit 的实际差异填写 `Summary`、`Changes`、`Validation`
|
||||||
|
和 `Base commit`;首次发布则使用项目声明的发布基线,没有声明时核对完整可达历史并明确
|
||||||
|
标记首次发布。空说明、只重复版本号或提交标题、缺少规定字段、模板占位文字、伪造变更
|
||||||
|
或无法由实际变化支持的内容都不能发布。
|
||||||
|
|
||||||
|
tag 不存在时,把检查通过的完整 message 写入文件,再用
|
||||||
|
`git tag -a <tag> <release-commit> -F <release-notes-file>` 创建 annotated tag;项目
|
||||||
|
要求签名时,必须先确认签名工具和密钥可用,创建 signed annotated tag,并在本地验证签名
|
||||||
|
成功后才允许 push。显式指定 release commit,并只推送这个 tag。禁止使用简短 `-m` 或
|
||||||
|
创建 lightweight release tag。签名不可用或验证失败时停止,不得降级为 unsigned tag。
|
||||||
|
|
||||||
|
同名远端 tag 已存在且指向其他 commit 时立即停止。不要覆盖、删除或移动已经发布的
|
||||||
|
tag。同名 tag 即使指向 release commit,只要它是 lightweight tag、缺少更新说明或说明与
|
||||||
|
计划不一致,也视为身份不匹配并停止。推送后读取远端 tag object,确认它是 annotated
|
||||||
|
tag,将它解引用到 commit 并核对完整更新说明;commit 和说明必须都与发布计划完全一致。
|
||||||
|
|
||||||
|
仅当用户本次请求明确要求时创建 Forge Release;项目策略只能说明创建方式,不能授予
|
||||||
|
外部写权限。必须引用已经存在并验证过的 tag,禁止让平台从默认分支隐式创建 tag。
|
||||||
|
Forge Release 正文复用 tag 中经过验证的更新说明,不维护第二份相互独立的发布内容。
|
||||||
|
|
||||||
|
### 9. 验证、恢复和清理
|
||||||
|
|
||||||
|
分别报告以下状态,不要用“发布成功”掩盖其中某一步未完成:
|
||||||
|
|
||||||
|
- 版本文件和本地验证。
|
||||||
|
- PR/MR URL、合并状态和 merged commit。
|
||||||
|
- 远端 tag 的对象类型、完整更新说明及其解引用后的 commit。
|
||||||
|
- Forge Release URL、可见性及正文一致性,若本次要求创建。
|
||||||
|
- worktree、本地分支和远端分支是否保留。
|
||||||
|
|
||||||
|
清理时只移除干净且已确认不再使用的 linked worktree,不使用强制删除。删除本地或远端
|
||||||
|
分支前确认其提交已合并且可从 base 或 tag 到达;本地和远端分支删除都必须有明确授权。
|
||||||
|
|
||||||
|
## 硬停止条件
|
||||||
|
|
||||||
|
遇到以下任一情况时停止相应写操作并说明恢复路径:
|
||||||
|
|
||||||
|
- 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 或覆盖用户工作。
|
||||||
|
- 不可信代码只能在带仓库写凭据、SSH agent、秘密或非必要网络的环境中运行。
|
||||||
|
|
||||||
|
不要在命令参数、文件、提交、PR/MR、日志或最终回复中暴露 token、密码、私钥路径或
|
||||||
|
认证配置。CLI 不可用时给出人工交接信息,不要擅自改用带 token 的 `curl`。
|
||||||
|
|
||||||
|
## 完成标准
|
||||||
|
|
||||||
|
只分析时,给出当前状态、建议版本、依据和下一步。直接发布时,给出目标 commit 和更新
|
||||||
|
说明,不得虚构 worktree 或分支步骤。开始准备版本时,给出所用 worktree、分支和基线
|
||||||
|
commit;未新建 worktree 时明确说明复用了哪个安全工作区。创建 PR/MR 时,给出 URL 与
|
||||||
|
检查状态。合并时,给出 merged commit。发布 tag 时,证明远端 tag 是包含计划更新说明的
|
||||||
|
annotated tag,并解引用到 release commit。创建 Forge Release 时,再给出 release URL、
|
||||||
|
可见性与正文一致性。任何部分未完成都要标明阻塞阶段和可恢复动作。
|
||||||
@@ -44,11 +44,11 @@ class OrcSkillTests(unittest.TestCase):
|
|||||||
self.assertIn("当前 shell", skill)
|
self.assertIn("当前 shell", skill)
|
||||||
self.assertNotIn("用户未指定档位时采用以下判断", skill)
|
self.assertNotIn("用户未指定档位时采用以下判断", skill)
|
||||||
self.assertNotIn("若该档位不足以安全完成", skill)
|
self.assertNotIn("若该档位不足以安全完成", skill)
|
||||||
for child in ("$ack", "$manage-release", "$builder"):
|
for child in ("$ack", "$releaser", "$builder"):
|
||||||
self.assertIn(child, routing)
|
self.assertIn(child, routing)
|
||||||
|
|
||||||
def test_children_do_not_reference_orc(self) -> None:
|
def test_children_do_not_reference_orc(self) -> None:
|
||||||
for child in ("ack", "manage-release", "builder"):
|
for child in ("ack", "releaser", "builder", "manage-release"):
|
||||||
for path in (REPO_ROOT / "skills" / child).rglob("*"):
|
for path in (REPO_ROOT / "skills" / child).rglob("*"):
|
||||||
if not path.is_file() or "__pycache__" in path.parts:
|
if not path.is_file() or "__pycache__" in path.parts:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -29,15 +29,28 @@ class CatalogTests(unittest.TestCase):
|
|||||||
"builder",
|
"builder",
|
||||||
"deployer",
|
"deployer",
|
||||||
"host-sec-check",
|
"host-sec-check",
|
||||||
"manage-release",
|
"releaser",
|
||||||
"note-style",
|
"note-style",
|
||||||
"pouch",
|
"pouch",
|
||||||
|
# 旧名兼容占位,仍须可列出(见 test_manage_release_is_deprecation_stub)
|
||||||
|
"manage-release",
|
||||||
):
|
):
|
||||||
self.assertIn(f"| {name} |", result.stdout)
|
self.assertIn(f"| {name} |", result.stdout)
|
||||||
self.assertIn("/ack 初始化", result.stdout)
|
self.assertIn("/ack 初始化", result.stdout)
|
||||||
self.assertIn("用 builder 初始化这个项目", result.stdout)
|
self.assertIn("用 builder 初始化这个项目", result.stdout)
|
||||||
self.assertNotIn("触发词", result.stdout)
|
self.assertNotIn("触发词", result.stdout)
|
||||||
|
|
||||||
|
def test_manage_release_is_deprecation_stub(self) -> None:
|
||||||
|
"""旧名只保留指向 releaser 的占位,不得再携带流程或参考资料。"""
|
||||||
|
stub = REPO_ROOT / "skills" / "manage-release"
|
||||||
|
skill = (stub / "SKILL.md").read_text(encoding="utf-8")
|
||||||
|
self.assertIn("name: manage-release", skill)
|
||||||
|
self.assertIn("已弃用", skill)
|
||||||
|
self.assertIn("../releaser/SKILL.md", skill)
|
||||||
|
self.assertTrue((REPO_ROOT / "skills" / "releaser" / "SKILL.md").is_file())
|
||||||
|
self.assertFalse((stub / "references").exists())
|
||||||
|
self.assertFalse((stub / "templates").exists())
|
||||||
|
|
||||||
def test_missing_readme_fails(self) -> None:
|
def test_missing_readme_fails(self) -> None:
|
||||||
with tempfile.TemporaryDirectory() as tmp:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
skill = Path(tmp) / "demo"
|
skill = Path(tmp) / "demo"
|
||||||
|
|||||||
Reference in New Issue
Block a user