wgpu 发布流程实战指南:从版本号到 crates.io 的大版本与小版本发布全流程
【免费下载链接】wgpuA cross-platform, safe, pure-Rust graphics API.项目地址: https://gitcode.com/GitHub_Trending/wg/wgpu
本篇指南基于 docs/release-checklist.md 编写,完整梳理 wgpu 项目(一个跨平台、安全、纯 Rust 的图形 API)的官方发布流程:包括每 12 周一次的大版本(Major)破坏性发布、按需进行的补丁(Patch)发布,以及发布前的依赖协调、CHANGELOG 整理、版本号同步、crates.io 发布、Git 标签创建、分支维护与社区公告等全部环节。读完本文,你将掌握一套可直接照搬的 wgpu 发布操作手册,并理解其背后的仓库结构(如工作区版本继承、publish = false的 crate、CHANGELOG 分类约定)是如何支撑这套流程的。
发布模型总览:固定节奏 + 按需补丁
wgpu 采用"固定大版本 + 灵活补丁"的双轨发布模型,这一点在 docs/release-checklist.md 的Structure一节有明确约定:
- 大版本(Major):每12 周发布一次带有破坏性变更的版本,且无论当时有多少进行中的功能(in-flight projects)尚未完成,都按时发布。这一硬性节奏保证了下游生态(如 Bevy、Firefox 等)有一个可预期的升级窗口。
- 补丁版本(Patch):在两个大版本之间的数周内,按需发布。一旦新的 major 版本发布,除非遇到关键 Bug 或编译问题,否则停止为上一个 major 版本继续打补丁。
谁可以执行发布?
流程对人员没有严格的排他性限制:@gfx-rs/wgpu团队的任意成员都可以按照 checklist 执行发布。这要求整套流程高度文档化、步骤可复现——这正是本清单存在的意义。
版本号从哪里来?
发布流程的起点是根目录 Cargo.toml 中的[workspace.package]版本号。当前仓库的版本配置如下:
[workspace.package] edition = "2021" rust-version = "1.93" license = "MIT OR Apache-2.0" version = "30.0.0"这是整个工作区(workspace)的单一版本事实来源:wgpu、wgpu-core、wgpu-hal、wgpu-types、naga、naga-types、wgpu-core-remote、wgpu-sync、wgpu-naga-bridge等 crate 都通过version.workspace = true继承这个版本号。因此 checklist 中的第一条"更新根Cargo.toml的版本号,就会更新所有 crate 的版本"是有据可依的——例如 wgpu/Cargo.toml 中的version.workspace = true与 naga/Cargo.toml 中的version.workspace = true。
值得注意的是,wgpu与naga各自在[package]中覆盖了rust-version(两者均为1.87,低于工作区的1.93),这是为了给下游用户更宽松的 MSRV 升级空间,发布时无需(也不应)改动这两处。
大版本(Major)发布:发布前约 1 周的准备
大版本发布不是"当天改个号就发",流程要求提前约一周开始准备,核心工作有两项:依赖 crate 协调与 CHANGELOG 整理。
1. 协调上游依赖 crate 的发布
发布前需要判断依赖树中的关键 crate 是否也要同步发布新版本,典型代表是:
glow(GLES 后端的 OpenGL 绑定库,维护者为 @groves);rspirv(SPIR-V 汇编/反汇编库,由@gfx-rs/wgpu团队维护);- 以及其他被 wgpu 依赖、且本次发布需要新版本的 crate。
如果需要,必须提前与这些 crate 的维护者协调发布时间,确保 crates.io 上的依赖版本与 wgpu 新版本兼容。这一协调并非走过场:wgpu 的下游(尤其是 Firefox)对依赖版本极其敏感——如 docs/managing-cargo-dependencies.md 所述,Firefox 需要通过cargo-vet审计每一个引入的依赖,且会尽量避免 SemVer 不兼容升级带来的依赖重复。因此依赖版本的大幅变动会直接影响 wgpu 被下游接纳的难度。
2. 通读并整理 CHANGELOG
发布前需要过一遍 CHANGELOG.md,做四件事:
- 重新归类(Re-categorize)放错分类的条目;
- 改写重大变更,让用户一眼看懂"升级到新版本我需要改什么";
- 补充遗漏的重大变更,凡是用户升级时需要知晓的破坏性改动都不能缺;
- 通篇 copy-edit,保证文字清晰。
当前 CHANGELOG.md 的Unreleased段即展示了这套分类约定:顶层分类有Major changes、Added/New Features、Changes、Bug Fixes、Performance、Documentation、Dependency Updates、deno_webgpu、Examples、Testing/Internal;底层分类则有General、naga、Validation、DX12、Vulkan、Metal、GLES / OpenGL、WebGPU、Emscripten、Hal。条目通常以- 描述. By @作者 in [#PR号]的格式书写,重大变更还会附上diff形式的新旧代码对照,例如Unreleased中TEXTURE_COMPONENT_SWIZZLE功能对TextureViewDescriptor新增swizzle字段的迁移示例。
大版本发布:发布当天逐步操作
以下是 checklist 中"发布当天"的完整操作序列,按执行顺序展开。
1. 提升版本号
将根目录 Cargo.toml 的[workspace.package] version改为新版本号(如30.0.0→31.0.0)。由于所有 crate 均继承工作区版本,这一处修改即完成了全工作区的版本提升。
2. 同步 wgpu 依赖版本号(Bump)
除工作区自身外,还需要把对外暴露的wgpu依赖版本号同步到新版本,涉及位置:
- 根 Cargo.toml 的
[workspace.dependencies](如wgpu = { version = "30.0.0", path = "./wgpu", ... }); examples/standalone/*下的每个独立示例 crate;examples/bug-repro/*下的每个 Bug 复现 crate。
这些示例之所以需要单独 bump,是因为它们不通过path依赖本地代码,而是声明对 crates.io 发布版本的依赖。例如 examples/standalone/01_hello_compute/Cargo.toml 中写着:
[dependencies] wgpu = "30.0.0"这类 crate 会被克隆出去作为用户项目的起点(examples/README.md 明确说明它们"可以被克隆出仓库作为自己项目的起点"),因此其依赖版本必须始终指向已发布的 crates.io 版本,而不能指向工作区内部的 path 版本。
3. 全文搜索旧版本号,更新文档链接
用 grep 检索上一个版本号,确保仓库内的文档、示例说明中的版本链接均已更新。checklist 给出的示例:如果上一个版本是v24.0.0,则搜索v24与24.0两处。
grep -rn "v24\|24\.0" --include="*.md" --include="*.rs" --include="*.toml" .像 examples/README.md 顶部[!NOTE]中指向latest release branch v30的链接,就是这类需要随版本更新的典型位置。
4. 更新依赖 crate
如准备阶段协调的那样,将glow、rspirv(如需要)更新到最新版本。以当前仓库为例,根 Cargo.toml 中glow = "0.18"、rspirv = "0.13",v30.0.1 的 CHANGELOG 中也出现过"Updateglowto 0.18 for wasm64 support"这样的依赖更新条目。
5. 为 CHANGELOG 添加新版本标题
在 CHANGELOG.md 顶部(Unreleased之上)新增一个以版本号和日期命名的标题,例如## v30.0.0 (2026-07-01)。发布完成后,原Unreleased的全部内容就归属于该版本。
6. 创建 PR 并等待 CI
将所有版本号变更与 CHANGELOG 更新汇总为一个 PR。在等待 PR 合并期间,先做一次发布 dry-run:
cargo publish --dry-run --workspace --all-features --exclude deno_webgpu这条命令的细节值得注意:
--dry-run:不真正上传到 crates.io,只做打包、校验与本地验证;--workspace:遍历整个工作区;--all-features:以全部 feature 组合验证打包,避免某些 feature 下编译不过;--exclude deno_webgpu:排除deno_webgpu——它虽然在工作区 members 中,但publish = false(见 deno_webgpu/Cargo.toml),是 Deno 运行时内置的 WebGPU 实现,不通过 wgpu 的发布流程上 crates.io。
7. 合并 PR 并发布
- 待 PR 的 CI 通过且 dry-run 成功之后,(force) merge该 PR;
- 切回
trunk分支(git checkout trunk && git pull),确保在最新代码上发布; - 执行真正的发布命令,可直接整段粘贴到终端:
cargo publish --workspace --all-features --exclude deno_webgpu8. 处理新 crate 的 owner
如果本次发布产生了新发布的 crate(此前从未发布过),需要确保github:gfx-rs:wgpu被添加为该 crate 的 owner,以保证后续版本仍能由团队发布:
cargo owner --add github:gfx-rs:wgpu <crate-name>9. 打标签(Tags)
- 创建一个签名标签
vX.Y.Z并推送到仓库,例如:
git tag -s v30.0.0 -m "wgpu v30.0.0" git push origin v30.0.0- 对每一个参与发布的 crate(即所有可
publish且不属于deno*的 crate),再创建形如{crate_name}-vX.Y.Z的标签,例如wgpu-v30.0.0、wgpu-core-v30.0.0、wgpu-hal-v30.0.0、naga-v30.0.0等。这样下游可以精确定位某个 crate 的某个发布版本。
10. 创建 GitHub Release
在wgpu仓库基于刚打的vX.Y.Z标签创建一个新 release,正文内容使用本版本的 CHANGELOG。注意 GitHub Release 是社区与下游用户感知发布的主要入口,因此文案应直接复用已整理好的 changelog 段落。
11. 创建版本分支vX并清理示例提示
- 创建一个以新版本命名的新分支
vX(例如v30)并推送; - 在该分支上,移除 examples/README.md 顶部的
[!NOTE]提示块。该 NOTE 的内容是"这些示例面向 wgpu 开发版本,如需查看最新 crates.io 发布版的示例请前往 latest release branch"——版本分支上的示例对应已发布版本,不再需要这条提示。
12. 里程碑管理
- 完成(close)本次发布对应的 GitHub milestone;
- 创建下一个里程碑,时间设在 12 周之后,与下一个 major 发布对齐。
13. 更新发布清单本身
把本次发布中发现的任何流程改进、新增步骤、踩坑经验回写到 docs/release-checklist.md。这份文档是"活文档",每次发布后都应沉淀增量经验。
14. 社区公告
将 GitHub Release 链接发布到以下社区渠道(checklist 原文要求的发布位):
- r/rust子版块:发布帖子并添加一个AMA(Ask Me Anything)评论;
- r/rust_gamedev子版块:交叉转发(crosspost),同样附 AMA 评论;
- wgpu Matrix频道(
#wgpu:matrix.org); - Rust Gamedev Discord的
#crates与#wgpu频道; - Bevy Discord的
#rendering-dev频道; - Graphics Programming Discord的
#webgpu频道; - Rust Community Discord的
#games-and-graphics频道。
r/rust 的帖子短链接应一并包含在上述各渠道的转发中,方便社区统一跳转讨论。
补丁(Patch)发布流程:backport 的艺术
大版本之间的补丁发布流程与 major 流程部分重叠,但最大的差异在于如何把 trunk 上的修复搬回版本分支。
1. 枚举待 backport 的 PR
补丁发布的第一步是枚举所有尚未 backport 的 PR。这些 PR 在 GitHub 上带有PR: needs back-porting标签,可以通过标签筛选拉取完整列表。凡是合并进 trunk、但又需要进入最新发布分支的修复,都会被打上该标签。
2. 在自己的分支上 cherry-pick
不要直接在发布分支上操作。基于最新的发布分支(release branch)新建自己的分支,然后逐一 cherry-pick 需要 backport 的 PR。关键细节:修改这些提交时使用--append选项,以保留原作者(original authorship):
git checkout v30 git checkout -b backport-v30-fixes git cherry-pick --append <commit-sha-1> <commit-sha-2> ...--append会在保留原提交作者信息的同时追加说明,避免 commit 的作者被改写为执行 backport 的人,这对开源社区的贡献归属至关重要。
3. 清理标签
对每个已 backport 的 PR,移除needs-backport标签,避免下一次枚举时重复处理。
4. 更新 CHANGELOG 并创建 PR
修正 CHANGELOG 中本次补丁相关的条目(只保留真正进入补丁版本的改动),并在顶部添加新标题,例如## v30.0.1 (2026-08-21)。然后将版本号变更与 CHANGELOG 更新整合为一个 PR,目标分支是发布分支(而非 trunk)。
5. dry-run 与合并
与 major 流程相同,等待 PR 期间先跑 dry-run:
cargo publish --dry-run --workspace --all-features --exclude deno_webgpuCI 通过且 dry-run 成功后,(force) merge,然后checkout 版本分支并执行正式发布:
git checkout v30 git pull cargo publish --workspace --all-features --exclude deno_webgpu6. 创建 Release 与标签
在发布分支上基于新标签vX.Y.Z(如v30.0.1)创建 GitHub Release,正文包含本补丁版本的 CHANGELOG;同时对每个发布的 crate 创建{crate_name}-vX.Y.Z标签。
7. 将 changelog 与版本号 backport 回 trunk
补丁版本发布后,还需要把发布分支上的 CHANGELOG 与版本号改动同步回trunk,并特别注意:已发布的补丁版本中的 changelog 条目,绝不能残留在 trunk 的Unreleased段——否则会出现在下个大版本的 changelog 中,造成条目重复。
当前仓库正是这套流程的实例:CHANGELOG.md 中v30.0.1 (2026-08-21)的 WebGPU 条目明确标注"backported in #10105",而v30.0.0 (2026-07-01)紧随其后,二者之间不存在条目交叉——这正是 backport 后清理Unreleased的效果。
8. 更新发布清单
与 major 流程一致,将补丁流程中发现的改进回写到 docs/release-checklist.md。
仓库视角:这套流程背后的工程支撑
理解发布流程的最佳方式,是同时看清仓库中与发布相关的工程细节:
工作区版本继承
根 Cargo.toml 定义了约 30 个 workspace members(wgpu、wgpu-core、wgpu-hal、wgpu-types、naga、naga-types、wgpu-core-remote、wgpu-sync、wgpu-naga-bridge、benches、examples/features、examples/standalone/*、examples/bug-repro/*、player、tests、xtask等),并声明default-members保证日常构建范围。绝大多数 crate 通过version.workspace = true继承[workspace.package] version,这是"改一个版本号全仓生效"的机制基础。
特殊成员的处理
deno_webgpu:工作区成员,但publish = false(见 deno_webgpu/Cargo.toml),因此发布命令始终以--exclude deno_webgpu排除它;examples/standalone/*、examples/bug-repro/*:独立 crate 且大多publish = false(如 examples/standalone/01_hello_compute/Cargo.toml),但它们声明了对 crates.io 上wgpu版本号的依赖,所以每次 major 发布都必须同步 bump 其wgpu依赖;naga/hlsl-snapshots:根 Cargo.toml 的注释特别说明它"不能指定版本号"——一旦指定,发布naga时 crates.io 会去查找该版本的包,导致发布失败,因此它只能作为纯 path 依赖存在。这提醒我们:发布前检查所有 crate 的依赖声明方式(version + path、纯 path、纯 version)同样重要。
CI 与发布的关系
仓库的 .github/workflows/publish.yml 名为 "Publish",但其实际职责是:安装 wasm target 与wasm-bindgen-cli、构建全部 WebGPU 示例(cargo xtask run-wasm --no-serve),并在 trunk 分支上将生成的示例页面部署到wgpu-rs.github.io的examples/目录。也就是说,crates.io 的发布是由清单中的人工cargo publish命令完成的,CI 发布流程承担的是示例站点的持续部署。二者共同构成了"代码发布(crates.io)"与"示例站点发布(GitHub Pages)"的完整闭环。
CHANGELOG 的机器可读结构
CHANGELOG.md 头部用 HTML 注释给出了条目书写的完整规范(分类清单与示例格式),每个条目带 PR 链接与作者。规范化的分类结构让"重新归类"、"按版本切片生成 Release 正文"这些发布动作都可以半自动化执行,这也是发布 checklist 敢要求"通读整理 changelog"的前提。
发布全流程速查表
以下把 major 与 patch 两条流程浓缩为速查清单,便于发布执行者对照操作:
| 阶段 | Major 发布 | Patch 发布 |
|---|---|---|
| 节奏 | 每 12 周一次,破坏性变更,准时发布 | 按需,新 major 后仅修关键 Bug/编译问题 |
| 准备(提前 1 周) | 协调glow/rspirv等依赖 crate;整理 CHANGELOG(归类/改写/补漏/润色) | 枚举PR: needs back-porting标签 PR |
| 版本号 | 根 Cargo.toml[workspace.package] version | 同步到补丁版本号 |
| 依赖 bump | 根 Cargo.toml、examples/standalone/*、examples/bug-repro/* | 同左(按需) |
| 版本残留检查 | grep 上一版本号(如v24、24.0) | — |
| 变更落地 | 创建 PR → dry-run → CI 通过后 (force) merge → checkout trunk | 基于发布分支建自己的分支 cherry-pick(--append)→ 移除 label → PR 到发布分支 |
| 发布命令 | cargo publish --workspace --all-features --exclude deno_webgpu | 同左(在发布分支执行) |
| 新 crate | 添加github:gfx-rs:wgpu为 owner | — |
| 标签 | 签名 tagvX.Y.Z+ 各 crate{crate_name}-vX.Y.Z | 同左 |
| Release | 基于vX.Y.Z创建,正文用本版 CHANGELOG | 同左 |
| 分支 | 创建vX分支,移除 examples/README.md 顶部[!NOTE] | 将 changelog/版本号 backport 回 trunk,清理Unreleased残留条目 |
| 里程碑 | 完成旧里程碑,创建 12 周后的新里程碑 | — |
| 收尾 | 更新 checklist;向 r/rust(含 AMA)等 7+ 渠道发布公告 | 更新 checklist |
结语
wgpu 的发布流程是一套"固定节奏 + 严格 checklist + 明确的仓库工程支撑"的成熟实践:根 Cargo.toml 的版本继承机制让版本号同步只需一处修改;CHANGELOG 的强分类规范让重大变更对用户可读、可迁移;--exclude deno_webgpu与独立示例 crate 的依赖声明则界定了发布边界;而签名标签、per-crate 标签与vX分支共同构成了可回溯、可维护的版本历史。对于任何想要照搬这套发布体系的 Rust 工作区项目而言,docs/release-checklist.md 本身就是一份高质量的操作蓝本。
【免费下载链接】wgpuA cross-platform, safe, pure-Rust graphics API.项目地址: https://gitcode.com/GitHub_Trending/wg/wgpu
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考