跳转到主要内容
你在状态页上把一次发版规划成一个版本,等它的工作做完再开始发版;之后 Orbi 按确定的流程把它发出去。 你在状态页或 GitHub 决定版本并发起发布任务。之后 Orbi 核验范围和检查,按需更新指定版本文件,发布 tag 与 GitHub Release,再关闭 milestone。引擎的里程碑推进流程也可以在版本决策确认后创建发布任务,不会替你决定版本号。 发版不是一次开发交付。没有模型会话,也没有 pull request,它跑的是一个固定的状态机。

状态页上的版本

所有套餐都能使用版本。单项目时在状态页展开「用量与设置」→「版本」;多个项目时先进入该项目详情。版本管理和发版入口不会增加免费交付次数,也不会解除套餐额度。发版仍由你发起。 免费次数用完后,仍可新建版本和 Release 任务,但新的 Release 任务不能开始。订阅后在该 Issue 上重新加 ai-ready 才会派发。发版本身没有 PR,不计入前 3 次成功合并的交付;开始时仍需要可用名额。 一个版本就是一个标题为版本号的 GitHub milestone,比如 v1.2.3。这一块显示:
  • 「当前版本:」Orbi 正在朝哪个版本做,或者「未设置(做所有已交给 Orbi 的任务)」。「在 GitHub 查看」打开这个 milestone;没设置时打开你仓库的 milestone 列表。
  • 「未发布的版本」:你开着的版本 milestone,以及各自「未关闭的 Issue」的数量。其他版本提供「切换到这个版本」。当前那个版本标着「当前版本」,提供「创建 Release 任务」,建好之后换成「查看 Release 任务」。一个开着的 milestone 都没有时显示「暂无开放版本」。
  • 「新建版本」:填一个版本号,点「新建并切换」。
  • 「说明」:折叠起来的一段按钮说明。

当前版本

开放的「当前版本」限定新认领的 ai-ready Issue,只做这个 milestone 里的票;其他票等待,页面可提供「移到版本」或「切换到版本」。当前 milestone 已关闭且没有更新的开放 milestone 时,新认领不按里程碑过滤,配置值仍保留。有更新的开放 milestone 时,自动推进还是开版本确认票,由仓库的 auto_next_milestone 决定。已有交付的接续不受新票认领范围限制。 没有设置当前版本时,所有 ai-ready Issue 都可以被认领。用 Orbi 完全可以不用版本,只有当你想分批发布时它才有意义。 版本号必须是开头一个 v、后面跟点号分隔的数字,比如 v1.2.3;其他形状会在 GitHub 上发生任何改动之前就被拒绝。

发一个版本

一个版本的工作都进去了之后,如果它还不是当前版本,先点「切换到这个版本」,再在它那一行点「创建 Release 任务」。 Orbi 会开出 Release Issue。同一个 milestone 还有其他开放 Issue 时,发布票保持 ai-ready 排队,等它们关闭;排队本身没有时间上限。范围就绪后,Orbi 执行发布,按需更新版本文件,打 tag,发布 GitHub Release 并关闭发布票。版本文件更新后,网站何时变化仍由你的发布或部署方式决定。

milestone 是必需的

发版的 scope 来自标题与版本号完全一致的那个 milestone,所以 v1.2.3 需要一个叫 v1.2.3 的 milestone。「新建并切换」和「创建 Release 任务」在 milestone 不存在时都会替你建好;如果你手写 Release Issue,要自己确认 milestone 存在。 如果发版因为缺 milestone 停下,状态页上那张受阻的 Issue 会提供「创建版本并继续」。

创建 Release 任务或切换版本报错时

版本文件

Orbi 会探测你的项目用什么声明版本号,按这个顺序找: pyproject.toml、package.json、pom.xml、build.gradle、build.gradle.kts、gradle.properties、Cargo.toml、composer.json、pubspec.yaml 一个都没有时,从状态页发起的发版只打 tag:不修改版本文件,只生成 tag 和 GitHub Release。读不出仓库目录是需要重试的错误;成功读取后确实没有支持的版本文件,则是正常的 tag-only 结果。状态页会记住对这个仓库的探测结果,以后才加的版本文件不会被重新探测到,这时请按下面的方法手写 Release Issue,写上 - version_file:。

