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、推文)都在发布成功之后作为下游作业自动运行:
- 使用 changelog skill 生成
CHANGELOG-next.md - 打开并合并版本号 PR
- 用
act在本地预演发布工作流 - 通过手动调度触发
Release Stable工作流 - 按提示审批两个环境门禁
- 验证发布存在且产物可下载
- 版本化文档部署
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.tomlscripts/release/bump-version.sh 是这一步的核心:它从Cargo.toml读取版本(也可用显式参数./scripts/release/bump-version.sh 0.7.0覆盖),校验 semver 格式,随后以bump()辅助函数对每个目标文件做正则替换。从源码看,它覆盖的面非常广:
- README 版本徽章:更新
README.md与docs/i18n/*/README.md中的version-vX.Y.Z-blue徽章; - Tauri 桌面端配置:用
jq(或 sed 回退)更新 apps/tauri/tauri.conf.json 的version字段; - Windows 安装器:同步
setup.bat的VERSION与RUST_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.lock:
cargo 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.sh、setup.bat、dist/aur/PKGBUILD、dist/aur/.SRCINFO、dist/scoop/zeroclaw.json、flake.nix、Dockerfile/Containerfile 特性集、dev/ci/docker-tags.toml、docs/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.releasescripts/release/refresh-translations.sh 从Cargo.toml读取版本(无手工输入),然后依次完成:
- 若
docs/book/po子模块未检出则自动初始化(git submodule update --init docs/book/po); - 校验工作区目录基于子模块当前
origin/main(dirty 且 head 不一致时直接报错退出); - 检查本地与远端均不存在
v{version}tag(存在则报错拒绝); - 运行
cargo mdbook sync --model-provider <alias>执行翻译,随后cargo mdbook check校验(--no-translate可跳过翻译); - 提交并推送目录到
zeroclaw-labs/zeroclaw-docs-translations子模块的main; - 在子模块 cut
v{version}tag 并推送; - 检出该 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:ci、size: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暴露给每次工作流运行:
从 https://cli.github.com 安装 GitHub CLI(Linux/macOS/Windows),认证一次:
gh auth login。安装
act扩展:gh extension install nektos/gh-actartifact 兼容性红线:产出 artifact 的作业需要
act实现actions/upload-artifactv7 与actions/download-artifactv8 所要求的 artifact-service 协议,而目前没有任何已发布的 act 版本实现它。助手脚本会在启动使用钉住 artifact actions 的作业前预检已装act版本并 fail-closed:在未验证版本上不会尝试该作业。在兼容的act版本发布并通过真实 artifact 往返验证之前,artifact 相关作业一律走下面的 GitHub 托管兜底路径——这是当前推荐路径,而非罕见例外。从 https://docs.docker.com/engine/install/ 安装 Docker Engine 或 Docker Desktop。Linux 上把自己加入
docker组以避免sudo。act也兼容 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-path让actions/upload-artifact与actions/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 create的publish、推送 GHCR 的docker作业、force-pushgh-pages的docs-deploy、开 issue 的daily-audit、发 webhook 的tweet-release/discord-release)可能在第一次尝试时就执行了真实副作用。
因此--all强制一份硬编码白名单,只跑已被证明本地安全的作业——目前是release-stable-manual.yml与cross-platform-build-manual.yml中的纯 artifact 构建步骤(validate、web、release-notes、build、build-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.sh的DRY_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); - 环境门禁作业(
publish、docker与 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-releases | publish | 创建 GitHub Release 并上传产物 |
docker | docker | 推送镜像到 GHCR |
crates-io | crates / 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.jsonl与ATTESTATION-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 create用GITHUB_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(
es、fr、ja、zh-CN)从docs/book/po子模块渲染,部署通过submodules: recursive解析已部署 ref 钉住的任意 commit。该 pin 在版本号 bump 时设置(见 Step 2 的刷新、tag、pin 流程)。英文不需要子模块。
引导gh-pages
若gh-pages被删除或需完全重建,按此顺序播种版本:
- 最旧的支持发布:
workflow_dispatch,tagv0.7.5 - 后续发布:
workflow_dispatch,tagv0.8.0-beta-1等 - 当前 master:
workflow_dispatch,tagmaster
重要:引导期间
master必须最后部署。它写入所有其他版本使用的权威_shared/chrome 层。
注意:Stable 由
docs/book/stable-version.txt(源码中提交、发布到 gh-pages 根的stable-version.txt)解析。引导后确认该文件指向预期的 GA 发布;根重定向与 "Stable (latest release)" 选择器条目跟随它。不创建/stable/目录。
手动重新部署与版本下限
手动重新部署特定版本:
- 前往Actions→Deploy mdBook docs to Pages
- 点击Run workflow
- 输入 tag(如
v0.7.5或master)
DOCS_MIN_VERSION下限:为防止意外部署很旧或不支持的版本,工作流强制最小版本下限(当前v0.7.5)。
- 早于
DOCS_MIN_VERSION的 tag(如v0.7.4)被工作流拒绝。 cargo mdbook gen-versions(xtask 助手)忽略gh-pages上低于该下限的任何目录,使其不出现在版本下拉框中。
需要抬高下限以放弃旧版本支持时:
- 更新
.github/workflows/docs-deploy.yml中的DOCS_MIN_VERSION环境变量。 - 旧版本目录会在下次部署时被
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: true再dry_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: false和allow_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-releases与docker两个环境门禁需要维护者中途审批;crates-io环境还门控 crates 发布器; - Docker Publish(
docker-publish.yml):构建、签名、扫描dev/ci/docker-tags.toml生成的四变体矩阵(minimal、default-features、dist、all-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: true加credential_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),仅供参考