跳到正文

发布流程

Verso 会先计算一份准确的文件计划,再记录一系列明确的本地阶段和最后一次远端事务。持久化计划让中断的 发布可以检查和恢复,无需重新计算原本要写入的内容。

写入之前

Verso 会加载一个发布组配置、发现成员、确认成员版本一致、确定一个目标版本,并计算每个文件实际的 before 和 after 内容。完整发布还会计算 changelog、commit message、tag、hook 和原子推送;bump 计划 只包含版本文件修改和版本 hook。

Shell
verso --version 2.0.0 --dry-runverso bump minor --dry-run

Dry-run 会输出这份准确计划,包括完整文件的 before/after diff,但不会写文件、运行 hook、创建事务日志 或执行会修改 Git 的命令。

使用命名发布组时,再添加 --group core。

真实执行时,Verso 会检查工作区策略和计划路径、拒绝已有目标 tag,并获取仓库事务锁。每个 Git 仓库 同时只能有一个 Verso 事务。

持久化阶段

第一次文件修改确认后,Verso 会把计划和进度存入 Git metadata,并用原子文件替换写入。完整发布阶段为:

text
planned  -> before_version -> 应用准确文件 -> files-applied -> after_version  -> before_commit -> git add/commit -> committed -> after_commit  -> before_tag -> annotated tag -> tagged -> after_tag  -> before_push -> git push --atomic -> pushed -> after_push  -> 清除事务

verso bump 只经过 planned -> files-applied,运行 before_version 和 after_version 后清除事务。它不会 修改 changelog、暂存文件、创建 commit 或 tag,也不会 push。

完整发布在文件、commit、tag 和 push 之前的确认默认都是“是”。目标版本不大于当前版本时,会更早出现 一个默认“否”的确认。--yes 会接受所有确认。

Status、resume 与 abort

Push 开始前,如果手工回滚已将 HEAD 和全部计划文件恢复到发布前状态,删除了发布 tag,且工作区和 索引都 clean,abort 会直接清除日志,无需连接远端。仅有工作区 clean 并不足以证明已撤回发布。

Shell
verso status [--json]verso resume [--retry-hook | --skip-hook]verso abort [--force]

status 是只读命令,会输出操作、发布组、阶段、版本对、修改文件数、中断的 hook,以及当前是否仍可 abort。

resume 会先用准确文件内容、HEAD 和 tag 对事务日志进行校准,跳过已完成的 hook 和确认,再从记录的 阶段继续。进程停止时正在运行的 hook 结果未知;应先检查副作用,再明确使用 --retry-hook 或 --skip-hook。

有事务时再次执行会修改仓库的 release 或 bump,Verso 会显示其发布组、版本对和阶段,再提示 resume 或 abort。恢复操作会结束本次调用,不会接着开始用户刚请求的新发布。

abort 很保守:只通过 compare-and-delete 删除 Verso 创建的准确 tag object,只对预期 release commit 做 soft reset,只取消计划路径的暂存,并且只在文件仍等于计划 after 内容时恢复。遇到意外 HEAD、移动 过的 tag 或后来编辑的文件时,它会拒绝覆盖无关工作。release commit 创建后,abort 还会检查固定远端; 若目标 tag 不属于事务,或 branch 已包含 release commit,则拒绝自动回滚。

即使 push 开始后本地 HEAD 前进,resume 仍会使用事务开始时持久化的 push URL、commit 和 tag。

错误与取消行为

推送前可明确处理的文件、hook、commit 和 tag 错误会触发 best-effort 本地 abort。release hook 失败时 会先检查固定远端;若无法检查,Verso 会保留事务,而不会假设 hook 没有发布。进程崩溃、用户在后续确认 中取消或状态不明确时会保留事务日志;push 尚未开始时可选择 resume 或 abort。push 失败只允许 resume。

停止位置持久化状态与下一步
第一次文件确认之前没有事务,也没有文件修改
已写文件 / commit 之前文件保持未暂存;resume 会提交,abort 会恢复
已有 commit / tag 之前保留预期 release commit;resume 会加 tag,abort 会 soft reset 并恢复
已有 tag / push 之前保留本地 commit 和 tag;resume 会推送,abort 会删除预期的本地修改
原子推送失败保留本地 commit、tag 和日志;修复或检查远端后 resume
推送成功 / after_push 失败保留本地和远端 ref;只允许 resume

清理绝不会使用 hard reset。恢复、取消暂存、reset、删除 tag、日志或远端验证错误都会明确报告,而不会被隐藏。

Hook 与 CI 交接

Hook 是任意项目 shell 命令。Dry-run 会输出名称和命令,但不会执行。Secret 应通过环境传入,不要存进 配置;hook 应当可以安全重试;破坏性操作或需要凭据的发布行为应优先放在 CI。after_push 是后续处理 边界:可以 resume,但无法撤销远端 ref。hook 中断后,应先确认旧进程已经停止,再重试、跳过或 abort 事务。

Registry 发布、GitHub Release、二进制构建和部署仍应交给 tag 触发的 CI。

开启自动化前,在目标仓库保留下面两项检查结果:

Shell
verso doctor --jsonverso --version <next-version> --dry-run --json

自动化命名发布组时,请给两条命令都添加 --group <NAME>。

原子推送细节

查看 Verso 推送的准确 ref

Verso 会解析当前分支配置的 remote 和 merge ref,只推送下面两个 ref:

text
<release-commit-oid>:refs/heads/<upstream-branch><tag-object-oid>:refs/tags/<release-tag>

命令使用 git push --atomic,不会包含其他本地 tag。远端必须支持原子推送,因此会同时接受两个 ref 或 全部拒绝。

Copyright © 2026 白熱.