ZeroClaw 发布操作手册:从 CHANGELOG 到版本化文档的七步稳定发布实战指南
2026/9/19 10:16:59 网站建设 项目流程

ZeroClaw 发布操作手册:从 CHANGELOG 到版本化文档的七步稳定发布实战指南

【免费下载链接】zeroclawFast, small, and fully autonomous AI personal assistant infrastructure, any OS, any platform — deploy anywhere, swap anything 🦀项目地址: https://gitcode.com/gh_mirrors/ze/zeroclaw

ZeroClaw 是一个跨平台的 AI 个人助手基础设施项目,其稳定版本发布目前仍由维护者通过release-stable-manual.yml工作流手工驱动。本文是发布 Runbook(docs/book/src/maintainers/release-runbook.md)的完整技术指南:你将从零走完「生成 CHANGELOG → 版本号 PR → act 本地预演 → 手动触发 → 审批环境门禁 → 验证产物 → 部署版本化文档」的七步全流程,并理解每一步背后的脚本、工作流与 CI 门禁实现,从而具备独立裁剪一次 ZeroClaw 稳定版的能力。

本文以仓库当前真实状态为准:发布流程验证于v0.8.2发布周期,仓库当前版本为v0.8.5(见 Cargo.toml 的[workspace.package] version与 docs/book/stable-version.txt)。这是一个过渡期人工流程:在 release-plz 落地并取代它之前(该迁移尚未发生),它仍然是事实上的线上发布过程。如果流程中的某些环节显得笨重,那是刻意保留的摩擦——团队还没有足够的自动化纪律去安全地移除它。


一、整体流程:七步概览

整个稳定发布过程可以压缩为七个步骤,其余一切(crates.io、Docker、网站重新部署、Scoop、AUR、Discord、推文)都在发布成功之后作为下游作业自动运行:

  1. 使用 changelog skill 生成CHANGELOG-next.md
  2. 打开并合并版本号 PR
  3. act在本地预演发布工作流
  4. 通过手动调度触发Release Stable工作流
  5. 按提示审批两个环境门禁
  6. 验证发布存在且产物可下载
  7. 版本化文档部署

Homebrew Core 通过其自身的 autobump 服务检测稳定版 GitHub Release,无需维护者做任何事——除非某个作业显式失败,或 Homebrew 的外部 bump 长期停滞。


Step 1:生成 CHANGELOG-next.md

第一步是运行changelog-generationskill 产出CHANGELOG-next.md,其完整流程定义在.claude/skills/changelog-generation/SKILL.md

该 skill 的工作方式:

  • 从上一次稳定 tag 到 HEAD 之间的 git log 生成 changelog;
  • 通过 GitHub GraphQL 解析贡献者;
  • 将结果写入CHANGELOG-next.md

产物处理有两种方式:直接把结果提交到短生命周期分支并纳入步骤 2 的版本号 PR;如果 diff 过大,也可以先开一个独立的 PR。如果CHANGELOG-next.md已从上一次中止的发布周期残留,先复核其准确性再复用

## In brief章节是公告的必需输入

文件在序言之后必须携带## In brief章节:两段短文字,合计至多 255 个字符,说明本次发布是什么。X(Twitter)和 Discord 公告工作流会发布这一章节,后面紧跟序言中的提交数与贡献者数,以及网站发布帖的链接(尚无发布帖时退化为 GitHub Release 链接)。缺少它时公告会回退到 Highlights 的首批条目,再缺则回退到原始提交列表。

发布前可以无副作用地预览任一已发布 tag 的公告文案:

gh workflow run tweet-release.yml -f release_tag=vX.Y.Z -f dry_run=true gh workflow run discord-release.yml -f release_tag=vX.Y.Z -f dry_run=true

合成后的文案会出现在该次运行的 job summary 中。仓库当前 CHANGELOG-next.md 即为v0.8.5的待发布 changelog,开头即包含 "ZeroClaw v0.8.5 is a security, connectivity, and operator-experience release spanning454 commitsfrom73 contributors" 这样的序言与 8 条 Highlights,可作为格式参考。


Step 2:版本号 PR(bump-version)

2.1 同步全仓库版本引用

先在 workspace 根 Cargo.toml 中提升workspace.package.version,然后按顺序运行两个发布脚本。首先同步全仓库的版本引用:

