拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Jujutsu 版本发布完全指南:从 CHANGELOG 整理到 crates.io 上线的全流程

Jujutsu 版本发布完全指南从 CHANGELOG 整理到 crates.io 上线的全流程【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj本文基于 jj 仓库的官方发布流程文档web/docs/src/content/docs/releasing.md与 docs/releasing.md 内容一致完整讲解 Jujutsujj项目维护者如何发布一个新版本包括更新 CHANGELOG 与统一管理 Cargo 版本号、借助 jj 自身的变更集changeset能力生成 Changelog diff 与贡献者名单、在 GitHub 上打 tag 并创建 Release以及按依赖顺序将各 crate 发布到 crates.io。读完本文你将掌握 jj 项目完整的发版 SOP并能直接套用到自己维护的 Rust workspace 项目中。发布前的准备更新 CHANGELOG 与 Cargo 版本一次正式的 jj 发版第一步不是打 tag而是准备一个包含CHANGELOG 更新 Cargo 版本号变更的 Pull Request参考 jj 历史中类似 PR #7954 的做法。这个 PR 通过评审并合并后才进入打 tag 阶段。整理 CHANGELOG 的四个检查要点在准备该 PR 时可以对 CHANGELOG 内容做自由改写copy-edit重点核对以下四点必要时填充 Release highlights 小节重大版本需要在 CHANGELOG 顶部用简短段落概括本版本最值得关注的亮点把更重要的条目排在前面避免读者错过关键变更统一条目的语言与格式保持整份文档风格一致通过查看 CHANGELOG 的 diff 找出放错位置的条目例如把Fixed bugs误写进New features。用 jj 自身生成 CHANGELOG diff项目利用 jj 的 revset 与 diff 能力直接从版本历史中提取上一个 tag 到main之间的 CHANGELOG 改动jj log -r heads(tags()) # 检查该 revset 是否显示上一个版本 jj diff --from heads(tags()) --to main CHANGELOG.md这里heads(tags())表示所有 tag 中最新的那个即上一个发版提交jj diff --from ... --to ...则精确展示两次提交之间 CHANGELOG.md 的变更便于逐条核对每个条目是否都进了正确的小节。补充版本对比引用链接在 CHANGELOG 文件底部有一组引用链接reference link形如[unreleased]: https://github.com/jj-vcs/jj/compare/v0.45.1...HEAD [0.45.1]: https://github.com/jj-vcs/jj/compare/v0.45.0...v0.45.1发布新版本时需要做两件事为新版本的 tag添加一条对比链接格式为上一个版本 tag 与当前版本 tag 的 compare URL例如https://github.com/jj-vcs/jj/compare/v0.32.0...v0.33.0同时把[unreleased]链接更新为最新版本 tag 对比 HEAD。在 CHANGELOG.md 底部可以看到这条既成的约定当前仓库的[unreleased]为v0.45.1...HEAD而[0.45.1]为v0.45.0...v0.45.1逐版本串成一条完整的对比链。CHANGELOG 的格式规范从 CHANGELOG.md 的头部可见本项目遵循两个公开约定Keep a Changelog每个版本小节下统一使用### Release highlights、### Breaking changes、### Deprecations、### New features、### Fixed bugs等固定小节Semantic Versioning版本号按主.次.补丁规则递增每个小节以## [版本号] - 日期作为标题例如## [0.45.1] - 2026-09-03。Cargo 版本号的统一管理workspace.package.versionjj 是一个 Cargo workspace所有 crate 的版本号都从根 Cargo.toml 的[workspace.package]统一继承[workspace.package] version 0.45.1 rust-version 1.89 edition 2024各成员 cratecli、core、core/proc-macros、lib、lib/gen-protos、lib/testutils在自己的Cargo.toml中通过version { workspace true }引用因此发版时只需要在根 Cargo.toml 改一处版本号。这一点可以在 lib/Cargo.toml、core/Cargo.toml、cli/Cargo.toml 等处逐一验证。值得留意的是根 Cargo.toml 中rust-version 1.89旁边有一行注释提醒维护者升级最低 Rust 版本时还要同步更新 CI、mise.toml、contributing.md、changelog.md 和 install-and-setup.md 等相关文件避免文档与代码事实脱节。也就是说发版 PR 不仅要改版本号与 CHANGELOG也要顺带检查这类跨文件的一致性。另外版本号与 CLI 输出直接关联jj version命令的实现位于 cli/src/commands/version.rs它通过command.app().render_version()渲染版本信息因此 workspace 版本号一旦更新用户通过jj version看到的版本也会随之变化。生成贡献者名单整理贡献者名单有点麻烦文档给出了两套方案。方案一通过 GitHub REST API推荐利用 jj 的 revset 先算出上一个版本 tag 到trunk()主干之间的全部提交的根提交再调用 GitHub 的 compare API 分页拉取提交列表并用jq去重、格式化root$(jj log --no-graph -r heads(tags(glob:v*.*.*) ::trunk()) -T commit_id) filter map(.commits[] | select(.author.login | endswith([bot]) | not)) | unique_by(.author.login) | map(* \(.commit.author.name) (\(.author.login))) | .[] gh api /repos/jj-vcs/jj/compare/$root...main --paginate | jq -sr $filter | sort -f其中filter的作用是过滤掉以[bot]结尾的机器人账号、按作者 login 去重、再输出* 姓名 (用户名)的 Markdown 列表格式。方案二纯本地生成不依赖网络 APIjj log --no-graph -r heads(tags())..main -T * author \n | sort -fu此方案直接枚举heads(tags())..main范围内所有提交的作者并去重排序。由于 jj 本地只存作者名author模板字段还需要手动为每个人找到对应的 GitHub 用户名并从对方的 GitHub 主页复制姓名与用户名补进名单。相比之下方案一能直接产出姓名用户名的完整格式省去手工匹配。名单整理完成后与 CHANGELOG、Cargo 版本号改动一起提交 PR走常规评审流程合并。打 tag 与创建 GitHub ReleasePR 合并后在 GitHub Releases 页面完成打 tag 与发布文档给出的操作步骤如下进入仓库的Releases页面点击 Draft a new release点击 Choose a tag输入v0.number.0例如v0.26.0以创建新 tag点击 Target → Recent commits选中刚合并的发版 PR 对应的提交以 tag 名称如v0.26.0作为 Release title把 CHANGELOG 中新版本对应的条目粘贴到正文勾选 Create a discussion for this release方便社区围绕该版本展开讨论点击 Publish release 完成发布。将 crate 发布到 crates.io为什么必须从全新 clone 发布发布前先在临时目录创建一个全新的仓库 clonecd $(mktemp -d) jj git clone https://github.com/jj-vcs/jj cd jj jj new v0.number.0jj new v0.number.0会把工作副本切换到刚打好的 tag 提交上。文档特别强调建议从全新 clone 发布原因是一个安全风险cargo publish打包时会包含[include]模式匹配到的、即使已被 git 忽略的文件。如果在长期使用的本地 clone 里发布忽略文件中可能遗留敏感内容密钥、凭据等而被一并打进 crate 包。在 lib/Cargo.toml 可以看到这种include字段的真实写法include [ /LICENSE, /src/, /tests/, !*.pending-snap, !*.snap*, ]cli/Cargo.toml同样有include [/LICENSE, /build.rs, /examples/, /src/, ...]的配置。在陌生环境的新 clone 中工作目录干净、无残留敏感文件可以把这个风险降到最低。按依赖顺序逐个发布 cratejj 的 Rust workspace 包含 6 个成员 crate见根 Cargo.toml[workspace] members [ cli, core, core/proc-macros, lib, lib/gen-protos, lib/testutils, ]但并非所有 crate 都需要发布从 lib/gen-protos/Cargo.toml 和 lib/testutils/Cargo.toml 可以看到这两个 crate 都声明了publish false它们只是构建期工具与测试辅助库不进入 crates.io。真正需要发布的 crate 及依赖关系为jj-core-proc-macroscore/proc-macrosjj-core的派生宏必须先发布jj-corecore依赖jj-core-proc-macros核心类型与算法jj-liblib依赖jj-core核心库实现jj-clicli依赖jj-lib最终命令行程序。因此发布命令依次为(cd core/proc-macros cargo publish) (cd core cargo publish) (cd lib cargo publish) (cd cli cargo publish)原文档发布时仓库结构为lib/proc-macros、lib、cli三个 crate命令为(cd lib/proc-macros cargo publish)、(cd lib cargo publish)、(cd cli cargo publish)当前仓库因拆分出jj-core而多出一层依赖CHANGELOG.md 中0.45.1版本条目明确提到修复了新的 jj-core crate 无法发布的问题印证了这一依赖顺序的必要性。每个 crate 依次发布前一个成功后再发布下一个确保 crates.io 上的依赖版本始终可用。小结一次完整发版的检查清单把整个流程收拢成一份可执行的清单准备发版 PR基于heads(tags())与main的 diff 整理 CHANGELOG.md填充 Release highlights、按重要性排序、统一格式、归位错放的条目在文件底部添加新版本 compare 引用链接并更新[unreleased]链接升级版本号修改根 Cargo.toml 中[workspace.package] version及各 crate 继承的版本生成贡献者名单优先用gh apijq方案提交并合并 PR打 tag 并发 GitHub Release以v0.number.0命名 tag指向发版 PR 的提交粘贴 CHANGELOG 内容勾选讨论区后发布发布 crates.io在mktemp -d的全新 clone 中jj new v0.number.0切到 tag再按jj-core-proc-macros → jj-core → jj-lib → jj-cli的依赖顺序逐个cargo publish。整个过程的一个独特之处在于整个发版流程大量使用 jj 自身的命令jj log、jj diff、jj new、revset 表达式heads(tags())、::trunk()等来辅助版本管理——用 jj 来发布 jj既是流程也是对新版本自身能力的一次实战检验。【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门