Electric 项目 durable-streams-rust 发布流程全解:Changesets 驱动的 crates.io / npm / Docker 三通道发布
2026/9/16 12:25:57 网站建设 项目流程

Electric 项目 durable-streams-rust 发布流程全解:Changesets 驱动的 crates.io / npm / Docker 三通道发布

【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric

本文是围绕 packages/durable-streams-rust/RELEASING.md 展开的发布操作指南,面向需要在 Electric monorepo 中为durable-streams-rust(Rust 编写的 Durable Streams 服务端)切新版本的维护者、CI 工程师,以及想理解"一个版本如何同时抵达 crates.io、npm 与 Docker Hub"的读者。读完你将掌握:版本锚点放在哪里、Changesets 如何驱动版本号提升、三个发布通道各自的产物与认证方式,以及当前 npm 通道被禁用时的发布边界。

一、版本锚点:package.json是唯一事实来源

durable-streams-rust的发布与传统 Rust 项目不同——它属于 Electric monorepo,因此遵循整个仓库统一的 Changesets 版本管理机制。版本号不存放在Cargo.toml,而是存放在包自己的package.json

// packages/durable-streams-rust/package.json(节选) { "name": "@electric-ax/durable-streams-server-rust", "version": "0.1.5", "description": "High-performance Durable Streams server (Rust) — native binary distributed via npm.", "private": true, "scripts": { "test:conformance": "vitest run --config conformance/vitest.config.ts", "sync-version": "node scripts/sync-cargo-version.mjs" } }

要点解析:

  • private: true:该包本身不会被发布到 npm。Changesets 只负责提升这里的版本号,而真正的二进制包(见第三节的四个平台包)由 CI 发布。它在这里的角色是"版本锚点"(anchor)。
  • @electric-ax/durable-streams-server-rust是锚点包名,所有下游产物(crates.io 的 crate、四个 npm 平台包、Docker 镜像)都对齐这一个版本号。
  • sync-version脚本:即 scripts/sync-cargo-version.mjs,负责在发布前把package.json中的版本同步到Cargo.toml,保证 npm、crates.io、Docker 三个通道发布的是同一个版本。

从源码看版本同步的细节:脚本读取包根目录的package.json拿到version,然后用行锚定正则^version = "[^"]*"替换Cargo.toml[package]段的版本号。它特意只用行锚定,因为依赖项写法是foo = { version = "..." }(不是行首version =),所以只有 crate 自身的版本会被命中;如果替换后没有变化且目标版本字符串本就不存在,脚本会直接抛错,防止"发布了一个版本未同步的 crate"这种事故。

运行方式见 scripts/sync-cargo-version.mjs:在包根目录执行node scripts/sync-cargo-version.mjs,或通过 pnpm 的pnpm sync-version

二、发布总览:一次版本提升,三个通道并行分发

RELEASING.md 明确给出发布模型:通过 Changesets 发布,与 monorepo 其他包一致。流程是:

  1. durable-streams-rust添加一个 changeset(记录变更说明);
  2. 合并 Changesets 自动生成的 "Version Packages" PR;
  3. 版本提升后,changesets_release.yml工作流**扇出(fan out)**到三个通道,以同一版本发布:
通道发布产物关键工作流
crates.iodurable-streamscrate,可通过cargo install durable-streams安装server_rust_publish.yml
npm@electric-ax/durable-streams-server-rust锚点包 + 四个平台二进制包server_rust_publish.yml
Docker Hubelectricax/durable-streams-server-rust(multi-arch 镜像)server_rust_dockerhub_image.yml

当前发布边界(务必先读)npm 发布目前处于禁用状态。一次发布只发布 crate(crates.io)和 Docker 镜像,不会发布 npm 包——server_rust_publish.yml中的npm-publish任务被门控关闭(在文件中搜索DISABLED:标记)。准备好后再重新启用 npm 包发布。另外,合并时的 canary Docker 构建也是关闭的,但发布镜像仍然照常推送。

也就是说:即使 CI 全绿,@electric-ax/durable-streams-server-rust及其平台包当前也不会出现在 npm 上,这一点在验收发布结果时要格外注意。