./scripts/release/bump-version.sh # version from Cargo.toml

scripts/release/bump-version.sh 是这一步的核心:它从Cargo.toml读取版本(也可用显式参数./scripts/release/bump-version.sh 0.7.0覆盖),校验 semver 格式,随后以bump()辅助函数对每个目标文件做正则替换。从源码看,它覆盖的面非常广:

  • README 版本徽章:更新README.mddocs/i18n/*/README.md中的version-vX.Y.Z-blue徽章;
  • Tauri 桌面端配置:用jq(或 sed 回退)更新 apps/tauri/tauri.conf.json 的version字段;
  • Windows 安装器:同步setup.batVERSIONRUST_MIN_VERSION(后者取自Cargo.toml[workspace.package] rust-version,两个变量分别用sed独立更新);
  • Workspace Cargo.toml:提升[workspace.package] version(所有子 crate 通过version.workspace = true继承),并同步[workspace.dependencies]中所有path = "crates|apps/..."依赖的版本钉——脚本注释明确指出,漏掉 apps/ 下的 pin 会让 lockfile 无法解析、在 bump 中途破坏cargo metadata
  • Cargo.lockcargo update --workspace仅重解析 workspace 成员条目;
  • Marketplace 模板:Dokploy 的meta-entry.json与 docker-compose 镜像 tag、EasyPanel 的meta.yaml镜像 tag;
  • 工作流描述示例discord-release.yml的示例 tag、publish-crates.sh--execute断言版本;
  • 文档书示例:扫描docs/book/src/**/*.md,只替换两种锚定模式——容器镜像 tag(zeroclawlabs/zeroclaw:vX.Y.Z)与/health响应示例中的"version":"X.Y.Z"/ RPC 握手中的"serverVersion":"X.Y.Z"(兼容紧凑与带空格的 JSON 两种风格),历史版本叙述文本被刻意跳过;
  • Docs 稳定指针:把vX.Y.Z写入 docs/book/stable-version.txt,这是「哪个已部署文档版本是 Stable」的唯一事实来源;
  • Nix git 依赖哈希:通过 scripts/dev/refresh-nix-hashes.sh 刷新nix/hashes.json(缺nix-prefetch-git/jq时优雅跳过);
  • 生成的安装面:运行cargo generate installers,重新生成install.shsetup.batdist/aur/PKGBUILDdist/aur/.SRCINFOdist/scoop/zeroclaw.jsonflake.nix、Dockerfile/Containerfile 特性集、dev/ci/docker-tags.tomldocs/book/src/_snippets/install.md、README/platform 文档中的 Unix 快速路径块以及docs/book/src/setup/windows.md的 Windows 预编译块。

关键设计:版本、特性与应用打包值全部来自Cargo.toml[package.metadata.zeroclaw];四个稳定安装路由来自xtask/src/generate/spec.rs中的类型化契约。永远不要手工编辑生成区域——CI 的 Installer Drift 门禁会在生成面与 spec 不同步时让 PR 失败,漏掉一次重新生成就无法合入。

2.2 刷新并钉住翻译目录

bump-version.sh设置发布版本后,刷新文档翻译目录并钉到对应 tag。如果目录是分开准备的,先在 cut tag 之前检查覆盖率并校验:

cargo mdbook stats cargo mdbook check

然后运行发布包装脚本:

./scripts/release/refresh-translations.sh --model-provider anthropic.release

scripts/release/refresh-translations.sh 从Cargo.toml读取版本(无手工输入),然后依次完成:

  1. docs/book/po子模块未检出则自动初始化(git submodule update --init docs/book/po);
  2. 校验工作区目录基于子模块当前origin/main(dirty 且 head 不一致时直接报错退出);
  3. 检查本地与远端均不存在v{version}tag(存在则报错拒绝);
  4. 运行cargo mdbook sync --model-provider <alias>执行翻译,随后cargo mdbook check校验(--no-translate可跳过翻译);
  5. 提交并推送目录到zeroclaw-labs/zeroclaw-docs-translations子模块的main
  6. 在子模块 cutv{version}tag 并推送;
  7. 检出该 tag,把主仓库 gitlink 钉到该 tag 并git add docs/book/po

