OPC 运营控制台

2026-10-01 13:48
发版线

一次发版 = 7 个节点 = 7 条 rel 命令

一次发版 = 7 个节点,每节点一条 rel 命令,各自可单独调用、可重入、有分类退出码;全链一条 rel all。AI 只出现在 rel plan 的文案字段里,其余六节都是工具在判。
7/7 节点已上线版本:v1.1 落地稿(2026-09-24)适用范围:Pinnadash 全线产品的发版流程
你只需要触发这一条
rel all <app> --from-plan <plan.json>
plan 由 rel plan 先落盘,后续节点自动接指针;任一节红即停,不续发。

发版流程图 · 7 个节点 = 7 条命令

1

整理版本信息

rel plan
判定:plan 字段齐全、版本单调递增、与现网 feed 版本不相同
退出码 0 / 1 / 2
已上线
2硬闸门

部署配置检查

rel check
判定:§3.2 八项体检全绿(fail-closed)
退出码 0 / 2 / 3 / 4
已上线
3

版本号落码

rel bump
判定:各 versionFiles 一致、工作区无越界改动
退出码 0 / 1 / 2
已上线
4

构建出包

rel build
判定:产物存在、内嵌版本与 plan 一致、签名可验
退出码 0 / 2 / 3
已上线
5对外不可逆

发布上线

rel ship
判定:三处回执齐、分发地址可取、发版锁释放
退出码 0 / 1 / 2 / 3 / 4
已上线
6

线上核验

rel verify
判定:绕缓存抓到新版本号、安装包 URL 可下载、官网 SKILL 与仓内正本一致(2026-09-29 补第五路;仓无 SKILL.md 跳过;全产品对账=ops/skill_sync.py)
退出码 0 / 5
已上线
7

回退

rel rollback
判定:快照可读且版本自洽、回退后线上绕缓存抓到旧版且安装包可下载
退出码 0 / 1 / 3 / 5
已上线
异常分支任一节红 → 停下改那一节(不换判据重试);rel verify 报 exit 5 → rel rollback 回上一版 → 复跑 verify。「已发布」这个词只允许来自 verify 的 exit 0。
序号即执行顺序(第一行 1-4,第二行 5-7)。绿=已上线该节,黄=有实现但判据不硬,红=节点缺位;橙顶边=硬闸门,红顶边=对外不可逆。数据源:docs/工程规范/RELEASE-LINE-STANDARD.md §1。

全链一条命令 · 断点续跑

# 一口气跑完:plan → check → bump → build → ship → verify(plan 由 rel plan 先落盘,后续节点自动接指针)
rel plan easy-clipboard --notes notes.json          # AI 只写 notes.json(版本号可省,自动顺延补丁号)
rel all  easy-clipboard                              # 检查→落码→出包→上线→核验

# 只跑到出包为止(先验产物再决定是否上线)
rel all easy-disk --to build

# 任一节失败 → 修完只从那节续跑,不重跑已成功的前序节
rel ship easy-flow --dry-run   # 看清单
rel ship easy-flow --yes       # 对外不可逆,单独跑必须显式授权
rel verify easy-flow

节点 ↔ 命令对照表(正本 §1 原样渲染,输入/输出并一列)

节点命令输入 → 输出判定退出码现状
整理版本信息rel plan产品仓 release.json + 线上 feed + CHANGELOG 未发布块 + --notes 文案
→ ~/.pinnadash/releases/<app>/<ver>/release-plan-<app>-<ver>.json
plan 字段齐全、版本单调递增、与现网 feed 版本不相同0 / 1 / 2已上线
✅ 2026-09-24 落地(客观字段命令自读,AI 只给 --notes)
部署配置检查rel checkplan + 产品仓 release.json
→ ~/.pinnadash/releases/<app>/<ver>/check.json
§3.2 八项体检全绿(fail-closed)0 / 2 / 3 / 4已上线
✅ 2026-09-24 落地(引擎缺失实测 exit 3 阻断)
版本号落码rel bumpplan
→ 版本号变更 + commit
各 versionFiles 一致、工作区无越界改动0 / 1 / 2已上线
✅ 现为 prepare 段(旧 --stage prepare 在双轨期)
构建出包rel build已 bump 的产品仓
→ NSIS 安装包
产物存在、内嵌版本与 plan 一致、签名可验0 / 2 / 3已上线
✅ 现为 build 段
发布上线rel ship安装包 + plan
→ R2 产物 + feed 点亮 + 逐版本 feed 快照 + 官网回填 + 代码 push
三处回执齐、分发地址可取、发版锁释放0 / 1 / 2 / 3 / 4已上线
✅ 现为 upload + web 两节;快照是 rel rollback 的回退源
线上核验rel verify公网地址
→ ~/.pinnadash/releases/<app>/<ver>/verify.json
绕缓存抓到新版本号、安装包 URL 可下载、官网 SKILL 与仓内正本一致(2026-09-29 补第五路;仓无 SKILL.md 跳过;全产品对账=ops/skill_sync.py)0 / 5已上线
✅ 现为 verify 段
回退rel rollback目标版本号(缺省取上一版,来源=R2 feed 快照清单)
→ feed 与官网回指旧版 + 复跑核验
快照可读且版本自洽、回退后线上绕缓存抓到旧版且安装包可下载0 / 1 / 3 / 5已上线
✅ 2026-09-24 落地(只覆盖有快照的版本,即 09-24 之后发布的版本)

