尧图精选

Beads v1.2.2 恢复性发布(Recovery Release)门禁全解析:从意外发布到 schema 偏移防护的工程实践

🕒 发布时间:2026/9/13 3:50:57 📁 来源:尧图网络
Beads v1.2.2 恢复性发布Recovery Release门禁全解析从意外发布到 schema 偏移防护的工程实践【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads本文基于 Beads 仓库的发布门禁记录 release-gates/v1.2.2-recovery-release-gate.md 展开复盘一次真实发生的意外发布事故及其恢复方案v1.2.0/v1.2.1 未经发布测试被意外发布v1.2.2 通过重发已测试的 1.1 版本线re-releasing the tested 1.1 line完成恢复。读者可以从中掌握恢复性发布的完整门禁矩阵、schema 前向偏移forward skew的防护与逃生机制、go.modretract 的发布治理用法以及针对已污染数据库的游标回滚恢复操作。事故背景一次未经测试的意外发布2026-08-11Beads 的v1.2.0与v1.2.1两个版本在未经发布测试的情况下被意外发布。其中v1.2.0的 tag 在发布前即被烧毁burned tag从未真正发布真正进入用户手中的是v1.2.1。问题在于只要运行过一次v1.2.1二进制任何命令包括bd list本地数据库 schema 就会被自动从 v53 迁移到 v65而这一迁移行为发生在未经任何 release testing 的代码上风险不可控。面对这一局面v1.2.2 采用了经典的恢复性发布recovery release策略v1.2.2 经过测试的v1.1.2代码树 事故感知的 schema 偏移提示消息incident-aware skew message 恢复指南文档docs/RECOVERY-1.2.1.mdgo.modretract 声明 发布验证工具release-verification tooling。关键信息记录如下均来自 release-gates/v1.2.2-recovery-release-gate.md日期2026-08-15Tagv1.2.26c124203e位于release/v1.2.2分支4 个内容提交 rc/晋升版本号提交叠加在v1.1.2之上不是从 main 切出ReviewPR #5773对比基线固定在v1.1.2的分支2026-08-15 通过RCv1.2.2-rc.1bb6be669f完整 pipeline 试运行绿灯判定VerdictPASS需要特别注意的是1.2.x 专属功能不在 v1.2.2 中。根据 docs/recovery/accidental-1-2-1-release.md 的说明work leases工作租约、events journal事件日志、sync federation同步联邦、HTTP API server、provenance events溯源事件等 1.2.x 特性都不会出现在这次恢复性发布里它们将在后续经过完整测试的版本中回归。v1.2.2 的唯一使命是让所有安装渠道Homebrew、npm、安装脚本、go install都前进到经过测试的代码上。Pre-tag 门禁矩阵发布前的 7 道验证关卡在release/v1.2.2分支上宿主为 linux dev box发布前依次通过了以下门禁完整结果表GateResultscripts/test.sh全量测试套件PASS— 63 个包通过cmd/bd249s和internal/doltserver360s超过本地 3 分钟默认超时但在 CI 规范的-timeout30m下通过npm run test:allPASS针对候选二进制的单元测试test:integration按设计在发布前不可运行postinstall 会拉取版本化 release 资产——由 pipeline 的 npm 门禁与发布后冒烟覆盖稳定性门禁upgrade-smoke-test.shPASS— 覆盖v1.1.2 → candidate与v1.1.0 → candidate全部场景。无参默认解析到 v1.2.0已烧毁的 tag无二进制。v1.2.1 →这条腿被故意拒绝前向偏移证据见后文验证腿 L4–L8make test-regression基线 v0.49.6PASS183 个测试896smake ci-package-mcp/ci-package-npm/ci-website本地PASS / PASS / PASSscripts/release-verification-1.2.2.sh配合 v1.2.1 二进制PASS— 21/21 项检查全部通过详见下文check-versions.sh严格 tag 模拟PASSvendorHash检查后无变化go.mod 的增量仅为 retractgo.sum 未动门禁宿主上无 nix深入upgrade-smoke-test.sh 的六类冒烟场景稳定性门禁 scripts/upgrade-smoke-test.sh 是这一矩阵中与升级路径关系最密切的一环其脚本头部注释明确列出了验证目标升级后 issue 数据保留、存储模式保持embedded 不切 shared、角色配置beads.rolegit config不被清除或改变、bd doctor quick通过、升级后的bd update变更正确持久化。脚本按场景逐步执行源码中的scenario/pass/fail/finish_scenario辅助函数组织Embedded maintainer 升级用旧版二进制init→create写入升级前 issue → 用候选二进制升级 → 校验beads.role保持为maintainer、旧 issue 在升级后仍可见、bd doctor quick通过。Contributor 升级校验beads.role保持为contributor。存储模式保持embedded init 后升级必须仍然存在 embedded DB.beads/embeddeddolt目录或遗留beads.db且config get storage.mode不得切到 shared-server。非交互 init 后角色必须已设置beads.role不得为 MISSING。升级后变更mutation持久化旧版建 issue → 升级 → 候选二进制bd update --notes→bd show读回验证 notes 持久化。依赖阻塞路径在升级后存活这条专门针对依赖拆分迁移0035、0041–0045、0047用旧版二进制写入依赖行旧 schema升级后执行bd ready、bd blocked、bd close三条关键路径验证数据复制data-copy没有把depends_on_issue_id弄丢且关闭 blocker 后依赖方正确解除阻塞is_blocked重算。从源码结构看该脚本支持多版本批量模式SMOKE_VERSIONSv0.62.0 v0.61.0 ./scripts/upgrade-smoke-test.sh会逐版本执行也支持CANDIDATE_BIN./bd指定预构建候选二进制旧版本二进制则从 release 资产下载并缓存到~/.cache/beads-regression/。这解释了门禁表中无参默认解析到 v1.2.0的由来脚本通过git tag --sort-version:refname取当前版本之前的最近 tag而 v1.2.0 是烧毁 tag、无对应二进制因此该腿被有意绕过。深入release-verification-1.2.2.sh 的 21 项检查scripts/release-verification-1.2.2.sh是专为本次事故编写的发布验证脚本驻留在 release 分支/tag 上且可随时重跑。门禁记录显示其 21/21 全部通过覆盖的核心验证腿包括整理自 release-gates/v1.2.2-recovery-release-gate.mdv53 schema 往返round-trip验证v1.2.1 二进制可以把数据库迁移到 v65复现事故状态候选 v1.2.2 二进制在 v65 数据库上拒绝启动并给出事故提示消息杜绝latest循环用户go install latest不会又装回坏的 v1.2.1BD_IGNORE_SCHEMA_SKEW1下读取逐字节一致、写入也能落盘恢复手册中的游标回滚后可无告警、无逃逸环境变量地正常打开events 重新纳入版本追踪re-track恢复后再次执行 v1.2.1 迁移具备幂等性且数据完好。Pipeline 证据tag 触发的双管道验证除本地门禁外tag 触发的 Release workflow 也留下了独立可复现的证据来自 tag 树上的 v1.1.2 时代工作流v1.2.2-rc.1Release workflow成功预发布版本的发布任务被正确跳过发布的 rc linux 二进制经下载验证bd version 1.2.2-rc.1 bb6be669frelease 被标记为 Pre-releaselatest未变。v1.2.2Release workflow成功release 被自动标记为Latest完整资产矩阵linux/darwin/windows ×2、android、freebsd、checksums、SBOM、attestations发布的 linux 二进制经下载验证bd version 1.2.2 6c124203e。跨版本 smoke on v1.2.230 green / 1 red唯一红色是v1.2.1 → candidate——即被预声明为预期特征的、故意拒绝的前向偏移。Migration Test Harness on v1.2.2success。值得注意的工程细节是本地门禁日志事后被宿主机 tmp 清理器清掉因此门禁记录以本文档为准并由两条 tag pipeline 独立复现验证——这保证了即使本地证据丢失发布结论依然可审计。schema 前向偏移防护源码级实现本次事故的核心技术问题是schema 前向偏移forward drift数据库 schema 版本高于二进制已知版本。Beads 在 internal/storage/schema/schema.go 中实现了完整的偏移防护。SchemaSkewErrorL85–L98在数据库 schema 版本领先于二进制版本时返回其错误消息即为事故中用户实际看到的形态schema version mismatch: database is at v65, binary knows up to v53 (12 migrations ahead)该错误类型的UserMessage()L100–L116会给终端用户输出完整的多行提示块包含你的 bd 二进制已过时、重新构建/安装建议以及逃生提示BD_IGNORE_SCHEMA_SKEW1 bd command bd --ignore-schema-skew command核心检查逻辑在checkSchemaSkewL130–L153通过CurrentVersion读取数据库当前 schema 版本缺少schema_migrations表时视为 v0因此对全新数据库安全——该守卫在可写打开路径上先于initSchema创建表执行版本为 0 或currentVersion LatestVersion()时直接放行版本超前且未设置BD_IGNORE_SCHEMA_SKEW1时返回SchemaSkewError设置后降级为 stderr 告警Warning: schema skew ignored — database (v%d) is ahead of binary (v%d); some queries may fail并放行。CheckForwardDriftL161–L163接受任意DBConn连接池*sql.DB或固定*sql.Conn因此只读存储路径跳过MigrateUp与可写打开路径MigrateUp对前向漂移的库直接 no-op 而非报错都能在任何查询撞上被删除/重命名的列之前快速失败。与之对称的是SchemaBehindError/CheckBehindDriftL165–L198当只读打开遇到 schema 落后于二进制的数据库时报错只读路径按设计跳过迁移同样可用BD_IGNORE_SCHEMA_SKEW1降级为告警。go.mod retract切断 latest 自动升级路径另一道关键防线是 go.mod 中的 retract 块L287–L295。Go 模块的 retract 指令用于通知模块代理与工具链该版本不应被使用从而让go install ...latest自动跳过这些坏版本// v1.2.0 and v1.2.1 were published accidentally without release testing and // auto-migrated local databases to an unsupported schema (v54..v65); v1.1.1 // was a burned tag that never shipped. v1.2.2 re-releases the tested 1.1 // line — retracting these keeps go install ...latest off the bad versions. retract ( v1.2.1 // accidental untested release; superseded by v1.2.2 v1.2.0 // burned tag for the accidental 1.2 release, never published v1.1.1 // burned tag, never published; superseded by v1.1.2 )注释完整交代了三者的不同命运v1.2.1是未经测试的意外发布v1.2.0是发布前烧毁的 tag从未发布v1.1.1同样是烧毁 tag从未发布。三者被统一 retract配合上文 v53 偏移守卫形成双重保障Go 工具链不会把用户导向坏版本即使装上了坏版本新二进制也会在打开被污染的数据库时明确拒绝。这也是门禁表最后一行vendorHash 不变go.mod 增量仅为 retract-onlygo.sum 未动的由来。另外根据门禁Notes部分的说明事故感知的 skew 消息并未移植到 main其守卫条件BinaryVersion 53在 1.2.x 线 schema 上是死代码main 的 schema 上限是 v65。换言之这条消息只存在于 v1.2.2 这条恢复分支上服务于事故窗口内的特定版本组合避免污染主线代码。受影响判定你是否被这次事故波及根据 docs/recovery/accidental-1-2-1-release.md 的恢复指南判定标准是两条同时成立至少运行过一次v1.2.1二进制使用 v1.2.2或任何 1.1.x 二进制时看到上述 schema mismatch 错误。以下两类用户通常不受影响升级了但从未运行过bd二进制只是被安装了工作区配置了 Dolt remoteremote-migrate gate 阻止了静默迁移。好消息是v1.2.x 的 schema 变更是严格追加式的strictly additive——1.1 线读写的数据没有任何被删除、重命名或收窄的部分因此恢复是一个两分钟的元数据修复而不是数据迁移。推荐恢复操作回滚 schema 游标Cursor Rollback恢复指南给出的首选方案是回滚 schema 游标。v1.2.x 的迁移被特意写成游标回滚后可重放安全replay-safe after a cursor rollback因此该操作可逆后续经过完整测试的 1.2.x 升级仍可正常工作。Step 1先把所有机器和 clone 升级到 v1.2.2。残留的 v1.2.1 二进制只要碰一次数据库就会静默地重新迁移。Step 2停止一切使用数据库的进程。关闭正在运行的bd进程服务器模式下还需执行bd dolt stop。Step 3备份工作区数据库cp -a .beads .beads.backup-pre-recoveryStep 4用 Dolt CLI 回滚游标。任意较新版本的dolt均可无需配置命令自带 author。数据库目录为.beads/embeddeddolt/dbembedded 模式默认或.beads/dolt/db服务器模式cd .beads/embeddeddolt/db dolt sql -q DELETE FROM schema_migrations WHERE version 53; CALL DOLT_ADD(schema_migrations); CALL DOLT_COMMIT(-m, recovery: roll schema cursor back to v53 (accidental v1.2.1), --author, bd recovery recoverybeads.invalid)如果命令报告 nothing to commit说明该步骤已完成可安全继续。Step 5在工作区运行任意bd命令。应当无告警、无需BD_IGNORE_SCHEMA_SKEW正常工作。该方法对v1.2.1 创建的数据库同样有效v65 schema 是 1.1 线所需一切的超集。如果你与队友通过 push/pull 共享 issue 数据需要注意迁移后的游标会复制要么恢复每一个 clone要么先恢复一个并 push再让其他人 pull。可选操作恢复审计事件版本化v1.2.x 的某个迁移把events审计表移出了 Dolt 的版本化平面游标回滚后1.1 线会继续写入审计事件但不做版本化、不同步其余一切正常同步。若你依赖版本化审计轨迹可在同一数据库目录下重新追踪该表dolt sql -q DELETE FROM dolt_ignore WHERE pattern events; CALL DOLT_ADD(-f, events); CALL DOLT_COMMIT(-m, recovery: re-track events table, --author, bd recovery recoverybeads.invalid)临时方案BD_IGNORE_SCHEMA_SKEW 逃生口如果当下立刻要用bd、来不及做游标回滚偏移守卫提供逃生口BD_IGNORE_SCHEMA_SKEW1 bd command这一组合v53 二进制 v65 数据库已被专门验证过读取逐字节一致、写入可用原因在于 v1.2.x 的 schema 追加内容对 1.1 线不可见。代价是审计事件版本化暂停见上文因此应将其视为临时手段而非最终归宿尽快完成游标回滚。恢复后遗留与备选方案恢复后遗留的数据意外发布期间写入 1.2.x 专属结构的数据会保留在数据库中但 1.1 线不使用它们——包括 work-lease 状态临时性5 分钟窗口、events-journal 行该功能默认关闭、provenance 行仅由显式新命令写入、以及storage_class标记。这些都不会阻塞未来的 1.2.x 升级升级后将直接继续使用。备选方案通过 Dolt 历史完整回滚若希望数据库历史本身恢复到迁移前状态游标回滚会在历史中保留迁移提交可利用 v1.2.1 迁移器为每次迁移制作一个带标签的 Dolt 提交schema: apply migration 0054_...至0065_...从而轻松定位迁移前提交。安全序列为用 v1.2.1 二进制执行bd export --all -o backup.jsonl导出 → 停止一切并复制.beads副本 → 在数据库目录执行dolt reset --hard pre-migration-commit→ 安装 v1.2.2 →bd import backup.jsonl。注意两个坑升级后删除的 issue 会复活import 无法重新删除在 v1.2.1 上记录的审计事件会丢失。多数用户应优先选择上面的游标回滚方案。发布后渠道状态管理恢复性发布不只是打一个 tag还需要在所有发布渠道上完成状态治理。截至 2026-08-15 的渠道状态来自门禁文档Post-publish channel state渠道状态GitHubreleases/latest指向 v1.2.2v1.2.1 被标记为 Pre-release并带指向恢复指南的警示横幅npmbeads/bddist-taglatest 1.2.21.2.1 的 deprecation 待办需组织凭据PyPIbeads-mcp1.2.2 已上线1.2.1 的 yank 待办走 maintainer Web UIGo proxylatest→ v1.2.2retract 已生效Homebrew-core待 bump 到 1.2.2formula 支持 autobump若 BrewTestBot 未动作需手动开brew bump-formula-pr这一节的工程要点是坏版本的处置不是删除了事而是在每个渠道上把它标记为非推荐Pre-release 标记、deprecation、yank、retract同时让latest指向已验证的好版本。复盘恢复性发布的三条工程经验从 release-gates/v1.2.2-recovery-release-gate.md 记录的完整过程可以提炼出三条可复用的工程经验前向偏移必须 fail-fast。internal/storage/schema/schema.go的SchemaSkewErrorCheckForwardDrift保证任何旧二进制遇到新 schema 时都在打开阶段快速失败并给出可操作提示而不是让用户在后续查询中撞上晦涩的 SQL 错误。BD_IGNORE_SCHEMA_SKEW则提供了经过验证的、显式的逃生通道。恢复发布用已知好版本 版本号 治理声明。v1.2.2 的本质是v1.1.2 的代码、更高的版本号所有安装渠道Homebrew、npm、安装脚本、go install都因此向前移动到经过测试的代码上同时go.modretract 与各渠道的 Pre-release/deprecation/yank 标记共同杜绝了用户重新获取坏版本。验证要双轨可复现。本地门禁upgrade-smoke-test.sh、release-verification-1.2.2.sh21/21、test.sh、make test-regression、check-versions.sh与 tag 触发的 pipelinerc.1 试运行 正式 tag、跨版本 smoke 30/1、Migration Test Harness互为印证即使本地日志被 tmp 清理器清除发布结论依然由两条 pipeline 独立复现。而跨版本 smoke 中那1 red是预声明的预期特征——测试失败也可以是被设计出来的护栏关键在于失败签名可预期、可解释。事故的最终归宿同样值得记录门禁 Notes 明确说明事故感知的 skew 消息未移植到 main其版本守卫在主线 schema上限 v65上是死代码——恢复补丁的生命周期与事故窗口绑定主线代码保持干净。完整的用户恢复手册见 docs/recovery/accidental-1-2-1-release.md版本变更记录见 CHANGELOG.md 的[1.2.2] - 2026-08-15条目。【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →