ci: run every Rust validation through Bazel, drop cargo - #466
Merged
Conversation
tinder-maxwellelliott
marked this pull request as ready for review
August 17, 2026 21:04
CI installed a host Rust toolchain and shelled out to cargo for four checks (fmt, clippy, unit tests, e2e) plus a separate 1.85 toolchain for the MSRV job. That is a second build system's worth of setup to maintain, and it pinned the checks to whatever rustc `dtolnay/rust-toolchain@stable` resolved to on the day rather than the compiler MODULE.bazel names -- so CI and a local `bazel test` could disagree. Each check now has a Bazel target: cargo fmt --all -- --check -> //:rust_format_check cargo clippy --all-targets -> //:rust_clippy_check cargo test --lib --bins -> //:rust_tests (already existed) cargo test --test e2e -> //tests:e2e_test cargo check (Rust 1.85) -> build with --extra_toolchains=...rust_msrv The lint gates pin an explicit root list rather than relying on the .bazelrc aspects. Neither aspect propagates along deps, so an aspect-only gate covers only the targets a build happens to name -- which is why nothing was checking tools/coverage. It was unformatted; `bazel run //cli/format:rustfmt` (new, and what `make format` now calls) fixed it. The e2e suite needed two changes to run under Bazel. Its support helpers read CARGO_MANIFEST_DIR and CARGO_BIN_EXE_*, which do not exist outside cargo, so they now prefer runfiles and keep the cargo values as a fallback -- `cargo test` still works locally. And the nested Bazel each fixture spawns is now chosen by $BAZEL: inside a Bazel test the first `bazel` on PATH is the outer Bazel's own binary, which ignores USE_BAZEL_VERSION, and two fixtures are version-sensitive enough to silently produce wrong results because of it. MSRV keeps its own toolchain in MODULE.bazel, registered but deliberately not preferred; the job selects it with --extra_toolchains and drops the lint output groups, since 1.85's clippy carries a different lint set and would fail that job for reasons unrelated to MSRV. perf-gate.yaml loses its Setup Rust step too -- that job already built through Bazel and never used it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tinder-maxwellelliott
force-pushed
the
claude/bazel-only-ci-68fbab
branch
from
August 17, 2026 21:10
bbe36c2 to
144e869
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CI installed a host Rust toolchain and shelled out to cargo for four checks, plus a second toolchain for MSRV. That is a second build system's worth of setup to maintain, and it pinned the checks to whatever rustc
dtolnay/rust-toolchain@stableresolved to on the day rather than the compilerMODULE.bazelnames — so CI and a localbazel testcould disagree. Every Rust validation now runs through Bazel.What replaced what
cargo fmt --all -- --check//:rust_format_check(rustfmt_test, transitive)cargo clippy --all-targets -- -D warnings//:rust_clippy_check(rust_clippy_test, transitive)cargo test --lib --bins//:rust_tests(already existed)cargo test --test e2e//tests:e2e_test(newrust_test)cargo checkon Rust 1.85bazel build //src:bazel-diff --extra_toolchains=…rust_msrv…perf-gate.yamlalso loses itsSetup Ruststep — that job already built through Bazel and never used it.Notes for review
The lint gates pin roots rather than relying on the
.bazelrcaspects. Neitherrust_clippy_aspectnorrustfmt_aspectpropagates alongdeps, so an aspect-only gate covers just the targets a build happens to name. That was already true of the existing clippy setup and meant nothing was checkingtools/coverage— it turned out to be unformatted.bazel run //cli/format:rustfmtis new and fixes it;make formatnow calls it instead ofcargo fmt --all, which only ever saw the root crate. The aspects stay in.bazelrcfor fast local feedback.The e2e port needed two changes. Its support helpers read
CARGO_MANIFEST_DIRandCARGO_BIN_EXE_*, which don't exist outside cargo, so they now prefer runfiles and keep the cargo values as a fallback —cargo teststill works locally. Separately, the nested Bazel each fixture spawns is now chosen by$BAZEL: inside a Bazel test the firstbazelonPATHis the outer Bazel's own binary, which ignoresUSE_BAZEL_VERSION, and two fixtures are version-sensitive enough that this silently produced wrong results.find_bazel()already checked$BAZELfirst, so this is a config change, not a code one.MSRV keeps its own toolchain, declared in
MODULE.bazeland registered but deliberately not preferred (rules_rust appendsrepository_settoolchains after the defaults). The job selects it with--extra_toolchainsand drops the lint output groups, since 1.85's clippy carries a different lint set and would fail that job for reasons unrelated to MSRV. It's Linux/x86_64 only — arepository_settag declares one exec triple, and the job runs onubuntu-latest. On another host the build just falls back to the default toolchain rather than failing.Rebasing onto #465 conflicted here, and the resolution is worth a look: that PR gated the stock Rust toolchains to
//platforms:is_system_libcso exactly one toolchain matches any build. The MSRV set carries the same gate and//platforms:system_libcin itstarget_compatible_with, so it doesn't reintroduce the ambiguity #465 removed on//platforms:linux_x86_64_musl.Verification
Locally on macOS: both lint gates,
//:rust_tests, the tools tests, and a--config=releasebuild all pass.The e2e suite is 32/36. The 4 failures are
external::*fixtures whose nested Bazel needs a JDK, and this machine has none (/usr/bin/javais the macOS stub) — each fails with "Unable to locate a Java Runtime", and I confirmed one fails identically undercargo testhere. That job installs Temurin 21, so they should pass in CI, but that is the specific claim I could not verify locally and the thing to watch on the first run.🤖 Generated with Claude Code