Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7114985
fix(bazel): match per-crate opt-levels and stamp on Windows
claude Oct 6, 2026
558b65f
fix(bazel): keep Windows build-script headers under MAX_PATH
claude Oct 6, 2026
f46beb2
fix(bazel): run Windows genrules and stamping without bash lookups
claude Oct 6, 2026
14b8ffd
fix(bazel): build serde_json and unit tests with Cargo's features
claude Oct 6, 2026
db0abfd
fix(bazel): run tests from their crate and patch aws-lc's long include
claude Oct 6, 2026
efca741
test(sessions): count the refused Pi fixture line
claude Oct 6, 2026
2fc3e2a
ci: scope validation queues to each pull request
ScriptedAlchemy Oct 6, 2026
b39e82d
perf(bazel): resolve test features once for the whole workspace
claude Oct 6, 2026
6fa1005
fix(hosts): prefer installed executables over Bazel outputs
ScriptedAlchemy Oct 6, 2026
68ff1ee
fix(bazel): preserve test runtime features and isolation
ScriptedAlchemy Oct 6, 2026
5f6269c
ci: expose Windows launcher and compiler failure inputs
ScriptedAlchemy Oct 6, 2026
c525658
Merge remote-tracking branch 'origin/claude/bazel-windows-fixes' into…
ScriptedAlchemy Oct 6, 2026
b7d27ef
fix(bazel): apply platform overrides after generic defaults
ScriptedAlchemy Oct 6, 2026
2121f5d
test(sessions): bind the Pi fixture's ninth line
claude Oct 6, 2026
a24afd2
fix(bazel): give tests one resolution and the binaries Cargo would spawn
claude Oct 6, 2026
debb3f4
fix(bazel): stage runtime resources for library tests
ScriptedAlchemy Oct 6, 2026
1a257e0
Merge remote-tracking branch 'origin/claude/bazel-windows-fixes'
claude Oct 6, 2026
5efa445
Merge remote-tracking branch 'origin/claude/bazel-windows-fixes'
claude Oct 6, 2026
3bb669c
test(macos): verify writable fixtures before filename capability
ScriptedAlchemy Oct 6, 2026
912022e
test(search-eval): re-pin the validation fallback receipt
claude Oct 7, 2026
3b0d8eb
Merge remote-tracking branch 'origin/claude/bazel-windows-fixes' into…
claude Oct 7, 2026
8ea7d46
fix(hosts): exclude Bazel convenience paths from registration
ScriptedAlchemy Oct 7, 2026
f208a4e
ci: log rustc's crate lookup for the Windows E0463
claude Oct 7, 2026
1baabab
fix(bazel): pass build scripts' C flags past rules_rust's CFLAGS
claude Oct 7, 2026
3f51fa9
fix(bazel): build bundled SQLite with Cargo's LIBSQLITE3_FLAGS
claude Oct 7, 2026
bcc51b4
ci: give Bazel test lanes rustup homes and the pnpm workspace
claude Oct 7, 2026
d4ee88f
fix(bazel): run Rust tests with native rules and runfiles
ScriptedAlchemy Oct 7, 2026
58fa8e2
Merge remote-tracking branch 'origin/claude/bazel-windows-fixes' into…
ScriptedAlchemy Oct 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 42 additions & 15 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
common --enable_bzlmod
common --announce_rc
common --show_progress_rate_limit=15
# build:linux, build:macos, and build:windows apply on their own hosts.
common --enable_platform_specific_config
build --incompatible_enable_cc_toolchain_resolution
build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
build --workspace_status_command=scripts/bazel/workspace_status.sh
# Bazel runs the status command through cmd.exe, which reads a forward slash
# as a switch (`scripts /bazel/...`), so the Windows path uses backslashes.
build:windows --workspace_status_command=scripts\\bazel\\workspace_status.bat
# .cargo/config.toml compiles vendored C deps with NDEBUG. Keep parity for
# cc crates built inside cargo_build_script actions (tree-sitter grammars).
build --action_env=CFLAGS=-DNDEBUG
build --action_env=CXXFLAGS=-DNDEBUG
# rules_rust replaces a build script's CFLAGS/CXXFLAGS with the C toolchain's
# own arguments, so the flags travel as HOST_ and TARGET_ variants, which
# cc-rs appends to them; it reads HOST_ for native builds, TARGET_ for cross.
build --action_env=HOST_CFLAGS=-DNDEBUG
build --action_env=TARGET_CFLAGS=-DNDEBUG
build --action_env=HOST_CXXFLAGS=-DNDEBUG
build --action_env=TARGET_CXXFLAGS=-DNDEBUG
# rules_rust compiles env!("CARGO_MANIFEST_DIR") to "${pwd}/<pkg>", which is the
# sandbox execroot. Crates that read CARGO_MANIFEST_DIR with env! instead of
# env::var (arborium grammars) then use a dead sandbox path when the build
Expand All @@ -18,20 +24,33 @@ build --action_env=CXXFLAGS=-DNDEBUG
# stay sandboxed.
build "--strategy_regexp=Compiling Rust bin _bs_.*=local"
build "--strategy_regexp=Compiling Rust bin build_script_build_.*=local"
# Tests read fixtures through env!("CARGO_MANIFEST_DIR") the same way, and a
# sandboxed rustc bakes a sandbox path that is gone by the time the test
# runs. Compile Rust in the real execroot so that path stays readable.
build --strategy=Rustc=local
build --strategy=RustcMetadata=local
# ld.bfd peaks near 4 GB per link. Cap parallelism so links do not
# OOM-kill each other on 8-core/32 GB workers.
build --jobs=4
build:linux "--@rules_rust//rust/settings:extra_rustc_flag=-Clink-arg=-fuse-ld=bfd"
# MSVC encodes narrow string literals in the host ANSI code page unless told
# otherwise, so tree-sitter grammars that spell symbol names as universal
# character names become invalid UTF-8 (see .cargo/config.toml).
build:windows "--action_env=CFLAGS=-DNDEBUG /utf-8"
build:windows "--action_env=CXXFLAGS=-DNDEBUG /utf-8"
build:windows "--action_env=HOST_CFLAGS=-DNDEBUG /utf-8"
build:windows "--action_env=TARGET_CFLAGS=-DNDEBUG /utf-8"
build:windows "--action_env=HOST_CXXFLAGS=-DNDEBUG /utf-8"
build:windows "--action_env=TARGET_CXXFLAGS=-DNDEBUG /utf-8"
# Genrules run Git Bash under a stripped PATH that holds no Python; hand
# actions the runner's PATH, as Linux and macOS find python3 in /usr/bin.
build:windows --action_env=PATH
# Windows runfiles default to a manifest; suites read fixtures and spawn
# binaries through the runfiles tree.
build:windows --enable_runfiles

test --test_output=errors
# Each rust_test is a whole Cargo test binary, where nextest caps single
# tests at six minutes; give medium (moderate) binaries 30 minutes.
test --test_timeout=-1,1800,-1,-1

# Blocking Clippy policy over every Rust target, matching
# `cargo clippy --workspace --all-targets -- -D warnings`.
Expand All @@ -47,6 +66,10 @@ build:release --@rules_rust//rust/settings:per_crate_rustc_flag=external/@-Copt-
# Hosted CI: keep going past one failure so a run reports every red target.
build:ci --keep_going
build:ci --show_timestamps
build:ci --verbose_failures
# Build scripts that compile C (aws-lc-sys) print megabytes of compiler
# output; keep a failing script's tail visible in the log.
build:ci --experimental_ui_max_stdouterr_bytes=16777216
test:ci --test_summary=terse
# Suites spawn host tools (ast-grep, node, git, and rust-analyzer through
# the rustup proxy, which needs its homes to find the pinned toolchain).
Expand All @@ -56,13 +79,17 @@ test:ci --test_env=CARGO_HOME

# BEGIN generated by scripts/bazel/gen_builds.py
# Cargo perf opt-levels for external crates (see [profile.perf]).
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__grafeo-adapters-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__grafeo-common-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__grafeo-core-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__grafeo-engine-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__grafeo-storage-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__regex-1.13.1/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__serde_json-1.0.151/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__sha2-0.11.0/@-Copt-level=3"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/+crate+crates__tiktoken-rs-0.12.1/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__grafeo-adapters-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__grafeo-common-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__grafeo-core-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__grafeo-engine-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__grafeo-storage-0.5.43/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__regex-1.13.1/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__serde_json-1.0.151/@-Copt-level=2"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__sha2-0.11.0/@-Copt-level=3"
build "--@rules_rust//rust/settings:per_crate_rustc_flag=external/rules_rust++crate+c__tiktoken-rs-0.12.1/@-Copt-level=2"
# END generated by scripts/bazel/gen_builds.py