三、crates.io 通道:durable-streamscrate

crates.io 上发布的是名为durable-streams的 crate。从 Cargo.toml 可以看清命名与产物细节:

[package] name = "durable-streams" version = "0.1.0" # 仓库内当前值;发布时由 sync-cargo-version.mjs 从 package.json 同步 edition = "2021" description = "High-performance Durable Streams server (Rust)" license = "Apache-2.0" rust-version = "1.75" # CI 在 stable 上构建,这里记录支持的最低版本 # crate 名为 durable-streams(裸名 durable-streams-server 在 crates.io 上已被占用), # 但产出的二进制保留历史名称,保证 conformance 测试、发布工作流和文档不受影响。 [[bin]] name = "durable-streams-server" path = "src/main.rs"

值得注意的两点:

  • crate 名与二进制名解耦:crates.io 上的包名是durable-streams(裸名durable-streams-server已被占用),但cargo install durable-streams安装下来后,你得到的可执行文件仍然叫durable-streams-server。这样 conformance 测试、发布工作流与既有文档都不必改名。
  • 版本在发布时同步:仓库中的Cargo.toml保持 0.1.0,真正发布到 crates.io 的版本由server_rust_publish.yml在发布前调用同步脚本写入。这也解释了为什么 CHANGELOG.md 与 package.json 的版本(0.1.5)会高于仓库内Cargo.toml的版本。

crates.io 发布走server_rust_publish.yml,认证方式见第六节(OIDC Trusted Publishing,CI 不存注册表 token)。

四、npm 通道:锚点包 + 四个平台包

npm 通道的产物结构是"一个主包 + 四个平台二进制包",全部由 npm/assemble.mjs 在发布前组装生成:

  • 主包@electric-ax/durable-streams-server-rust:不携带任何二进制,只包含bin/launcher.cjs启动器、targets.json平台清单和 README,通过optionalDependencies按需拉取对应的平台包(见 npm/templates/main.package.json)。
  • 四个平台包:每个包含一个预编译好的原生二进制bin/durable-streams-server,并在package.json中声明oscpu和可选的libc约束,确保 npm 只在你当前平台安装正确的包。

平台矩阵定义在 npm/targets.json:

npm 平台包Rust targetoscpulibc
@electric-ax/durable-streams-server-rust-linux-x64x86_64-unknown-linux-gnulinuxx64glibc
@electric-ax/durable-streams-server-rust-linux-arm64aarch64-unknown-linux-gnulinuxarm64glibc
@electric-ax/durable-streams-server-rust-darwin-x64x86_64-apple-darwindarwinx64
@electric-ax/durable-streams-server-rust-darwin-arm64aarch64-apple-darwindarwinarm64

从 npm/assemble.mjs 可以看到组装逻辑的关键点:

  1. 读取targets.json,为每个目标在binsDir/<rustTarget>/durable-streams-server找编译产物,找不到就抛错(防止带着缺失平台二进制发布);
  2. 把二进制复制进平台包的bin/目录并chmod 0o755(保证可执行位);
  3. 用模板 npm/templates/platform.package.json 生成平台包package.json,注入os/cpu/libc同一版本号
  4. 主包optionalDependencies中的每个平台包都被钉死在该版本optionalDependencies[t.pkg] = version),保证npm install拿到的是配套二进制;
  5. 最后输出顺序是"平台包在前、主包在后"——这正是发布顺序:先发平台包,再发主包,避免主包发布时引用的平台包尚不存在。

由于当前 npm 发布被门控关闭(见第二节),这部分逻辑由 CI 触发但不会真正推送;同时 RELEASING.md 指出:npm 侧的 trusted publishers 尚未配置,这也是 npm 发布重新启用前必须补齐的前置条件之一。

五、Docker Hub 通道:multi-arch 镜像

Docker Hub 上发布electricax/durable-streams-server-rust,multi-arch(多架构)镜像,由server_rust_dockerhub_image.yml负责。

