状态页上的版本
所有套餐都能使用版本。单项目时在状态页展开「用量与设置」→「版本」;多个项目时先进入该项目详情。版本管理和发版入口不会增加免费交付次数,也不会解除套餐额度。发版仍由你发起。 免费次数用完后,仍可新建版本和 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。