# Platform configs expand here, after generic build defaults, so their
# workspace-status command and compiler environment take precedence.
build --enable_platform_specific_config
22 changes: 20 additions & 2 deletions .github/actions/setup-bazel/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,38 @@ runs:
repository-cache: true
disk-cache: ${{ inputs.cache-key }}
cache-save: ${{ github.event_name != 'pull_request' }}
# Windows build-script runfiles nest each vendored crate's sources
# under its repository name twice; a short output base (default
# D:/_bazel) keeps MSVC's header paths under MAX_PATH.
output-base: ${{ runner.os == 'Windows' && 'D:/b' || '' }}

# Test dependencies, not conveniences: the LSP negotiation acceptance
# spawns rust-analyzer through the pinned toolchain, the ast-grep
# bindings are graded against the host CLI, and SDK journeys run node.
# bindings are graded against the host CLI, and SDK journeys run node
# and pnpm. Bazel points HOME at the test's scratch directory, so the
# launcher finds rustup and cargo only through explicit homes, which the
# runner leaves unset.
- name: Install the pinned toolchain's components
if: inputs.test-tools == 'true'
shell: bash
run: rustup toolchain install
run: |
rustup toolchain install
# Git Bash spells $HOME as /c/...; native Windows programs need C:\...
native() { if command -v cygpath >/dev/null; then cygpath -w "$1"; else echo "$1"; fi; }
{
echo "CARGO_HOME=$(native "${CARGO_HOME:-$HOME/.cargo}")"
echo "RUSTUP_HOME=$(native "${RUSTUP_HOME:-$HOME/.rustup}")"
} >> "$GITHUB_ENV"

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
if: inputs.test-tools == 'true'
with:
node-version: 22

# The SDK journeys build sdks/typescript with pnpm from the checkout.
- uses: ./.github/actions/setup-pnpm
if: inputs.test-tools == 'true'