要求显式传入--model-provider别名,使发布不依赖硬编码后端;别名从providers.models.<kind>.<alias>解析。需要覆盖Cargo.toml默认版本时,可在--model-provider前传显式版本:

./scripts/release/refresh-translations.sh 0.8.2 --model-provider anthropic.release

关于docs/book/po子模块与cargo mdbook sync的 extract → merge → AI-fill 三段管线,详见 Docs & Translations。

2.3 提交、PR 与门禁

把一切提交在一起,提交信息为:

chore: bump version to vX.Y.Z

如果 PR 同时改动[workspace.package] rust-version或钉住的 Rust 工具链,要把它当作兼容性变更而非纯发布管道改动:PR 应写明新的 MSRV、解释源码构建升级路径,并证明 CI、Docker、安装器与生成面在新下限上达成一致再合入。

打开 PR 后:

  • 打标签type:cisize:XS以及 PR labeler 自动添加的路径标签;若提升工具链下限,追加risk:high并走 lane D;
  • 需要两位独立 Core Team 成员审批,CI 全绿才合入;
  • CI 的Installer Drift门禁在生成面与 spec 失同步时使 PR 失败;Validate Translations Pin门禁会解析钉住提交处的子模块并校验目录格式与 msgid 一致性——坏 pin 也无法合入。

确认合入正确落地:

git fetch origin git show origin/master:Cargo.toml | grep '^version' # Must show: version = "X.Y.Z"

Step 3:用 act 本地预演发布工作流

Release Stable是一个 GitHub Actions 作业图,在你点击 Run workflow 的那一刻就开始消耗环境门禁的审批窗口。如果某个工作流步骤坏了(缺少构建产物、陈旧路径、有人删了 codegen 步骤却没更新 CI),故障会在你已承诺发布窗口、版本 PR 已合入、master 已处于新版本号之后才浮出水面——恢复意味着要紧急修分支、重跑 CI、在一棵已自我宣告为「完整发布版本」的树上赶时间发布。

