🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇧🇦 bs · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇹🇼 zh-TW
最后更新: 2026-08-28 — v3.8.51 使用 Claude Code 技能实现自动化,从而简化发布流程。
在两次发布之间保持队列/分支为绿色:请参阅 RELEASE_GREEN.md (
/green-prs系列 +npm run check:release-green+/babysit+ nightly)。定期运行 这些流程——尤其是在执行此检查清单之前——可确保发布 PR 从绿色状态开始。
# 1. 提升版本并生成 CHANGELOG(技能)
/version-bump-cc patch # 或 minor/major
# 2. 在本地运行质量门禁
npm run check # lint + 测试
npm run test:coverage # 完整覆盖率门禁(60/60/60/60)
# 3. 构建并进行冒烟测试
npm run build
npm run test:e2e # 可选,但建议运行
# 4. 生成发布(技能)
/generate-release-cc
# 5. 部署(技能)
/deploy-vps-both-cc # 或 akamai-cc / local-cc
# 6. 捕获发布证据(技能)
/capture-release-evidences-cc默认情况下,npm-publish.yml 通过 **npm 可信发布(OIDC)**进行发布:
stage-npm 作业(由 GitHub 托管)会在该次运行中使用 GitHub 的 id-token 换取一个短期 npm
凭证——仓库机密中无需保存长期 npm 令牌,无需进行 2FA 提示,并附带来源证明。
如今,可绕过 2FA 的令牌正在被逐步淘汰,这正是 npm 批准的绕过方式;
它恢复了项目截至 v3.8.48 所采用的全自动流程,同时保留
WS1.3 保证(泄露的令牌无法单独执行发布——因为根本不存在令牌)。
**一次性设置(所有者):**npmjs.com → package omniroute → Settings → Trusted
Publisher → GitHub:owner diegosouzapw、repo OmniRoute、workflow npm-publish.yml
(environment:none)。在完成该设置之前,自动步骤将以 ENEEDAUTH 失败:
请使用 publish_mode=staged(见下文)或 direct 重新分派。
npm-publish 工作流不再直接发布:它会启动打包后的 tarball
(check:pack-boot),然后运行 npm stage publish——完全相同的字节会被暂存在
注册表中,但在所有者批准之前无法安装。人工 2FA 门禁已移至验证之后,
而非验证之前。
工作流变为绿色后,所有者执行的流程:
npm stage list omniroute——查找暂存 ID(也会显示在工作流摘要中)。- 验证暂存的字节(建议):运行
npm stage download <id>,然后将下载的 tarball 安装到临时前缀中并启动它(npm run check:pack-boot会在 CI 中自动执行 相同的打包→安装→启动判定)。 npm stage approve <id>——2FA 提示本身即为发布操作。npm stage reject <id>会将其丢弃。- 发布后安全网:发布后验证器(v3.8.49 计划中的 WS1.4)会在干净的容器中从 公共注册表安装已发布的版本并启动它。
**紧急后备方案:**通过 workflow_dispatch 并设置 publish_mode=direct,可恢复
旧版的即时 npm publish(仅当暂存功能本身出现异常时使用;需记录原因)。
**一次性加固(所有者,npmjs.com):**为
omniroute 配置仅暂存模式的 Trusted Publisher,使泄露的长期令牌无法从任何位置直接执行
npm publish——CI 只能暂存;只有所有者的 2FA 才能正式发布。
**损坏制品处理手册(未更改):**默认应立即执行
npm deprecate omniroute@<bad> "<reason> — use <fixed>"
(数分钟内生效、可逆);仅可在 72 小时/无依赖项的窗口期内使用 npm unpublish,
且绝不能将其作为首选操作。Docker:切勿重写版本标签——回滚是将
latest 重新指向最后一个正常的摘要。
Docker Hub latest(每次发布稳定 SemVer 版本时均为必需):
docker-publish 工作流必须同时标记 X.Y.Z,并且在
should-promote-latest.sh 确认该版本是最高的稳定 SemVer 时,还必须使用
相同的摘要标记 :latest。作业完成后:Hub 中 latest 的摘要必须等于新的
SemVer 摘要,且 last_updated 已更新。不要让 :latest 继续指向较旧的
构建,而发布说明却在介绍仅存在于 git 中的修复。Compose
快速入门使用 :latest;GitOps 应继续固定到 X.Y.Z。请参阅
Docker 发布通道和 #10317。
带有 hotfix 标签的 PR 会跳过繁重的 CI 矩阵(9 分片 E2E、覆盖率棘轮、
质量门禁、扩展质量检查),并保留快速且高信号的门禁:构建、
单元测试分片、集成测试、vitest、lint/类型检查、文档同步、check:pack-artifact
以及 tarball 启动冒烟测试(check:pack-boot)。目标:在 ≤15 分钟内通过,而不是约 33 分钟。
准入策略——必须同时满足以下四项(参考 Chromium/VS Code/Node 紧急通道):
- 严重程度:生产环境已中断——已发布的制品在启动时崩溃 / 安全修复 / 此版本的所有用户均受影响。“重要”不等于“中断”。
- 权限:只有仓库所有者可以添加
hotfix标签。该标签本身即表示 批准——绝不可在活动 PR 上自行使用。 - 证据:PR 正文须链接到上一次繁重套件完全通过的运行记录(即被跳过的 作业原本会重新验证的套件),以及针对该修复先失败后通过的测试。
- 范围:仅限 cherry-pick——只包含最小修复,不得重构,不得夹带其他更改。
被跳过的覆盖率/棘轮检查范围会由发布分支上的下一次完整运行重新验证
(持续保持发布分支为绿色)——该通道只跳过等待,绝不跳过验证。
仅测试的差异(所有文件均位于 tests/ 下,且均不位于 tests/e2e/ 下)会自动跳过 E2E
矩阵,无需任何标签。
- 此版本对应的所有 PR 均已合并到
release/vX.Y.0 - 此版本所有未关闭的 Linear/issue 项均已关闭或推迟到下一个里程碑
-
release/vX.Y.0分支上的 CI 全部通过 - 代码中不存在
TODO(release)标记:grep -r "TODO(release)" src/ open-sse/ - Docker 基础镜像已更新至最新版本(当前为
node:24.15.0-trixie-slim)
- 运行
/version-bump-cc <patch|minor|major>(Claude Code 技能)- 更新
package.json、electron/package.json中的版本 - 根据自上一个标签以来的 git 提交重新生成
CHANGELOG.md - 更新 README.md 徽章
- 更新
- 手动审查 CHANGELOG.md,并在需要时整理提交消息
- 确保
CHANGELOG.md中最新的 semver 章节与package.json版本一致 - 保留
## [Unreleased]作为变更日志的第一个章节,用于记录即将开展的工作 - 更新
docs/openapi.yaml→info.version必须与package.json版本一致
-
npm run lint— 0 个错误(警告为既有问题) -
npm run typecheck:core— 无问题 -
npm run typecheck:noimplicit:core— 无问题(严格模式) -
npm run check:cycles:ratchet— 不超过冻结的metrics.cycles上限(直接运行check:cycles时,只要存在任何循环依赖就会以状态码 1 退出,#15281) -
npm run check:any-budget:t11— 在预算范围内 -
npm run check:route-validation:t06— 无问题 -
npm run check:node-runtime— 满足受支持的最低运行时要求(>=22.22.2 <23、>=24.0.0 <27,以src/shared/utils/nodeRuntimeSupport.ts中的SUPPORTED_NODE_RANGE为准;与package.json中的engines保持一致)
-
npm run test:unit— 通过 -
npm run test:vitest— 通过(MCP 服务器、autoCombo、缓存) -
npm run test:coverage— 满足 60/60/60/60 门槛(语句/行/函数/分支) -
npm run test:integration— 通过(如果变更涉及 DB / 处理程序) -
npm run test:combo:matrix— 通过(组合策略矩阵:以确定性方式验证全部 19 种公开路由策略的选择决策;修改组合路由、策略解析或回退逻辑时运行) -
RUN_COMBO_LIVE=1 npm run test:combo:live— 可选/手动(受开关控制的真实上游冒烟测试;从 VPSroot@192.168.0.15获取只读 DB 快照;会调用真实提供者并消耗额度;绝不在 CI 中运行;未设置开关时会正常跳过) -
npm run test:combo:live:vps— 可选/手动(第 3 阶段 VPS 实时冒烟测试:使用纯 Node ESM 针对实时.15服务器执行 7 个 HTTP 场景;需要ssh root@192.168.0.15;仅创建/删除__live_test__*组合;会调用真实提供者;绝不在 CI 中运行) -
npm run test:e2e— 通过(UI 变更) -
npm run test:protocols:e2e— 通过(MCP/A2A 变更) -
npm run test:ecosystem— 通过
Husky 钩子位于 .husky/,并会在执行 git 操作时自动运行。
- pre-commit:
npx lint-staged + node scripts/check/check-docs-sync.mjs + npm run check:any-budget:t11 - pre-push: 快速且确定性的门禁检查 —
npm run check:any-budget:t11 && npm run check:tracked-artifacts(于 2026-06-13 启用)。特意排除了test:unit(速度较慢;由 CI 的test-unit作业覆盖)。- 推送发布分支之前,手动运行
npm run test:unit。
- 推送发布分支之前,手动运行
如果钩子失败:修复根本问题,不要使用 --no-verify 绕过。
所有将纳入发布版本的提交都必须遵循 type(scope): subject 格式。
有效类型: feat、fix、refactor、docs、test、chore、perf、style、ci
有效作用域: db、sse、oauth、dashboard、api、cli、docker、ci、mcp、a2a、memory、skills、cloud-agent、guardrails、compression、auto-combo、resilience、providers、executors、translator、domain、authz
破坏性变更:添加 BREAKING CHANGE: 尾注,或在作用域后添加 !(例如 feat(api)!: drop /v0)。
-
npm run check:docs-sync通过(由 pre-commit 自动运行) -
npm run check:docs-all通过(总括检查:docs-sync + docs-counts + env-doc-sync + deprecated-versions + doc-links) -
npm run check:env-doc-sync以状态码 0 退出 — 代码 ↔.env.example↔docs/reference/ENVIRONMENT.md之间的环境变量约定保持完整 -
npm run check:doc-links以状态码 0 退出 — 重构后不存在损坏的内部 markdown 引用 - 已审查
docs/architecture/ARCHITECTURE.md,确认存储/运行时信息没有偏差 - 已审查
docs/guides/TROUBLESHOOTING.md,确认环境变量和运维信息没有偏差 - 如果
.env.example有变更:已更新docs/reference/ENVIRONMENT.md - 如果新功能具有 UI:
docs/guides/USER_GUIDE.md中已提及该功能 - 如果新功能具有 API:已更新
docs/reference/API_REFERENCE.md+docs/openapi.yaml - 如果新功能是一个模块:存在专用的
docs/<MODULE>.md - 如果存在破坏性变更:
docs/guides/TROUBLESHOOTING.md中包含迁移说明
-
npm run i18n:check以状态码 0 退出 — 翻译状态(.i18n-state.json)与源文档同步(严格模式下不存在发生偏差的源文档;对于最后时刻的文档微调,警告模式的提示可以接受,但在创建标签前应为 0) -
npm run i18n:check-ui-coverage以状态码 0 退出 — 每个 UI 语言区域均达到或超过 80% 的覆盖率下限 -
npm run i18n:sync-ui:dry报告全部 66 个目标语言区域中缺失的键数量为 0(除源语言en之外的每个语言区域) - 如果英文源文档有变更,请在创建标签前运行
npm run i18n:run(需要在.env中配置OMNIROUTE_TRANSLATION_API_KEY) - 如果翻译贡献较少,可以推迟到下一个版本(在 CHANGELOG 中跟踪)
- 如果
src/lib/db/migrations/中存在新文件:- 每个迁移都是幂等的(
CREATE TABLE IF NOT EXISTS等) - 迁移已封装在事务中
- 编号正确(序列中不存在空缺)
- 每个迁移都是幂等的(
- 在全新安装上测试:删除
~/.omniroute/omniroute.db并运行npm run dev - 在现有安装上测试:备份 DB、运行迁移并验证架构
- 如果迁移会重写表,确保正确处理 WAL 文件(
-wal、-shm)
-
src/shared/constants/providers.ts的 Zod schema 在加载时有效- 所有提供者都包含必填字段(
id、label、kind等) - 为新的免费提供者提供了
freeNote - OAuth 提供者已在
src/lib/oauth/constants/oauth.ts中注册oauthConfig
- 所有提供者都包含必填字段(
- 如果添加了新提供者:在
open-sse/executors/中有对应的执行器 - 如果不是 OpenAI 格式:在
open-sse/translator/中有对应的转换器 - 模型已在
open-sse/config/providerRegistry.ts中注册 -
tests/unit/中的单元测试覆盖提供者分类和路由
如果更改了 electron/:
-
npm run electron:smoke:packaged通过 - 至少测试了
:win、:mac、:linux中的一种构建 - 代码签名证书未过期(如果进行签名)
-
electron/package.json的版本与根目录下的package.json一致 - 如果发布到
stable,已更新自动更新渠道指针
仓库使用三个不同的输出目录——切勿混淆:
| 目录 | 用途 | 是否跟踪 |
|---|---|---|
src/ |
应用程序源代码(TypeScript / TSX) | 是 |
.build/ |
构建中间产物——next build 输出(distDir) |
否(已被 git 忽略) |
dist/ |
可发布的 npm 包——由 assembleStandalone 组装 |
否(已被 git 忽略) |
运维人员注意:远程 VPS 的镜像目录仍为
/usr/lib/node_modules/omniroute/app/。 只有仓库内的构建输出发生了移动(app/→dist/)。部署技能会通过 rsync 将dist/的内容同步到远程app/目录——无需更改 VPS 路径。
单次构建流程:
npm run build:release
└─ rm -rf .build dist (清理)
└─ next build → .build/next/ (中间产物)
└─ assembleStandalone (将 standalone + static + public + natives 复制到 dist/)
└─ writes dist/BUILD_SHA (HEAD 哨兵)
部署时不要先运行 npm run build,再单独运行 npm run build:cli——请使用
npm run build:release,它会通过一条命令完成全新重建并生成哨兵文件。
-
npm run build:release成功,并且dist/BUILD_SHA==git rev-parse --short HEAD -
npm run check:pack-artifact检查干净——没有app.__qa_backup、scripts/scratch、package-lock.json或其他本地残留文件 - 构建后存在
dist/server.js - 可选的本地打包运行时冒烟测试:在运行
npm run dev:candidate -- build后执行npm run dev:candidate -- validate,使用隔离的DATA_DIR启动已打包的 tarball,并检查/api/health+/v1/models(参见贡献黄金路径)
- 运行
/generate-release-cc(Claude Code 技能):- 创建标签
vX.Y.Z - 推送标签和分支
- 创建包含变更日志正文的 GitHub Release
- 附加 Electron 安装程序(如果已构建)
- 创建标签
- 或手动执行:
git tag -a vX.Y.Z -m "Release vX.Y.Z" git push origin vX.Y.Z gh release create vX.Y.Z --notes-from-tag
部署技能使用轻量级 rsync 流程——不使用 npm pack,也不使用 npm i -g:
- 使用与目标匹配的部署技能:
/deploy-vps-local-cc——本地 VPS(192.168.0.15)/deploy-vps-akamai-cc——Akamai VPS(69.164.221.35)/deploy-vps-both-cc——两者
- 部署前,确认
dist/BUILD_SHA==git rev-parse --short HEAD - 必须在具有真实
node_modules的位置运行构建(主检出目录或已执行npm ci的 worktree——不能是使用符号链接的 worktree) - 对已部署的实例进行冒烟测试:
- 打开
/dashboard/health→ 检查版本字符串是否与发布版本一致 - 使用已知提供者发送
/v1/chat/completions请求 - 验证
/api/monitoring/health返回状态为CLOSED的断路器 - 确认 MCP 传输正常响应(
/mcpHTTP、/mcp-sseSSE)
- 打开
- 运行
/capture-release-evidences-cc(Claude Code 技能)- 捕获新功能的 WebP 截图/录屏
- 附加到发布说明/博客文章
- 在 GitHub Discussions / Discord 中发布公告
- 为下一个版本创建里程碑
- 如果属于关键更新:置顶讨论,或发布到
news.json以显示应用内横幅
Radar 公告特意以 active: false 的状态提交。只有在以下各项均有证据支持后,
才能通过单独的更改将其激活:
- 所有堆叠的 Radar PR 均已合并,并且发布分支顶端的 CI 为绿色
- 在
RADAR_ENABLED默认仍处于关闭状态时,部署并对 OSS Radar 路由执行冒烟测试 - 在指定的 Radar 主机上对
GET /planos、/termos、/privacidade和/reembolso执行冒烟测试 - 在私有服务中记录运维人员身份/联系方式/地址,以及经所有者批准的法律审查
- 仅在测试模式下测试 Stripe Checkout 和已签名的 webhook
- 使用已批准的发件人/域名测试一次加密的事务性电子邮件投递
- 验证备份恢复,并执行一次有人监督且设置预算上限的研究运行
- 在接受捐赠凭证之前批准 BRL/PIX 审核政策
- 仅在通过上述门槛后启用公开 Checkout,然后激活新的
news.jsonID - 验证 Home 横幅使用本地化文案,并且在关闭旧 ID 后,新 ID 会重新出现
在发布任何包含嵌入式服务变更的版本之前,请验证:
-
DATA_DIR=$(mktemp -d) npm start &— 等待 10 秒以完成启动 -
curl -s http://127.0.0.1:20128/api/services/9router/status | jq '.tool'返回"9router"(不能是 404,也不能是 500)。确认迁移071_services.sql已应用且初始行已写入。 -
sqlite3 $DATA_DIR/storage.sqlite "PRAGMA table_info(version_manager);" | grep -E "provider_expose|logs_buffer_path|last_sync_at"返回 3 行。 -
sqlite3 $DATA_DIR/storage.sqlite "PRAGMA table_info(webhooks);" | grep -E "kind|metadata_encrypted"返回 2 行(验证070_webhooks_kind_metadata.sql已应用)。 -
node --import tsx/esm --test tests/unit/db/no-migration-collisions.test.ts通过 — 防止未来出现冲突。
-
POST /api/services/9router/install在 2 分钟内返回 200,并包含installedVersion -
POST /api/services/9router/start在 30 秒内返回 200 和state: "running" -
GET /api/services/9router/status报告health: "healthy" - 使用
"model": "9router/auto/..."调用POST /v1/chat/completions返回 200(通过 9Router 进行端到端路由) -
GET /dashboard/providers/services/9router/embed/dashboard在代理内呈现 9Router 原生 UI(不使用直接指向127.0.0.1:port的 iframe) -
POST /api/services/9router/rotate-key返回{ keyRotated: true },且服务干净重启 -
POST /api/services/9router/stop返回 200 和state: "stopped" -
GET /api/services/9router/logs?tail=50返回 SSE 流,其中包含带有近期日志行的snapshot事件 - 在 PATH 中没有
npm的环境里安装时,返回 500 和友好的错误消息(不包含堆栈跟踪)
-
POST /api/services/cliproxy/install在 2 分钟内返回 200 -
POST /api/services/cliproxy/start在 30 秒内返回 200 和state: "running" -
GET /api/services/cliproxy/status报告health: "healthy" -
POST /api/services/cliproxy/stop返回 200 和state: "stopped" -
GET /api/services/cliproxy/logs?tail=50返回 SSE 流
-
curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:20128/api/services/9router/start返回403 LOCAL_ONLY -
curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:20128/api/services/cliproxy/start返回403 LOCAL_ONLY - 来自
/api/services/*的错误响应不包含err.stack或绝对文件路径
在发布任何 v3.8.x 版本之前,请验证以下附加项目:
-
omniroute --tray可在 macOS 上启动(systray2 已安装到~/.omniroute/runtime/) -
omniroute --tray可在 Linux 上启动(需要 DISPLAY;若未设置,应给出友好错误) -
omniroute --tray可在 Windows 上启动(使用 PowerShell NotifyIcon,无额外二进制文件) -
omniroute config tray enable创建自动启动项;禁用时会将其移除 -
npm install -g omniroute@<this-version>执行 postinstall 时不会发生致命退出 - 更新路径会保留可选依赖项:
omniroute update --apply和自动更新程序 运行npm install -g … --include=optional,以确保optionalDependencies(better-sqlite3、 keytar、tls-client,以及 llmlingua SLM 栈:@atjsh/llmlingua-2@2.0.5、js-tiktoken)在更新后仍然存在。ultramodelPathSLM 层还需要 tinybert 模型,该模型会在首次使用时自动下载到${DATA_DIR}/models/llmlingua。随后,Postinstall (scripts/build/colocateOptionals.mjs) 会将 SLM 可选依赖闭包集中放置到dist/node_modules中,使 worker 解析到唯一的@huggingface/transformers^4.2.0 实例 — 独立 trace 仅捆绑 transformers,不包含动态导入的 可选依赖项;若不这样做,worker 会使用根目录的 transformers 加载 llmlingua-2, 并且 SLM 层会静默地进入故障开放状态。 -
omniroute status在没有.env时仍可工作(CLI 令牌路径,仅限环回地址) -
curl http://localhost:20128/api/shutdown返回 401(始终受保护的路由) -
curl -H "host: evil.com" http://localhost:20128/api/mcp/sse返回 401(环回保护) - SQLite 运行时在首次运行时解析为
bundled(捆绑的二进制文件对当前平台有效) - 删除
node_modules/better-sqlite3时,SQLite 运行时回退到runtime - 智能 MCP 过滤器可压缩真实的
playwright-mcp browser_snapshot输出(缩减幅度 ≥50%) - 所有 10 个
skills/omniroute*/SKILL.md文件均可通过 GitHub 原始内容 URL 公开获取 - 在全新设置中,入门向导显示“How It Works”层级导览步骤
- 主页仪表板的层级覆盖率组件显示已配置/已激活数量
v3.8.59 之后的下一个版本是 3.9.0,其顶端提交将分化为两个长期维护分支:
stable/v3(v3 LTS 版本线,npm latest)和 develop(v4,版本提升至 4.0.0,npm
nightly)。分支/渠道模型、前向移植和标签请参阅
RELEASE_STRATEGY.md;计划请参阅 ROADMAP(阶段 3)。切分仅执行一次;
3.8.58 会在 fork 上进行端到端演练,而 3.8.59 则以
GO/NO-GO 检查清单收尾。
npm run release:dry-run-lts-cut # 实际切分:从 HEAD 创建 3.9.0,前一个标签为 v3.8.59
npm run release:dry-run-lts-cut -- --from <3.9.0-tip> # 固定源提交scripts/release/dry-run-lts-cut.mjs 不执行任何操作:它读取 git 和 gh,并输出
完整流程——前置条件(源可解析;源仓库具有完整历史记录——
浅克隆无法推送 stable/v3,接收端会在遇到第一个嫁接的父提交时拒绝该 pack,
因此请从完整克隆执行切分,或先执行 git fetch --unshallow origin——前一个
标签存在;package.json 为目标版本;存在一个打开的 release-freeze issue;现有
发布分支上没有打开的 Release branch not green issue——不存在的分支会报告
?(未知),绝不会报告为绿色——Mergify release 队列已配置(G11:queue_rules、
checks_timeout、标签 queue);release/* 规则集仍会阻止删除和强制推送;并且
stable/v3 和 develop 尚不存在)、两个分支步骤、哪些休眠工作流的触发器和
if: 条件会变为 true(以及哪些仍受仓库变量限制或固定到规范仓库)、预期的
dist-tags(latest → 3.9.0,next 和 nightly 为空)以及回滚流程。退出码 0 =
RESULT: READY,1 = 某项阻塞性前置条件失败(✗),2 = 用法错误。
--advisory <id,...> 会将某项检查降级为警告(!),但不会隐藏它。
请在 3.9.0 发布冻结仍处于开启状态时执行实际切分的试运行——分支会在创建标签之后、 阶段 12c 解除冻结之前创建。
# 1. 使用演练参数在当前顶端提交上进行试运行
npm run release:dry-run-lts-cut -- --target-version 3.8.58 --previous-tag v3.8.57 \
--advisory freeze,base-green
# 2. 针对 FORK 远程仓库执行(会拒绝 origin 或 URL 为规范仓库的任何远程仓库;
# 每个步骤都会在终端中请求确认)
git remote add rehearsal https://github.com/<you>/OmniRoute.git
node scripts/release/dry-run-lts-cut.mjs --execute --remote rehearsal \
--target-version 3.8.58 --previous-tag v3.8.57 --advisory freeze,base-green
# 3. 在 fork 中运行休眠工作流(如果试运行报告固定到了规范仓库,
# 则使用 workflow_dispatch),然后回滚
node scripts/release/dry-run-lts-cut.mjs --execute --rollback --remote rehearsal \
--target-version 3.8.58 --previous-tag v3.8.57 --advisory freeze,base-greendevelop 版本提升提交通过 git 底层命令构建(不会触及工作树),并会更新与周期开启提交
相同的五个文件:package.json、open-sse/package.json、
electron/package.json、package-lock.json 和 docs/openapi.yaml。随后会在
develop 上开启 [4.0.0] CHANGELOG 章节及其 i18n 镜像,并在该分支的第一个
PR 之前完成。该脚本绝不会更改 npm dist-tags——请在临时软件包上演练这些操作。
.github/workflows/preview-artifact.yml 从 PR 头部提交构建一个生产 tarball,并
验证该确切构建(#8084 切片 (a))。仅支持同一仓库内的 PR;不会发布任何内容。
gh workflow run preview-artifact.yml -f pr_number=<N> # 或添加 `preview-artifact` 标签
gh run download <run-id> --name preview-artifact-pr<N>-<sha7> --dir preview
cd preview && sha256sum -c SHA256SUMS
gh attestation verify omniroute-*.tgz --repo diegosouzapw/OmniRoute
npm install -g ./omniroute-*.tgz # 安装预览版本该运行会执行 npm ci、npm run build:release、npm run check:pack-artifact,
打包 tarball,运行 npm run check:pack-boot(使用伪造的密钥和临时数据目录),
再次打包;除非摘要完全相同,否则运行失败。随后记录 artifact-identity.json
(头部 SHA、基准 SHA、锁文件哈希、平台、架构、node ABI、打包器、构建策略——
scripts/release/artifact-identity.mjs),并在单独的作业中证明该 tarball。
推广预览版本意味着安装该 tarball:绝不要从源代码重新构建。
-
GO 已记录在 LTS_GO_NO_GO.md 中。
-
npm run release:dry-run-lts-cut -- --from v3.9.0输出RESULT: READY。 -
使用试运行输出的命令,手动在
origin上创建分支——该脚本拒绝推送到origin。若要复用已审核的 develop 提交,请先在 3.9.0 顶端提交上,针对你的 fork 执行--execute演练;它会输出两个 SHA,随后可以推送相同的提交:git push origin <stable-sha>:refs/heads/stable/v3 <develop-sha>:refs/heads/develop
-
在第一个 PR 合并之前,保护
stable/v3和develop(规则集 + 合并队列)。 -
休眠的工作流会根据分支是否存在而启用:
forward-port.yml(推送到stable/v3)、validate-stable-pr.yml(以stable/v3为目标分支的 PR)和nightly-v4-build.yml(构建develop)。正式启用前,请设置仓库密钥secrets.FORWARD_PORT_TOKEN(以便 CI 在 前向移植 PR 上运行);在所有者将仓库变量vars.NIGHTLY_PUBLISH设置为true,且 npm 可信发布接受nightly-v4-build.yml之前,夜间发布将保持关闭。渠道解析由scripts/release/dist-tag.mjs负责,即npm-publish.yml使用的同一解析器。 -
验证渠道:
npm view omniroute dist-tags --json应显示latest= 3.9.0,且在 v4 发布之前不存在next/nightly。 -
如有需要,可执行回滚:
git push origin --delete refs/heads/stable/v3 refs/heads/develop和npm dist-tag add omniroute@3.8.59 latest。
如果发布存在严重问题:
gh release edit vX.Y.Z --prerelease(标记为非最新版本)git tag -d vX.Y.Z && git push --delete origin vX.Y.Z(仅当用户尚未采用该版本时)- 或者:在
release/vX.Y.0上进行热修复 → 发布补丁版本vX.Y.(Z+1) - 立即在 GitHub Discussions 和 Discord 中发布通知
- 绝不直接提交到
main - 绝不对
main或release/*分支使用git push --force - 绝不跳过 Husky 钩子(
--no-verify) - 绝不提交密钥、凭据或
.env文件 - 覆盖率必须保持在 ≥60/60/60/60(语句/行/函数/分支)
- 修改
src/、open-sse/、electron/或bin/中的生产代码时,始终包含或更新测试
在创建 PR 之前,先在本地运行文档同步保护检查:
npm run check:docs-syncCI 也会在 .github/workflows/ci.yml 中运行此检查(lint 作业)。