- name: Install ast-grep
if: inputs.test-tools == 'true'
uses: ./.github/actions/install-ast-grep
Expand Down
35 changes: 29 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@ jobs:
needs: [scope-gate, gates]
if: ${{ needs.scope-gate.outputs.run-heavy == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 240
# A cold Bazel disk cache (any MODULE.bazel or toolchain change) builds
# and tests every target from scratch.
timeout-minutes: 330
env:
CARGO_BAZEL_TIMEOUT: "3600"
steps:
Expand Down Expand Up @@ -310,18 +312,39 @@ jobs:
shell: bash
run: bazel test --config=ci //...

# tracedecay-lsp and tracedecay-code-index get a bare E0463 for every
# --extern their params file names: rustc's locator dropped each
# candidate without recording why. Rerun one lsp compile from its own
# params with the locator's reasons logged, until that is fixed.
- name: Trace rustc crate lookup for tracedecay-lsp
if: failure()
shell: pwsh
run: |
$execRoot = (bazel info execution_root).Trim()
Set-Location $execRoot
$params = Get-ChildItem "bazel-out/x64_windows-fastbuild/bin/crates/tracedecay-lsp/*.params.expanded" | Select-Object -First 1
$rustc = Get-ChildItem "external/rules_rust++rust+*_tools/rust_toolchain/bin/rustc.exe" | Select-Object -First 1
"params: $($params.FullName)"; "rustc: $($rustc.FullName)"
Get-Item (Select-String -Path $params -Pattern '^--extern=tokio=(.*)$').Matches[0].Groups[1].Value |
Format-List FullName,LinkType,Target,Length
$env:RUSTC_LOG = "rustc_metadata::locator=info"
& $rustc.FullName "@$($params.FullName)" 2>&1 |
Select-String -Pattern 'tokio|serde-|Rejecting|no metadata|not present|error' |
Select-Object -First 200

# Blocking Clippy policy over every Bazel Rust target, the
# `cargo clippy --workspace --all-targets -D warnings` equivalent.
clippy:
name: Clippy
needs: [scope-gate, gates]
if: ${{ needs.scope-gate.outputs.run-heavy == 'true' }}
concurrency:
group: ci-clippy
group: ci-clippy-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: false
queue: max
runs-on: ubuntu-24.04-arm
timeout-minutes: 120
# Clippy compiles every target; a cold disk cache needs over two hours.
timeout-minutes: 240
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Expand Down Expand Up @@ -365,7 +388,7 @@ jobs:
needs: [scope-gate, gates]
if: ${{ needs.scope-gate.outputs.run-heavy == 'true' }}
concurrency:
group: ci-feature-gates
group: ci-feature-gates-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: false
queue: max
runs-on: ubuntu-24.04-arm
Expand All @@ -392,7 +415,7 @@ jobs:
needs: [scope-gate, gates]
if: ${{ needs.scope-gate.outputs.run-heavy == 'true' }}
concurrency:
group: ci-shipped-cli
group: ci-shipped-cli-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: false
queue: max
runs-on: ubuntu-latest
Expand Down Expand Up @@ -421,7 +444,7 @@ jobs:
needs: [scope-gate, gates]
if: ${{ needs.scope-gate.outputs.run-heavy == 'true' }}
concurrency:
group: ci-dashboard
group: ci-dashboard-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: false
queue: max
runs-on: ubuntu-latest
Expand Down
56 changes: 54 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,63 @@ register_toolchains("@rust_toolchains//:all")

crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
crate.from_cargo(
name = "crates",
# One letter: Windows build-script paths repeat the hub's repository
# name, and MSVC cannot open headers past MAX_PATH (gen_builds.py).
name = "c",
cargo_lockfile = "//:Cargo.lock",
manifests = ["//:Cargo.toml"],
)
use_repo(crate, "crates")

# rules_rust stages build scripts under a runfiles tree that spells the crate
# repository twice, and MSVC joins relative includes without normalizing them,
# so aws-lc's four-level `../` jitterentropy include overran MAX_PATH. The
# builder already puts the jitterentropy library on the include path.
crate.annotation(
crate = "aws-lc-sys",
patch_args = ["-p1"],
patches = ["//scripts:bazel/patches/aws-lc-sys-jitterentropy-include.patch"],
version = "0.45.0",
)

# .cargo/config.toml's [env] LIBSQLITE3_FLAGS, which Cargo hands every build
# script and Bazel does not: bundled SQLite's worker-thread cap and disabled
# memory status counters.
crate.annotation(
build_script_env = {
"LIBSQLITE3_FLAGS": "-DSQLITE_MAX_WORKER_THREADS=15 -DSQLITE_DEFAULT_MEMSTATUS=0",
},
crate = "libsqlite3-sys",
version = "0.38.2",
)

# BEGIN generated by scripts/bazel/gen_builds.py
# Cargo's target features for crates a build-dependency widens
# (TARGET_FEATURE_CRATES in scripts/bazel/gen_builds.py).
crate.annotation(
additive_build_file_content = """
load("@rules_rust//rust:defs.bzl", _target_rust_library = "rust_library")

_target_rust_library(
name = "serde_json_target",
srcs = glob(["**/*.rs"], allow_empty = True),
compile_data = glob(["**"], allow_empty = True, exclude = ["**/* *", ".tmp_git_root/**/*", "BUILD", "BUILD.bazel", "WORKSPACE", "WORKSPACE.bazel"]),
crate_features = ["alloc", "default", "float_roundtrip", "raw_value", "std"],
crate_name = "serde_json",
crate_root = "src/lib.rs",
edition = "2021",
rustc_flags = ["--cap-lints=allow"],
tags = ["cargo-bazel", "crate-name=serde_json", "manual", "noclippy", "norustfmt"],
version = "1.0.151",
deps = ["@c__itoa-1.0.18//:itoa", "@c__memchr-2.8.3//:memchr", "@c__serde_core-1.0.229//:serde_core", "@c__zmij-1.0.23//:zmij", "@c__serde_json-1.0.151//:build_script_build"],
)
""",
crate = "serde_json",
override_target_lib = "@c__serde_json-1.0.151//:serde_json_target",
version = "1.0.151",
)
use_repo(crate, "c__serde_json-1.0.151")
# END generated by scripts/bazel/gen_builds.py
use_repo(crate, "c")

node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
node.toolchain(node_version = "22.14.0")
Expand Down
Loading
Loading