自己手写 Release Issue

按钮只是个便利入口。你也可以手动建这张 Release Issue:打上 ai-ready 和 ai-release,并把它放进标题就是版本号的 milestone,例如 v1.2.3。Orbi 会从这个 milestone 取版本号和范围,从仓库配置取基础分支,并按上面的顺序找版本文件;一个都找不到时,发版会停下,请你补上可选的 ## Release 段,写 - version_file: none(只打 tag)或要用的文件。 这一段可选,用来显式写明各字段:
写了这一段就会严格解析:version 和 base_branch 必填,字段重复或出现未知字段会立即失败,version 必须和 milestone 标题一致,scope_from_milestone 和 scope 必须恰好写一个。要逐条列出范围,写 - scope:,下面每项一行 - #N。这一段里不写 version_file 时,按 pyproject.toml 处理。

打 tag 之前 Orbi 检查什么

门禁按顺序执行,查不了的门禁算没过。 先冻结起始 base:发布从基础分支的一个确定提交开始。需要改版本号时,会生成要发布的版本提交;检查和 tag 必须对应实际发布的那个提交。 先检查 milestone,再认领发布票:有其他开放 Issue 就继续排队。认领后出现同 milestone 的 ai-in-progress、ai-pr-opened 或 ai-fix-needed 交付时,执行中的门禁才等待这些任务,默认上限 30 分钟。单独的 ai-ready 不属于这层等待。仅有开放 PR 本身不构成发布门禁。 发版 commit 上的 CI 必须是绿的。 这就是测试验收,也是这里最值得搞明白的一条: 仓库上报的检查决定有哪些自动验收证据。从未观察到 CI 时,发布可以带着无检查证据通过,但这不证明测试通过。基础分支已有 CI 时,新推送的版本提交暂时没有检查,需要等检查注册;待完成或失败的检查不会当作通过。 pending 的 check 不算失败:门禁会等最终结论,默认最多等 30 分钟,等待期间持续上报进度。等待超时会如实报成超时,绝不会伪装成 CI 失败。 scope 逐条实时核验。 每一条要么是已合并的 PR,要么是以 completed 关闭的 Issue。Issue 正文里的勾选框完全不看,核验走 GitHub API。以 not planned 关闭的 Issue 会被记为排除,不进 changelog。

产出什么

  • 在发版 commit 上创建一个带注释的 tag,用普通 push 推上去,永远不用 --force。已有 tag 不会移动;真正的 tag 冲突会让发布停下。恢复发布时,可以沿用已经位于基础分支历史中的既有 tag 提交。
  • 发布一个 GitHub Release,release notes 里带完整证据:版本号、tag、发版 commit、逐条 scope 证据、门禁证据和测试证据。
  • 关闭 milestone。
每一步都是幂等的。发版失败后停在 ai-blocked,不会自动重试;修掉原因后把 ai-blocked 换成 ai-ready,它会接着跑,而不是从头来。

发版失败时

CI 红了或超时会走正常的失败路径,Issue 被标记 ai-blocked 并写明原因。 这时版本号的 bump 可能已经落在你的基础分支上了,这是可接受的状态:bump 是幂等的,修好 CI 重跑一次会安全地把同一个版本再准备一遍。

为什么发版保持手动

版本和发布策略由你决定。可以在页面手动发起,或建带 ai-ready 与 ai-release 的 Issue;也可以在确认版本后,按已启用的里程碑流程创建发布任务。发布状态机负责检查和发布,不会独立决定产品范围。
发版状态机属于引擎,不属于 Cloud。它的完整参考,包括每一道门禁、接续行为和写下的证据,在 docs.orbi.build/zh/workflow。