每节点详解(命令 + 完整示例)

1整理版本信息 rel plan 已上线

输入产品仓 release.json + 线上 feed + CHANGELOG 未发布块 + --notes 文案
输出~/.pinnadash/releases/<app>/<ver>/release-plan-<app>-<ver>.json
rel plan easy-clipboard --notes notes.json --json
# 输出:~/.pinnadash/releases/easy-clipboard/0.5.11/release-plan-easy-clipboard-0.5.11.json
# notes.json = {"changes":[{"zh":"…","en":"…"}, …]}(中英必须成对,缺 en 即 exit 2)

2部署配置检查 rel check 已上线

输入plan + 产品仓 release.json
输出~/.pinnadash/releases/<app>/<ver>/check.json
八项体检(全绿才放行,任一 FAIL 即 exit 2 阻断全链):
rel check easy-clipboard --json
# 0 = 八项全绿;2 = 有 FAIL 项(stderr 逐条列出 + 修法提示)

3版本号落码 rel bump 已上线

输入plan
输出版本号变更 + commit
rel bump easy-clipboard            # 写版本号 + commit

4构建出包 rel build 已上线

输入已 bump 的产品仓
输出NSIS 安装包
rel build easy-clipboard           # 出包;--dry-run 只打印将要执行的构建命令

5发布上线 rel ship 已上线

输入安装包 + plan
输出R2 产物 + feed 点亮 + 逐版本 feed 快照 + 官网回填 + 代码 push
rel ship easy-clipboard --dry-run   # 先看要动哪些外部资源
rel ship easy-clipboard --yes       # 真发:R2 + feed + 官网 + push

6线上核验 rel verify 已上线

输入公网地址
输出~/.pinnadash/releases/<app>/<ver>/verify.json
rel verify easy-clipboard --json

7回退 rel rollback 已上线

输入目标版本号(缺省取上一版,来源=R2 feed 快照清单)
输出feed 与官网回指旧版 + 复跑核验
rel rollback easy-clipboard --dry-run     # 先看要动哪些外部资源(现网 → 目标版)
rel rollback easy-clipboard --yes         # 回到上一版(上一版来源=R2 里的逐版本 feed 快照清单)
rel rollback easy-image --to 0.3.1 --yes  # 回到指定版

通用参数(全线命令一致)

参数作用
--jsonstdout 只出结构化结果,日志走 stderr
--dry-run只打印将要执行的动作与将改动的外部资源
--yes对外不可逆节(ship/rollback)必需
--to <节点>串跑到该节点为止(仅 rel all)
--from <节点>从该节点续跑(依赖已有产物)
--app <slug>产品标识(easy-clipboard 这一族,与 feed/app 注册名一致);动词形态下它紧跟动词写,--app 是旧形态等价写法

退出码即契约(AI 与人都照它处置,不靠读日志猜)

exit 0 PASS
进下一节
exit 1 用法或前置不满足(参数错、check 未过、缺 --yes)
改命令或补前置,不碰代码
exit 2 内容不达标(体检 FAIL、产物与 plan 不符)
改产物或 plan 后重跑本节
exit 3 外部依赖不可用(R2 / feed / 官网 / 网络)
标 pending 进待办,不当已发
exit 4 缺凭据 / 凭据过期 / 发版锁被占
交老板补凭据或另一会话收锁
exit 5 已发布但线上核验不符
默认 rel rollback,不续发

发版纪律

实现映射与落地顺序

本文节点现实现(`app_admin/scripts/release.mjs`)状态
rel 门面main() 动词分派 + VERBS/STAGE_TO_VERB✅ 动词形态已上;旧 --app --from-plan [--stage] 作 alias 保留,每次调用打一行迁移提示
plancmdPlan()(+ unreleasedBlock/bulletsOf 读 CHANGELOG 未发布块)✅ 2026-09-24 落地,三件判定真实触发
checkrunGate() 八项 + writeGateReport()✅ 改 fail-closed:引擎缺失/执行失败/输出不可解析一律 FAIL 阻断(实测 exit 3);逐条收集一次报完
bump/build/ship/verifyprepare/build/upload/web/verify 段✅ 语义归并,判定不变;ship 加 --yes 闸、逐版本 feed 快照;verify 落 verify.json
rollbackcmdRollback() + listKeys()(R2 前缀清单)✅ 2026-09-24 落地,依赖 ship 落的 updates/<app>/v<ver>.json 快照
渲染ops/release_docs.py✅ 解析 §1 表 → 出 HTML + 流程图;文档不达标 exit 2 不出半成品页
机检app_admin/test/release-line.test.js✅ 动词集/段集/CHANGELOG 读取 + 退出码 1/2 真实触发(spawn 实测)
落地顺序:① check 独立并 fail-closed → ② plan 校验 → ③ rollback → ④ 门面动词化(旧 --stage 调用带 alias 过渡,确认后一次摘除,不搞长期双轨)。
本页由 ops/release_docs.py 从文档生成,要改流程请改 docs/工程规范/RELEASE-LINE-STANDARD.md §1 表格后重跑,不要直接改 HTML。
页面生成时间 2026-10-01 13:48 · 正本 docs/工程规范/RELEASE-LINE-STANDARD.md · 节点数 7 · 由 ops/release_docs.py 生成,禁手改