core-agent-ide/codex-rs/docs/bazel.md
Josh McKinney de93cef5b7
bazel: enforce MODULE.bazel.lock sync with Cargo.lock (#11790)
## Why this change

When Cargo dependencies change, it is easy to end up with an unexpected
local diff in
`MODULE.bazel.lock` after running Bazel. That creates noisy working
copies and pushes lockfile fixes
later in the cycle. This change addresses that pain point directly.

## What this change enforces

The expected invariant is: after dependency updates, `MODULE.bazel.lock`
is already in sync with
Cargo resolution. In practice, running `bazel mod deps` should not
mutate the lockfile in a clean
state. If it does, the dependency update is incomplete.

## How this is enforced

This change adds a single lockfile check script that snapshots
`MODULE.bazel.lock`, runs
`bazel mod deps`, and fails if the file changes. The same check is wired
into local workflow
commands (`just bazel-lock-update` and `just bazel-lock-check`) and into
Bazel CI (Linux x86_64 job)
so drift is caught early and consistently. The developer documentation
is updated in
`codex-rs/docs/bazel.md` and `AGENTS.md` to make the expected flow
explicit.

`MODULE.bazel.lock` is also refreshed in this PR to match the current
Cargo dependency resolution.

## Expected developer workflow

After changing `Cargo.toml` or `Cargo.lock`, run `just
bazel-lock-update`, then run
`just bazel-lock-check`, and include any resulting `MODULE.bazel.lock`
update in the same change.

## Testing

Ran `just bazel-lock-check` locally.
2026-02-14 02:11:19 +00:00

2.7 KiB

Bazel in codex-rs

This repository uses Bazel to build the Rust workspace under codex-rs. Cargo remains the source of truth for crates and features, while Bazel provides hermetic builds, toolchains, and cross-platform artifacts.

As of 1/9/2026, this setup is still experimental as we stabilize it.

High-level layout

  • ../MODULE.bazel defines Bazel dependencies and Rust toolchains.
  • rules_rs imports third-party crates from codex-rs/Cargo.toml and codex-rs/Cargo.lock via crate.from_cargo(...) and exposes them under @crates.
  • ../defs.bzl provides codex_rust_crate, which wraps rust_library, rust_binary, and rust_test so Bazel targets line up with Cargo conventions. It provides a sane set of defaults that work for most first-party crates, but may need tweaks in some cases.
  • Each crate in codex-rs/*/BUILD.bazel typically uses codex_rust_crate and makes some adjustments if the crate needs additional compile-time or runtime data, or other customizations.

Evolving the setup

When you add or change Rust dependencies, update the Cargo.toml/Cargo.lock as normal. Then refresh the Bzlmod lockfile from the repo root:

just bazel-lock-update

This runs bazel mod deps --lockfile_mode=update and updates MODULE.bazel.lock if needed. Commit the lockfile changes along with your Cargo lockfile update.

To verify lockfile alignment locally (the same check CI runs), use:

just bazel-lock-check

In some cases, an upstream crate may need a patch or a crate.annotation in ../MODULE.bzl to have it build in Bazel's sandbox or make it cross-compilation-friendly. If you see issues, feel free to ping zbarsky or mbolin.

When you add a new crate or binary:

  1. Add it to the Cargo workspace as usual.
  2. Create a BUILD.bazel that calls codex_rust_crate (see nearby crates for examples).
  3. If a dependency needs special handling (compile/runtime data, additional binaries for integration tests, env vars, etc) you may need to adjust the parameters to codex_rust_crate to configure it. One common customization is setting test_tags = ["no-sandbox] to run the test unsandboxed. Prefer to avoid it, but it is necessary in some cases such as when the test itself uses Seatbelt (the sandbox does as well, and it cannot be nested). To limit the blast radius, consider isolating such tests to a separate crate.

If you see build issue and are not sure how to apply the proper customizations, feel free to ping zbarsky or mbolin.

References