廉价的保险是:在打开 GitHub Actions 表单之前,先在精确的已合入 master commit上本地跑同一作业图。act(nektosact)在 Docker 容器内执行 GitHub Actions 工作流,使用与 GitHub 相同的actions/*生态。它无法完美镜像云端 runner(无法触达 artifact 上传运行时、GitHub 签发的 OIDC token、环境 secret,或依赖真实发布 tag 的作业),但它能跑那些覆盖了我们历史上几乎所有发布期 CI 故障的构建与测试步骤。这一步每次发布投入 15–20 分钟,且确实抓到过常规 per-PR CI 发现不了的真实缺陷(因为出故障的工作流只在workflow_dispatch上跑,push不触发)。

3.1 一次性安装

act运行工作流。最干净的安装路径是 GitHub CLI 扩展,因为它继承你的gh认证并把真实GITHUB_TOKEN暴露给每次工作流运行:

  1. 从 https://cli.github.com 安装 GitHub CLI(Linux/macOS/Windows),认证一次:gh auth login

  2. 安装act扩展:

    gh extension install nektos/gh-act

    artifact 兼容性红线:产出 artifact 的作业需要act实现actions/upload-artifactv7 与actions/download-artifactv8 所要求的 artifact-service 协议,而目前没有任何已发布的 act 版本实现它。助手脚本会在启动使用钉住 artifact actions 的作业前预检已装act版本并 fail-closed:在未验证版本上不会尝试该作业。在兼容的act版本发布并通过真实 artifact 往返验证之前,artifact 相关作业一律走下面的 GitHub 托管兜底路径——这是当前推荐路径,而非罕见例外。

  3. 从 https://docs.docker.com/engine/install/ 安装 Docker Engine 或 Docker Desktop。Linux 上把自己加入docker组以避免sudoact也兼容 Podman 与 Colima。

就这些。仓库的.actrc与 scripts/dev/act-local.sh 处理其余一切(runner 镜像、secrets 文件、artifact server、action SHA 预取)。

3.2 每次发布的预演

确保工作树与步骤 2 的已合入 master 尖端一致:

git fetch upstream git checkout upstream/master

列出所有工作流文件中可运行的作业:

./scripts/dev/act-local.sh --list

运行单个作业、交互选择,或运行全部可安全预演的作业:

./scripts/dev/act-local.sh release-stable-manual:web # one job ./scripts/dev/act-local.sh # interactive picker ./scripts/dev/act-local.sh --all # every dry-run-safe job

首次运行会拉取 runner 镜像(约 1.5 GB)并通过Swatinem/rust-cache预热 Rust 构建缓存,之后快得多。脚本自动创建 gitignored 的.secrets文件、把每个钉住的 action SHA 预取进~/.cache/act/(act 的浅克隆无法解析任意 commit)、通过父进程环境把gh认证的GITHUB_TOKEN传入运行(token 值从不进入 argv)、并设置--artifact-server-pathactions/upload-artifactactions/download-artifact能在作业间工作。底层全是普通act,脚本只是去掉了 flag 汤。

从 scripts/dev/act-local.sh 源码可见其工程细节:

  • GoGitActionCache--use-new-action-cache选择 act 的 GoGitActionCache(唯一能解析非 tip 钉住 SHA 的后端;默认磁盘缓存做浅克隆并在这些 SHA 上 400 报错),--action-offline-mode--all扫描中复用已缓存 action;
  • 版本自动推导:若工作流有version:workflow_dispatch输入,自动从Cargo.toml[workspace.package] version推导并作为--input version=...传入;
  • artifact 兼容预检preflight_artifact_service解析已发布 act 版本并与内部阈值ACT_ARTIFACT_MIN_VERSION="999.0.0"比较——这是一个不可达哨兵,不是让你去安装的版本;没有任何已发布 act 版本满足它,只有在对某个版本完成真实 artifact 往返验证后才会降为具体版本号。因此,任何 artifact 产出或消费作业在构建开始前就会预检失败并指向 GitHub 托管 Actions——不要降级钉住的 artifact actions 来让本地 runner 通过。

对于--all,兼容性会在第一个作业启动前跨完整选中作业集检查;任一选中作业需要 artifact 服务则整体 fail-closed 退出,绝不跑部分子集。

本地 artifact 预检失败是当前每个已发布 act 上的预期行为,不是偶发故障。把精确 commit 推上 GitHub,用托管工作流作为 artifact 承载作业的验证兜底。只读的跨平台构建可以安全调度并从 CLI 观察:

gh workflow run cross-platform-build-manual.yml --ref <validation-branch> gh run list --workflow cross-platform-build-manual.yml --branch <validation-branch> --limit 1 gh run watch <run-id> --exit-status

不要提前触发release-stable-manual.yml作为 dry-run 替代品——该工作流在环境审批后会真正发布。本地 artifact 作业记为因版本策略跳过,用托管跨平台构建做 artifact 往返,把受保护的 stable-release 运行留给 Step 4。

3.3--all只运行 dry-run-safe 白名单上的作业

act遵守 GitHub 的环境保护门禁。当维护者的真实GITHUB_TOKEN被传入运行,一个向 GitHub 写入的作业本地成功(调用gh release createpublish、推送 GHCR 的docker作业、force-pushgh-pagesdocs-deploy、开 issue 的daily-audit、发 webhook 的tweet-release/discord-release)可能在第一次尝试时就执行了真实副作用。

因此--all强制一份硬编码白名单,只跑已被证明本地安全的作业——目前是release-stable-manual.ymlcross-platform-build-manual.yml中的纯 artifact 构建步骤(validatewebrelease-notesbuildbuild-desktop)。其余全部跳过并记录原因:

==> skip release-stable-manual:publish (not on dry-run-safe allowlist) ==> skip release-stable-manual:docker (not on dry-run-safe allowlist) ==> skip release-stable-manual:crates (not on dry-run-safe allowlist) ==> skip release-stable-manual:redeploy-website (not on dry-run-safe allowlist) ==> skip docs-deploy:deploy (not on dry-run-safe allowlist) ==> skip daily-audit:advisories (not on dry-run-safe allowlist) ==> skip tweet-release:tweet (not on dry-run-safe allowlist)

白名单是fail-closed的:仓库新增的工作流在维护者审阅并将其安全作业 ID 加入scripts/dev/act-local.shDRY_RUN_SAFE_JOBS之前,一律视为潜在可变。这很重要,因为discover_jobs遍历的是.github/workflows/*.yml下的所有工作流而非仅发布工作流,denylist 会让未来的写入面工作流悄悄溜过。

两个逃生口(用于确有理由本地尝试非白名单作业的罕见情况):

  • ./scripts/dev/act-local.sh release-stable-manual:publish:显式<wf>:<job>形式运行你指定的作业,若目标不在白名单上,调用act前会打印响亮的警告;
  • ./scripts/dev/act-local.sh --all --no-allowlist:为整个--all运行关闭白名单过滤(仅当你已验证工作流步骤不会触达变更面时使用,例如在无真实注册表凭据、.secrets文件为空的 fork 上)。

3.4 在 act 下预期失败(且无妨)的部分

act无法模拟几个 GitHub 专属表面,这些失败不是真实缺陷:

  • 依赖真实发布 tag 的作业(publish创建 GitHub Release);
  • 环境门禁作业(publishdocker与 crates 发布器):本地不存在审批 UI;
  • OIDC 联邦身份 token。

其余一切——tsc错误、缺文件、Rust 编译失败、cargolockfile 不匹配——都是真实缺陷。在通过标准 PR(基于 master)修复这些之前,不要在 GitHub Actions 表单上点击 Run workflow。


Step 4:触发 Release Stable 工作流

前往 Release Stable 工作流页面,点击Run workflow,填写:

  • Branch:master
  • Stable version to release:X.Y.Z不带v前缀

第一个作业(validate)检查版本与Cargo.toml一致、且vX.Y.Ztag 尚不存在。若失败,修复不匹配后重新触发,不要试图绕过它。


Step 5:审批环境门禁

三个作业受 GitHub 环境保护规则门控。各自进入 pending 时,工作流运行中会出现"Waiting for review"横幅。三个都出现后逐一审批;仅当crates-io的无 token 包预检通过后才审批它

环境作业作用
github-releasespublish创建 GitHub Release 并上传产物
dockerdocker推送镜像到 GHCR
crates-iocrates / Publish to crates.io按依赖顺序发布已验证的 23-crate workspace

错过审批窗口导致作业超时时,只需从工作流运行页重跑失败的作业,无需从头重启。


Step 6:验证发布产物

publish完成后逐项确认:

[ ] GitHub Release 存在于 /releases/tag/vX.Y.Z 且标记为 Latest [ ] Release notes 非空 [ ] SHA256SUMS 产物存在且非空 [ ] SPDX 与 CycloneDX 两份 SBOM 产物均存在 [ ] 恰好一个 zeroclaw-vX.Y.Z-verification.tar.gz 产物存在 [ ] 无松散的 *.bundle、*.attestation.jsonl 或 *.intoto.jsonl 产物 [ ] 至少一个二进制归档可下载(抽查 linux x86_64) [ ] 预编译 Docker 与生成的 Docker matrix 作业全绿

CHANGELOG-next.md在发布后刻意留在 master 上publish作业只把它当作 release body 读取,不会删除它。下一个发布周期会覆盖它,无需手工清理。

对于常规workflow_dispatch路径,Docker Publish 在 stable release 工作流内部同步运行,全部发布作业变绿即无需单独检查 Docker。若维护者改为推送vX.Y.Ztag 启动发布,Docker Publish 会作为独立的 tag 触发运行启动——在把容器发布视为完成前,先确认那个兄弟运行是绿的。crates.io、Scoop、AUR 只有在各自作业变红时才需单独关注。Homebrew Core 在此工作流之外,其 autobump 服务按自己的节奏检查符合条件的分支公式。

需要验证签名、SBOM 或 SLSA 来源的消费者可参考 Release artifact verification:可下载产物使用 GitHub 托管的 Build Level 2 认证(记录产物摘要、源 commit 与发布工作流身份),支持gh attestation verify在线验证,也支持通过zeroclaw-vX.Y.Z-verification.tar.gz归档(内含<artifact>.attestation.jsonl包、trusted_root.jsonlATTESTATION-BUNDLES.md索引)做断网验证,另有zeroclaw-vX.Y.Z-sbom.spdx.json/-sbom.cdx.json两份 SBOM 与 cosign 签名的 GHCR 镜像。

此外,任何发布认证工作流变更之后,人工维护者必须在关闭跟踪 issue 前,运行 docs/maintainers/release-attestation-runbook.md 中的在线与断网验证演练。本地工作流 lint 或act运行不能替代这一发布级检查——两者都无法铸造 GitHub 的生产 OIDC 认证。


Step 7:版本化文档部署

ZeroClaw 文档在gh-pages分支上使用版本化结构。Release Stable工作流的deploy-docs作业在publish成功后,为发布 tag 调度Deploy mdBook docs to Pages工作流;被调度的运行异步构建并发布该版本文档到/vX.Y.Z/(调度作业不等待它)。

为什么是显式调度而不是 tag-push 触发器。docs-deploy.yml声明了tags: [v*],但发布 tag 是publish作业通过gh release createGITHUB_TOKEN创建的。GitHub 不会为用GITHUB_TOKEN创建的 tag push 启动新的工作流运行,所以tags: [v*]触发器对这种方式 cut 的发布永不触发。deploy-docs作业因此通过workflow_dispatch(在GITHUB_TOKEN下也运行的文档化例外)以 tag 为输入调用docs-deploy.yml。若未来用手持个人 token 手工 cut tag,tags: [v*]push 触发器会触发,发布工作流的调度成为同一部署的无操作重跑,两条路径收敛于/vX.Y.Z/

自动发生的事

  • deploy-docs作业调度一个落在/vX.Y.Z/的构建。
  • "Stable" 是指针,不是副本。发布 tag 部署(如v0.8.0)才构建并发布该版本的文档目录。bump-version.sh把发布版本写入docs/book/stable-version.txt;该变更落在 master 上只刷新 stable 元数据。master 部署不会重建或重新发布 release tag 的文档;它把stable-version.txt复制到gh-pages根,并重新生成根/重定向与版本选择器的 "Stable (latest release)" 条目,让两者解析到该发布已经发布的版本目录。若所指版本目录不在gh-pages上,部署会大声失败。不存在重复的/stable/树。
  • 顺序至关重要:tag 部署必须先让/vX.Y.Z/出现在gh-pages上,master 部署才能把 stable 指针翻到它。常规发布序列中版本号 PR 先合入(Step 2),所以它的 master 文档部署通常先于Release Stable创建并部署 tag。那次较早的 master 部署发现/vX.Y.Z/不存在,会刻意保留旧指针;翻转被推迟(见docs-deploy.yml的 deferred-flip 逻辑)。deploy-docs作业随后创建/vX.Y.Z/,翻转在目录上线后的下一次master 部署上发布。注意deploy-docs只调度 tag 构建而不等待它:绿色的deploy-docs作业只代表调度被接受,不代表文档运行结束。/vX.Y.Z/上线后,用tag=master调度docs-deploy.yml来发布 stable 指针翻转(并在 Actions 页确认被调度的运行确实成功)。
  • gh-pages临时的:每次部署 force-push 单个孤儿 commit(无累积历史),通过DOCS_KEEP_VERSIONS(master 加上最新的 N 个正式版;预发布与更旧的正式版被裁剪)执行保留策略,控制克隆体积。
  • _shared/目录(UI CSS、JS 与 favicon)随构建更新,主题会级联到所有已部署版本。
  • 翻译 locale(esfrjazh-CN)从docs/book/po子模块渲染,部署通过submodules: recursive解析已部署 ref 钉住的任意 commit。该 pin 在版本号 bump 时设置(见 Step 2 的刷新、tag、pin 流程)。英文不需要子模块。

引导gh-pages

gh-pages被删除或需完全重建,按此顺序播种版本:

  1. 最旧的支持发布:workflow_dispatch,tagv0.7.5
  2. 后续发布:workflow_dispatch,tagv0.8.0-beta-1
  3. 当前 master:workflow_dispatch,tagmaster

重要:引导期间master必须最后部署。它写入所有其他版本使用的权威_shared/chrome 层。

注意:Stable 由docs/book/stable-version.txt(源码中提交、发布到 gh-pages 根的stable-version.txt)解析。引导后确认该文件指向预期的 GA 发布;根重定向与 "Stable (latest release)" 选择器条目跟随它。不创建/stable/目录。

手动重新部署与版本下限

手动重新部署特定版本:

  1. 前往ActionsDeploy mdBook docs to Pages
  2. 点击Run workflow
  3. 输入 tag(如v0.7.5master

DOCS_MIN_VERSION下限:为防止意外部署很旧或不支持的版本,工作流强制最小版本下限(当前v0.7.5)。

  • 早于DOCS_MIN_VERSION的 tag(如v0.7.4)被工作流拒绝。
  • cargo mdbook gen-versions(xtask 助手)忽略gh-pages上低于该下限的任何目录,使其不出现在版本下拉框中。

需要抬高下限以放弃旧版本支持时:

  1. 更新.github/workflows/docs-deploy.yml中的DOCS_MIN_VERSION环境变量。
  2. 旧版本目录会在下次部署时被DOCS_KEEP_VERSIONS保留清理自动裁剪,无需手工编辑gh-pages回收空间。

出问题怎么办:故障排查速查表

运行瞬间死于startup_failure(零作业创建):把它当作症状而非白名单诊断。检查运行摘要与仓库 Actions 策略。若 GitHub 报告 selected-actions 拒绝且发布工作流最近增改过uses:refs,把这些 refs 与 Allowed actions 对比,在 Settings → Actions → General 只添加被拒的模式,等设置传播几分钟,再调度一次全新运行。若 GitHub 未报告策略拒绝,则调查工作流定义或其他仓库策略。

validate 失败:版本不匹配:版本号 PR 未合入,或输入了错误版本。修复不匹配后重新触发。

环境门禁超时:只重跑超时的作业,无需重启工作流。

Scoop 或 AUR 分发作业失败:各自有对应的手动可触发子工作流。先用dry_run: true重跑对应子工作流确认修复,再dry_run: false。这些是锦上添花:分发作业失败不使发布本身失效。Scoop 凭据失败时用 Scoop Bucket Canary 而非把通用 dry run 当作凭据证明;canary 启用 fail-closed 的credential_canary路径。

crates.io 发布器上传部分 crate 后停止:不要提升版本或开始第二次发布。crates.io 版本无法替换或删除。在同一发布 commit 修复失败 crate,然后用dry_run: false对同一 tag 重跑Pub crates.io;发布器先查询每个<crate>@<version>并跳过已落地的版本。读取最后一个成功 crate 的 Publish 步骤。若预检失败则未尝试任何上传,问题仍可逆。

scoop作业报remote: Permission ... denied to <account>(403):是权限问题而非 manifest 问题:bucket token 失效或权限不足。按 RotatingSCOOP_BUCKET_TOKEN轮换 token,然后调度 Scoop Bucket Canary 确认修复(不写入 bucket)。用dry_run: false重跑 Scoop 发布器并确认 bucket 落地新版本。Bucket 侧 Excavator 恢复仍待定(依赖zeroclaw-labs/scoop-zeroclaw#1、仓库工作流写权限与维护者冒烟测试);在这些步骤完成前不要指望它修复发布。

每周Scoop Bucket Canary变红:token 过期或失去写权限。同一轮换路径。在下次发布前修复。

Homebrew Core 停滞:Homebrew 不是发布工作流作业。查阅 Homebrew autobump 状态与文档化手动 bump 路径,而不是添加仓库 fork token。

AUR 作业报The AUR is down due to maintenance上游故障而非凭据问题。若日志在SSH key diagnostics下显示 key 指纹、失败来自服务器而非 SSH,则AUR_SSH_KEY无恙。发布器在约七分钟内重试五次,硬作业超时。每次尝试重克隆当前包,若另一运行已发布更新版本则停止而非降级。到达维护错误意味着故障窗口超过了重试预算。等待aur.archlinux.org恢复,然后在发布 tag 上重新调度 Pub AUR Package:先dry_run: truedry_run: false。用curl -fsS 'https://aur.archlinux.org/rpc/v5/info?arg%5B%5D=zeroclawlabs'确认结果,或直接调度 AUR Freshness Check。跳过此步会让 AUR 静默落后,直到每周检查发现它。

AUR 比刻意回滚的稳定发布更新:验证回滚 tag 与包内容。若已发布包含有回滚 tag 不含的非零epoch不要重新调度旧 tag:发布元数据来自不可变 tag,默认分支编辑无法改变该运行。改为准备一个包含回滚代码的前向编号稳定发布,在dist/aur/PKGBUILD添加匹配的epoch=赋值,运行cargo generate installers重新生成dist/aur/.SRCINFO,审阅两个文件,合入并 cut 新发布 tag。新鲜度检查在 tag 发布前保持红色。绝不allow_downgrade跨越 epoch 边界。同一 epoch 内回滚时,手动 Pub AUR Package 工作流先跑一次dry_run: true验证元数据生成与版本守卫的目标侧,再以dry_run: falseallow_downgrade: true运行。非 dry-run 守卫额外比较新鲜 AUR 克隆。该覆盖只存在于手动调度;可复用接口不声明该输入,因此无法请求它。绝不用它绕过畸形 AUR 元数据或无法解释的版本不匹配。

发布因同一版本包文件不同而停止:发布器有意拒绝在现有epoch:pkgver-pkgrel元组上替换不同文件。检查 diff。授权 AUR 维护者必须恢复从该发布 tag 生成的规范 PKGBUILD 与.SRCINFO,或合入修正的源码变更并在新稳定 tag 下发布。编辑默认分支并重新调度旧 tag 无效,因为发布器从不可变 tag 读取元数据。

发布报告当前 AUR 版本非数值或畸形:自动化发布器有意 fail-closed,allow_downgrade无法绕过畸形元数据。授权 AUR 维护者必须手工 AUR push 修复为良构的epoch:pkgver-pkgrel,通过 AUR RPC 验证,再重新调度正常发布器。不要削弱守卫来让畸形已发布状态可比较。


被移除的遗留工作流

.github/workflows/中若干此前存在的自动发布工作流已被删除,因为它们绕过审阅或不可逆地发布。它们不再存在;若在 PR 中再次出现,视为回归并阻止:

工作流移除原因
release-beta-on-push.yml每次推送到 master 都自动发布
publish-crates-auto.yml任何版本变更自动发布到 crates.io,不可逆
version-sync.yml以 bot 身份直接提交 master,绕过审阅
checks-on-pr.yml重复 CI:产生令人困惑的冲突状态
pre-release-validate.yml未使用的生成清单;本 runbook 取代了它

剩余工作流(自动与手动)的完整清单见 CI & Actions。其中与发布直接相关的关键条目包括:

  • Release Stable(release-stable-manual.yml:手动触发的完整发布管线——构建全部目标、创建 GitHub Release、推送预编译的latest/版本化/debianDocker 镜像到 GHCR、在 release tag 调用生成的 Docker 变体矩阵、触发网站重新部署、调用分发子工作流(Scoop、AUR、Discord、推文)。github-releasesdocker两个环境门禁需要维护者中途审批;crates-io环境还门控 crates 发布器;
  • Docker Publish(docker-publish.yml:构建、签名、扫描dev/ci/docker-tags.toml生成的四变体矩阵(minimaldefault-featuresdistall-features);人工v*tag 直接启动它,而workflow_dispatch启动的稳定发布因其 tag 由GITHUB_TOKEN创建、不会触发 tag-push 事件,由release-stable-manual.yml在不可变 release tag 上同步调用它;
  • Discord Release / Tweet Release:稳定发布成功后分别发布公告;
  • Scoop Bucket Canary:每周用dry_run: truecredential_canary: true预演 Scoop 发布路径,检测SCOOP_BUCKET_TOKEN凭据腐化——它刻意不接入 Release Stable,死掉的包管理器凭据绝不应阻塞或延迟发布;
  • AUR Freshness Check:每周对比已发布zeroclawlabsAUR 版本与当前稳定 GitHub Release,AUR 落后则失败(AUR RPC 不可达时警告并通过,因为那是上游可用性问题而非包停滞)。

未来方向:Runbook 是桥梁而非终点

本 runbook 与release-stable-manual.yml过渡方案,不是目的地。目标终态:

  • release-plz 自动管理版本号提升与 changelog;
  • 单个release.yml取代当前子工作流的拼凑;
  • SLSA 来源证明内建进管线;
  • 团队通过合入一个发布 PR 来 cut 发布,而不是遵循 runbook。

在那一刻到来之前,请使用本流程。你用本 runbook 手工 cut 的每一次发布,都是为自动化最终需要做什么积累的实践依据。

【免费下载链接】zeroclawFast, small, and fully autonomous AI personal assistant infrastructure, any OS, any platform — deploy anywhere, swap anything 🦀项目地址: https://gitcode.com/gh_mirrors/ze/zeroclaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询