镜像构建细节可以对照 Dockerfile 理解:

  • 多阶段构建:第一阶段基于rust:1-bookwormcargo build --release --locked编译(--locked保证按Cargo.lock精确构建);第二阶段基于gcr.io/distroless/cc-debian12只拷贝二进制,无 shell、无包管理器,镜像体积最小化。
  • 构建上下文控制:Dockerfile 只拷贝Cargo.tomlCargo.locksrc/,不拷贝target/npm/,因此不依赖仓库根目录的.dockerignore
  • 默认特性:构建使用默认 features(不带tier/telemetry),镜像最小且与 conformance 测试矩阵一致。Dockerfile 注释明确提示:要发布 S3 分层存储能力,需要在构建命令中加--features tier并且在 runtime 阶段额外安装ca-certificates
  • 运行默认值EXPOSE 4437(协议默认端口);ENTRYPOINT为服务端二进制,CMD ["--host", "0.0.0.0"]——因为二进制默认只绑定127.0.0.1,容器外无法访问,所以镜像默认绑定所有接口;持久化需要挂载卷并追加--data-dir(默认是临时目录)。

六、认证与安全:OIDC Trusted Publishing

两个注册表(crates.io 与 npm)都通过OIDC Trusted Publishing进行身份认证,因此CI 中不存储任何注册表 token。这是现代发布管线的安全最佳实践:认证凭证由 CI 平台(如 GitHub Actions)与注册表之间直接协商,密钥从不落盘到仓库或 secrets 中。

当前状态(RELEASING.md 原文事实):

  • durable-streamscrate 已在 crates.io保留名称,其 Trusted Publishing 已配置完成;
  • npm 侧的 trusted publishers仍待配置,在完成配置之前 npm 发布不应被重新启用。

七、发布操作步骤速查

综合 RELEASING.md 与上述源码细节,一个完整的发布周期是:

  1. 写 changeset:在仓库中为durable-streams-rust添加一个 changeset,按 semver 声明是 patch / minor / major,并附上变更描述(仓库历史可参考 CHANGELOG.md,例如 0.1.5 记录的是 memory-mode CPU 修复与恢复硬化,0.1.4 记录的是写路径性能重构与崩溃恢复修复)。
  2. 合并 "Version Packages" PR:Changesets 机器人会提交一个 PR,把锚点包 package.json 的version提升到新版本。合并该 PR 即触发版本提升。
  3. CI 扇出发布changesets_release.yml在版本提升后触发三个通道:
    • server_rust_publish.yml:先跑 scripts/sync-cargo-version.mjs 把package.json版本同步进Cargo.toml,再发布durable-streamscrate;同时组装并发布 npm 包(当前npm-publish任务被DISABLED:门控关闭)。
    • server_rust_dockerhub_image.yml:按 arch 构建 multi-arch 镜像并推送electricax/durable-streams-server-rust
  4. 验证:用cargo install durable-streams验证 crates.io 版本;docker pull electricax/durable-streams-server-rust并核对多架构清单;同时确认 npm 上没有意外出现新版本(当前预期行为)。

八、发布相关注意事项小结

  • 版本必须始终一致:crates.io、npm 平台包、Docker 镜像共用package.json中的同一个版本号,依赖sync-cargo-version.mjsassemble.mjs在发布时注入;改动发布流水线时不要绕过这两处。
  • 平台包钉死版本:主包的optionalDependencies用精确版本引用平台包,发布顺序必须是"平台包先、主包后",否则会出现安装时找不到对应版本的问题。
  • Cargo.toml 同步失败即中止:同步脚本在找不到[package]版本可替换时会抛错,防止静默发布错误版本。
  • 镜像默认特性最小化:当前 Docker 镜像不包含tier/telemetryfeature;若未来要发布 S3 分层能力,需同时改 Dockerfile 的构建参数与 runtime 依赖(ca-certificates)。
  • 重新启用 npm 的前置条件:解除server_rust_publish.yml中的DISABLED:门控,并完成 npm 侧的 OIDC trusted publishers 配置;在此之前,crates.io 与 Docker Hub 是唯一生效的发布通道。

【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric

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

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

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

立即咨询