如何自动化检查 semver?

解读

在国内 Rust 岗位面试中,面试官问“如何自动化检查 semver”并不是想听你背诵语义化版本规范,而是考察你是否理解 Rust 生态对兼容性承诺的严苛要求、是否能把 Cargo 内置机制与 CI 实践结合,以及能否在 多人协作、闭源 crate、monorepo、国内网络环境 下给出可落地的方案。回答时要突出“零人工干预”“编译即正确”的 Rust 文化,并体现你对 cargo-semver-checks、public API 边界、国内镜像源、合规审计 四个维度的闭环思考。

知识点

  1. semver 的 Rust 释义:Cargo 把“不兼容”定义为“public API 的破坏性变更”,与语言层级的 orphan rule、trait coherence 直接挂钩。
  2. cargo-semver-checks:基于 rustdoc JSON 的静态分析工具,无需发布到 crates.io 即可本地跑,可在 GitHub Actions / Gitee Go / Jenkins 中零成本落地。
  3. public API 边界:#[doc(hidden)]、semver-exempt、feature-gate 都会改变扫描范围,必须让 CI 与 deny list 保持一致
  4. 国内 CI 网络:crates.io-index 同步延迟、GitHub API 限流,需要把 toolchain 与缓存托管到 腾讯云 COS / 阿里云 OSS + 自建 git 镜像
  5. 合规审计:金融、车载、信创项目要求“升级前必须有兼容性报告”,cargo-semver-checks 生成的 JSON 报告可直接对接内部审批系统

答案

在工程里用三行命令完成“编译期自动 semver 审计”:

  1. 在 Cargo.toml 增加
    [workspace.metadata.ci]
    semver-checks = "1.0"
    把 cargo-semver-checks 锁进 toolchain,避免 CI 拉不到外网最新版

  2. 在 GitHub Actions / Gitee Go 里加一步:

    • name: Semver Check
      run: |
      cargo install --version 1.0.0 cargo-semver-checks --locked
      cargo semver-checks check-release --only-explicit-features
      --only-explicit-features 保证未启用的 feature 代码不会被当成 public API,防止误报。
  3. 把报告上传到内部评审系统:
    cargo semver-checks check-release --output-format json > semver.json
    通过企业微信机器人或钉钉群推送“本次 MR 引入 0 项破坏性变更”,实现“编译通过即兼容”。

若项目未发布到 crates.io,只需在 CI 里先跑
cargo doc --no-deps -Z unstable-options --output-format json
再跑 cargo-semver-checks,即可完全离线比对 baseline,解决国内网络隔离痛点。

拓展思考

  1. monorepo 场景:多个 crate 相互依赖时,把 baseline JSON 存到 git LFS,在 PR 阶段只重扫发生变更的子树,可将 CI 时间从 15 min 降到 2 min。
  2. 闭源交付:甲方要求“任何补丁升级都不能改 API”,可在 release pipeline 里把 semver.json 写进 SBOM(软件物料清单),作为合规证据留存三年。
  3. ABI 兼容:cargo-semver-checks 只覆盖 Rust 语义层;若动态库通过 FFI 暴露,需要再跑 rust-abi-checker,把报告合并到同一 JSON,实现“源码级 + ABI 级双重门禁”。