feat(build): migrated native pipeline to bazel with remote caching

- Replaced the napi-cli/cargo-zigbuild/cargo-xwin/sccache build path with
  Bazel: rules_rust + crate_universe over Cargo.lock, hermetic zig cc
  toolchains (linux-gnu pinned to glibc 2.17, linux-musl), host Xcode for
  darwin, and a repo-local hermetic clang-cl + llvm-ml + xwin toolchain for
  windows-msvc (bazel/toolchains/msvc).
- All eight shipped addons build as //:natives-<target> via the release
  transition in bazel/defs.bzl (opt, thin LTO, cgu=16, stripped, canonical
  .node naming); scripts/bazel-natives.ts is the single driver for local
  dev and CI.
- Rust validation moved to bazel test + clippy aspects (strict workspace
  policy for opted-in crates, default lints elsewhere, mirroring cargo
  semantics) and the rustfmt aspect; cargo stays as the dev-iteration
  surface, with brush-core/brush-builtins promoted to workspace members
  and excluded from cargo dev tasks to keep their historical scope.
- CI caches through an in-cluster bazel-remote action cache (TLS + basic
  auth, cluster-internal only); GitHub-hosted runners never touch the
  infrastructure and use an actions/cache-backed disk cache instead.
- Deleted the hand-rolled caching machinery: ci-target-cache,
  ci-native-artifact-cache, ci-build-native, native-source-hash,
  find-native-artifacts, restore-linux-native, native-prewarm workflow,
  ensure-* toolchain actions, and all sccache/Swatinem wiring.
- Warm native rebuilds drop from ~20 minutes to seconds; a cold client
  with a warm remote cache rebuilds the linux x64 pair in ~2.5 minutes.
This commit is contained in:
can1357
2026-07-27 12:22:19 +02:00
parent 5f988a8270
commit 8facd237d5
121 changed files with 66794 additions and 2630 deletions
+6
View File
@@ -0,0 +1,6 @@
node_modules
target
packages
python
infra
docs
+67
View File
@@ -0,0 +1,67 @@
# Bazel build configuration for the pi-natives NAPI addon pipeline.
# Cross targets, ISA variants, and release codegen are encoded in the
# //:natives-* addon targets (bazel/defs.bzl transition), so a bare
# `bazel build //:natives-<target>` is always release-grade.
common --enable_platform_specific_config
# Hermetic-ish action env: no host env leaks into action keys. Build scripts
# that need host tools (cmake for audiopus_sys' bundled opus) get an explicit
# PATH through crate annotations in MODULE.bazel.
build --incompatible_strict_action_env
# NOTE: rust pipelined_compilation stays OFF: handing dependents rmeta-only
# crates breaks `rust_test(crate = ...)` harness compiles whose deps export
# macro_rules! ("can't find crate" at macro expansion).
# Keep rustc errors readable.
build --@rules_rust//rust/settings:error_format=human
# Generated toolchains carry target_settings requiring the nightly channel.
build --@rules_rust//rust/toolchain/channel=nightly
# --- Rust validation (replaces cargo clippy/nextest in CI) --------------------
# Mirrors cargo semantics: crates with `[lints] workspace = true` (pi-ast,
# pi-iso, pi-natives, pi-shell, pi-walker) get the strict workspace policy
# (clippy-strict; bazel/clippy.bazelrc is generated from Cargo.toml); everything
# else gets default clippy + -Dwarnings (clippy).
build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect
build:clippy --output_groups=+clippy_checks
build:clippy --@rules_rust//rust/settings:clippy_flag=-Dwarnings
build:clippy-strict --config=clippy
import %workspace%/bazel/clippy.bazelrc
# rustfmt check via aspect, against the workspace rustfmt.toml.
build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect
build:rustfmt --output_groups=+rustfmt_checks
build:rustfmt --@rules_rust//rust/settings:rustfmt.toml=//:rustfmt.toml
test --test_output=errors
test --test_summary=terse
# --- CI base -----------------------------------------------------------------
build:ci --curses=no --color=yes --show_timestamps
build:ci --announce_rc
build:ci --verbose_failures
# Fail-fast inside one invocation; job-level matrix provides isolation.
build:ci --keep_going=false
# --- Remote cache ------------------------------------------------------------
# The bazel-remote endpoint is cluster-internal only; .github/actions/bazel-cache
# composes endpoint + credentials into an rc fragment on omp-kata pods.
# GitHub-hosted runners never use a remote cache (actions/cache-backed
# --disk_cache instead). These configs carry only the policy bits.
#
# cache-rw: trusted in-cluster writers (omp-kata pods).
build:cache-rw --remote_upload_local_results=true
build:cache-rw --remote_local_fallback
# cache-ro: read-only consumers (e.g. local dev via .bazelrc.user + VPN/tailnet).
build:cache-ro --remote_upload_local_results=false
build:cache-ro --remote_local_fallback
# Don't let a cache outage fail the build.
build:cache-rw --remote_retries=2
build:cache-ro --remote_retries=2
build:cache-rw --remote_timeout=60s
build:cache-ro --remote_timeout=60s
# --- Local development ---------------------------------------------------------
# Optional user overrides (remote cache endpoint, disk cache, etc.).
try-import %workspace%/.bazelrc.user
+1
View File
@@ -0,0 +1 @@
9.2.0
+65
View File
@@ -0,0 +1,65 @@
name: "Compose bazel cache config"
description: >
Single source of truth for how a CI job caches bazel work, emitted as a
bazelrc fragment (rc output) consumers pass via `bazelisk --bazelrc=...`.
omp-kata pods (detected via BAZEL_REMOTE_USER/BAZEL_REMOTE_PASSWORD from the
bazel-remote-ci secret) get read-write gRPC access to the in-cluster
bazel-remote service — an address that only resolves inside the cluster, so
nothing about the infrastructure leaks from this public repo. GitHub-hosted
runners never talk to that infrastructure: they use a local bazel disk cache
persisted with actions/cache, keyed on the crate lockfile and module
definition.
inputs:
scope:
description: >
Disk-cache key discriminator for GitHub-hosted runners; jobs building
different target sets (linux pair, darwin-all, msvc, validation) use
separate scopes so they don't evict each other's entries.
required: true
outputs:
rc:
description: Path to the generated bazelrc fragment
value: ${{ steps.compose.outputs.rc }}
runs:
using: composite
steps:
- name: Restore bazel disk cache (GitHub-hosted)
if: env.BAZEL_REMOTE_USER == ''
uses: actions/cache@v4
with:
path: |
~/.cache/omp-bazel-disk
~/.cache/omp-bazel-repo
key: bazel-disk-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.Bazel.lock', 'MODULE.bazel', 'rust-toolchain.toml') }}
restore-keys: |
bazel-disk-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-
- name: Compose cache config
id: compose
shell: bash
run: |
set -euo pipefail
rc="$RUNNER_TEMP/bazel-cache.rc"
if [ -n "${BAZEL_REMOTE_USER:-}" ]; then
auth="$(printf %s "${BAZEL_REMOTE_USER}:${BAZEL_REMOTE_PASSWORD}" | base64 | tr -d '\n')"
{
echo "common --config=ci"
echo "common --config=cache-rw"
echo "common --remote_cache=grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092"
echo "common --tls_certificate=infra/bazel-remote/ca.crt"
echo "common --remote_header='authorization=Basic ${auth}'"
# PVC-backed shared repository cache (pods are ephemeral; without
# it every job re-downloads toolchains + crate archives).
echo "common --repository_cache=$HOME/.cache/omp-bazel-repo"
} > "$rc"
else
{
echo "common --config=ci"
echo "common --disk_cache=$HOME/.cache/omp-bazel-disk"
echo "common --repository_cache=$HOME/.cache/omp-bazel-repo"
} > "$rc"
fi
echo "rc=$rc" >> "$GITHUB_OUTPUT"
+34
View File
@@ -0,0 +1,34 @@
name: "Build native addons (bazel)"
description: >
Build the requested //:natives-* targets with bazelisk and copy the .node
files into the destination directory. Cache wiring comes from the
bazel-cache action: in-cluster read-write on omp-kata, actions/cache-backed
disk cache on GitHub-hosted runners.
inputs:
targets:
description: Space-separated scripts/bazel-natives.ts target names
required: true
dest:
description: Destination directory for the .node files
required: false
default: packages/natives/native
cache-scope:
description: Disk-cache key discriminator (see bazel-cache action)
required: false
default: natives
runs:
using: composite
steps:
- id: cache
uses: ./.github/actions/bazel-cache
with:
scope: ${{ inputs.cache-scope }}
- name: Build native addons
shell: bash
run: |
set -euo pipefail
export OMP_BAZEL_RC="${{ steps.cache.outputs.rc }}"
bun scripts/bazel-natives.ts ${{ inputs.targets }} --dest "${{ inputs.dest }}"
-427
View File
@@ -1,427 +0,0 @@
name: Build native addon
description: >
Build the pi_natives cdylib for one platform/arch/variant and upload it as a
hash-tagged artifact. Self-detects the runner via $SCCACHE_BUCKET (injected
only on the self-hosted omp-kata pods): on-infra it uses the image's baked
toolchains + the RustFS-backed sccache; on GitHub-hosted runners it installs
the toolchains and uses Swatinem target/ cache + the GitHub Actions sccache
backend. PRs run on GitHub-hosted runners, so the on-infra path only ever
serves trusted push/main + release builds.
inputs:
hash:
description: Rust source hash used in the artifact name
required: true
platform:
description: Target platform (linux, darwin, win32)
required: true
arch:
description: Target arch (x64, arm64)
required: true
variant:
description: Optional build variant (baseline, modern); required for native x64 builds.
required: false
default: ""
target:
description: Optional rustc target triple for cross-compilation
required: false
default: ""
glibc:
description: >
Optional glibc floor override for linux-gnu builds (defaults to "2.17").
Routes the build through cargo-zigbuild against that floor without
affecting the rustup target or host-arch native test steps.
required: false
default: ""
libc:
description: Optional Linux libc artifact qualifier (for example, musl)
required: false
default: ""
rust_checks:
description: Run clippy/rustfmt checks (only one matrix entry should set this)
required: false
default: "false"
skip_validation:
description: Skip clippy/rustfmt and the Rust test suite for build-only matrix entries.
required: false
default: "false"
skip_build:
description: Run validation and cache population without building or uploading a native addon.
required: false
default: "false"
cache_scope:
description: Separates target snapshots whose Cargo work differs (for example, build and validation).
required: false
default: "build"
save_cache:
description: Whether to persist the GitHub-hosted or RustFS target snapshot.
required: false
default: "false"
runs:
using: composite
steps:
- name: Detect runner environment
id: detect
shell: bash
run: |
# $SCCACHE_BUCKET is injected only on the self-hosted omp-kata runner
# pods (envFrom sccache-s3); its presence is the repo's single
# "on can.internal infra?" signal. On-infra: baked toolchains, RustFS
# sccache, no GitHub target/ cache. Off-infra (GitHub-hosted): install
# toolchains, Swatinem target/ cache, GitHub Actions sccache backend.
if [ -n "${SCCACHE_BUCKET:-}" ]; then
echo "on_infra=true" >> "$GITHUB_OUTPUT"
echo "runner: self-hosted omp-kata (baked tools + RustFS sccache)"
else
echo "on_infra=false" >> "$GITHUB_OUTPUT"
echo "runner: GitHub-hosted (install tools + Swatinem cache + GHA sccache)"
fi
- name: Resolve build targets
id: resolve
shell: bash
env:
TARGET: ${{ inputs.target }}
GLIBC: ${{ inputs.glibc }}
PLATFORM: ${{ inputs.platform }}
LIBC: ${{ inputs.libc }}
ARCH: ${{ inputs.arch }}
run: |
set -euo pipefail
# Keep the portability floor here: this action is included in the
# native source hash, and every workflow then consumes one value.
if [ "$PLATFORM" = linux ] && [ "$LIBC" != musl ]; then
GLIBC="${GLIBC:-2.17}"
elif [ -n "$GLIBC" ]; then
echo "::error::glibc floor '$GLIBC' is only valid for linux-gnu builds"
exit 1
fi
# `cross_target` is what the napi build feeds cargo: cargo-zigbuild reads
# the glibc floor as a `.<major>.<minor>` triple suffix. `bare_target` is
# what rustup needs — never glibc-suffixed (rustup rejects the suffix)
# and empty for host-arch builds whose target is already installed.
base="$TARGET"
if [ -z "$base" ]; then
case "$ARCH" in
x64) base="x86_64-unknown-linux-gnu" ;;
arm64) base="aarch64-unknown-linux-gnu" ;;
esac
fi
cross_target=""
if [ -n "$GLIBC" ]; then
case "$base" in
*-linux-gnu) cross_target="${base}.${GLIBC}" ;;
*)
echo "::error::glibc floor '$GLIBC' requires a linux-gnu target, got '$base'"
exit 1
;;
esac
elif [ -n "$TARGET" ]; then
cross_target="$TARGET"
fi
bare_target="${TARGET%%.*}"
{
echo "cross_target=$cross_target"
echo "bare_target=$bare_target"
} >> "$GITHUB_OUTPUT"
echo "Resolved cross_target='$cross_target' bare_target='$bare_target'"
# --- Rust toolchain -----------------------------------------------------
- name: Ensure baked Rust toolchain (omp-kata)
if: steps.detect.outputs.on_infra == 'true'
uses: ./.github/actions/ensure-rust-toolchain
with:
toolchain: nightly-2026-04-29
components: ${{ inputs.rust_checks == 'true' && 'clippy,rustfmt' || '' }}
target: ${{ steps.resolve.outputs.bare_target }}
- name: Install Rust toolchain (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false'
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly-2026-04-29
components: ${{ inputs.rust_checks == 'true' && 'clippy, rustfmt' || '' }}
targets: ${{ steps.resolve.outputs.bare_target }}
- name: Install Linux build prerequisites (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false' && runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y build-essential
# audiopus_sys builds bundled libopus via CMake (Ninja generator for MSVC
# cross); baked into the omp-kata image and GitHub-hosted images, so this
# only self-heals runners that predate the bake.
- uses: ./.github/actions/ensure-cmake
- name: Prepend rustup toolchain bin to PATH (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false'
shell: bash
run: |
# Homebrew on macOS runners ships rustup-init with shadow proxies for
# `cargo`/`rustc`/etc. that error out as the installer ("unexpected
# argument 'metadata' found"). Force the real toolchain binaries to win
# on PATH. (ensure-rust-toolchain already does this on omp-kata.)
toolchain_bin="$(dirname "$(rustup which cargo)")"
echo "$toolchain_bin" >> "$GITHUB_PATH"
echo "Prepended $toolchain_bin to PATH"
# --- Rust flags (shared) ------------------------------------------------
- name: Configure native Rust flags
if: inputs.target == '' || inputs.arch == 'x64'
shell: bash
env:
TARGET_ARCH: ${{ inputs.arch }}
TARGET_VARIANT: ${{ inputs.variant }}
run: |
case "$TARGET_ARCH:$TARGET_VARIANT" in
x64:modern)
rustflags="-C target-cpu=x86-64-v3"
;;
x64:baseline)
rustflags="-C target-cpu=x86-64-v2"
;;
x64:*)
echo "::error::x64 native builds require variant=modern or variant=baseline"
exit 1
;;
*)
if [ -n "${RUSTFLAGS:-}" ]; then
echo "Using caller-provided RUSTFLAGS=$RUSTFLAGS"
exit 0
fi
# Non-x64 native builds (darwin arm64) keep the target's default
# CPU features. `-C target-cpu=native` both baked the CI host's
# CPU features into shipped artifacts and trips ring 0.17's
# aarch64-apple const assertion (CAPS_STATIC == MIN_STATIC_FEATURES)
# once extra static features are enabled.
echo "Using default target CPU features (no RUSTFLAGS)"
exit 0
;;
esac
echo "RUSTFLAGS=$rustflags" >> "$GITHUB_ENV"
echo "Configured RUSTFLAGS=$rustflags"
# --- Cargo + rolling target cache (GitHub-hosted only) ------------------
# Swatinem keeps the registry/tool cache. target/ uses an explicit rolling
# key: a new source hash restores the latest compatible snapshot through
# restore-keys, then saves the rebuilt state under a fresh immutable key.
# This is especially important for the three-core Intel macOS runner.
- name: Cache Cargo dependencies (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false'
uses: Swatinem/rust-cache@v2
with:
shared-key: native-deps-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}
cache-on-failure: true
save-if: ${{ inputs.save_cache == 'true' }}
cache-targets: false
- name: Restore rolling Rust target/ (GitHub-hosted)
id: gha-target
if: steps.detect.outputs.on_infra == 'false'
uses: actions/cache/restore@v4
with:
path: target
key: native-target-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}-${{ hashFiles('rust-toolchain.toml') }}-h${{ inputs.hash }}
restore-keys: |
native-target-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}-${{ hashFiles('rust-toolchain.toml') }}-
# --- sccache ------------------------------------------------------------
- name: Ensure baked sccache (omp-kata)
if: steps.detect.outputs.on_infra == 'true'
uses: ./.github/actions/ensure-sccache
with:
version: "0.15.0"
- name: Setup sccache (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false'
uses: mozilla-actions/sccache-action@v0.0.10
- name: Enable sccache for cargo
# CARGO_INCREMENTAL=0 is required: sccache silently skips caching when
# incremental is enabled, turning the wrapper into a no-op. The backend is
# conditional: omp-kata reads the shared S3 (RustFS) config from the
# inherited pod env; GitHub-hosted runners use the GHA cache backend.
shell: bash
env:
CROSS_TARGET: ${{ steps.resolve.outputs.cross_target }}
run: |
jobs="${OMP_CI_CPU_COUNT:-$(getconf _NPROCESSORS_ONLN)}"
if [ -z "${OMP_CI_CPU_COUNT:-}" ] && [ -r /sys/fs/cgroup/cpu.max ]; then
read -r quota period < /sys/fs/cgroup/cpu.max
if [ "$quota" != "max" ]; then
quota_jobs=$((quota / period))
[ "$quota_jobs" -ge 1 ] || quota_jobs=1
[ "$quota_jobs" -ge "$jobs" ] || jobs="$quota_jobs"
fi
fi
{
echo "OMP_CI_CPU_COUNT=$jobs"
echo "RUSTC_WRAPPER=sccache"
echo "CARGO_INCREMENTAL=0"
echo "CARGO_BUILD_JOBS=$jobs"
echo "CMAKE_BUILD_PARALLEL_LEVEL=$jobs"
echo "NEXTEST_TEST_THREADS=$jobs"
} >> "$GITHUB_ENV"
echo "Native build parallelism: $jobs"
# Route CMake-built C (audiopus_sys' bundled opus) through sccache
# too — build scripts bypass RUSTC_WRAPPER. Non-cross builds only:
# cross builds compile C with zig cc / clang-cl wrapper scripts that
# sccache may fail to classify, which would hard-fail the compile.
if [ -z "$CROSS_TARGET" ]; then
{
echo "CMAKE_C_COMPILER_LAUNCHER=sccache"
echo "CMAKE_CXX_COMPILER_LAUNCHER=sccache"
} >> "$GITHUB_ENV"
fi
if [ -n "${SCCACHE_BUCKET:-}" ]; then
echo "sccache backend: shared S3 ($SCCACHE_BUCKET @ $SCCACHE_ENDPOINT)"
else
echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV"
echo "sccache backend: GitHub Actions cache"
fi
# --- cargo-nextest (native test runner; non-cross builds only) ----------
- name: Ensure baked cargo-nextest (omp-kata)
if: steps.detect.outputs.on_infra == 'true' && inputs.target == '' && inputs.skip_validation != 'true'
uses: ./.github/actions/ensure-cargo-tool
with:
binary: cargo-nextest
crate: cargo-nextest
- name: Install cargo-nextest (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false' && inputs.target == '' && inputs.skip_validation != 'true'
uses: taiki-e/install-action@v2
with:
tool: nextest
- uses: ./.github/actions/bun-install
# --- Cross-compile toolchains -------------------------------------------
# Non-MSVC targets (e.g. aarch64-unknown-linux-gnu) build with
# cargo-zigbuild (needs zig); MSVC targets (e.g. x86_64-pc-windows-msvc)
# build with cargo-xwin (needs clang/lld/llvm). The napi CLI's
# --cross-compile flag picks the backend; we just install what it needs.
# Cross builds only run on push/main + release (omp-kata), so the
# GitHub-hosted cross branches exist for portability and never fire here.
- name: Ensure baked zig (omp-kata, non-MSVC cross)
if: steps.detect.outputs.on_infra == 'true' && steps.resolve.outputs.cross_target != '' && !endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: ./.github/actions/ensure-zig
with:
version: "0.16.0"
- name: Setup zig (GitHub-hosted, non-MSVC cross)
if: steps.detect.outputs.on_infra == 'false' && steps.resolve.outputs.cross_target != '' && !endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: mlugg/setup-zig@v2
with:
version: 0.16.0
- name: Ensure baked cargo-zigbuild (omp-kata, non-MSVC cross)
if: steps.detect.outputs.on_infra == 'true' && steps.resolve.outputs.cross_target != '' && !endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: ./.github/actions/ensure-cargo-tool
with:
binary: cargo-zigbuild
crate: cargo-zigbuild
- name: Install cargo-zigbuild (GitHub-hosted, non-MSVC cross)
if: steps.detect.outputs.on_infra == 'false' && steps.resolve.outputs.cross_target != '' && !endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: taiki-e/install-action@v2
with:
tool: cargo-zigbuild
- name: Install LLVM tooling (GitHub-hosted, MSVC cross)
if: steps.detect.outputs.on_infra == 'false' && endsWith(steps.resolve.outputs.cross_target, '-msvc')
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y clang lld llvm
- name: Ensure baked cargo-xwin (omp-kata, MSVC cross)
if: steps.detect.outputs.on_infra == 'true' && endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: ./.github/actions/ensure-cargo-tool
with:
binary: cargo-xwin
crate: cargo-xwin
- name: Install cargo-xwin (GitHub-hosted, MSVC cross)
if: steps.detect.outputs.on_infra == 'false' && endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: taiki-e/install-action@v2
with:
tool: cargo-xwin
- name: Cache cargo-xwin Windows SDK
if: endsWith(steps.resolve.outputs.cross_target, '-msvc')
uses: actions/cache@v4
with:
path: ~/.cache/cargo-xwin
key: cargo-xwin-${{ runner.os }}-v1
- name: Accept xwin license
if: endsWith(steps.resolve.outputs.cross_target, '-msvc')
shell: bash
run: echo "XWIN_ACCEPT_LICENSE=1" >> "$GITHUB_ENV"
# --- target/ cache (omp-kata) --------------------------------------------
# sccache only covers rustc invocations; build-script outputs (57
# tree-sitter grammar C compiles, bundled opus via CMake, ring asm) and
# cargo's fingerprint/link work bypass it. Snapshot target/ to the same
# RustFS S3 bucket, keyed per platform/libc/arch/variant + toolchain and
# overwritten on each save so storage stays bounded at one snapshot per
# key. GitHub-hosted runners get the same effect from the rolling cache above.
- name: Verify target cache compressor (omp-kata)
if: steps.detect.outputs.on_infra == 'true'
shell: bash
run: zstd --version
- name: Restore target/ cache (omp-kata)
if: steps.detect.outputs.on_infra == 'true'
shell: bash
env:
TARGET_CACHE_KEY: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}
run: bun scripts/ci-target-cache.ts restore "$TARGET_CACHE_KEY"
# --- Checks, build, upload (shared) -------------------------------------
- name: Rust checks
if: inputs.rust_checks == 'true' && inputs.skip_validation != 'true'
shell: bash
run: bun run check:rs
- name: Test workspace (Rust)
# macOS has no `#[cfg(target_os = "macos")]` tests in the workspace, and
# Windows-only tests are no longer exercised in CI (win32-x64 cross-builds
# on Linux). Skipping the duplicate Linux runs on macOS saves ~10 min of
# parallel runner time.
if: inputs.target == '' && inputs.platform != 'darwin' && inputs.skip_validation != 'true'
shell: bash
run: bun run test:rs
- name: Build native addon(s)
if: inputs.skip_build != 'true'
shell: bash
env:
CROSS_TARGET: ${{ steps.resolve.outputs.cross_target }}
TARGET_PLATFORM: ${{ inputs.platform }}
TARGET_ARCH: ${{ inputs.arch }}
TARGET_VARIANTS: ${{ inputs.variant }}
run: |
if [ "$CROSS_TARGET" = x86_64-apple-darwin ]; then
# Do not accept Homebrew's arm64 libopus through pkg-config;
# build audiopus_sys's bundled x64 archive.
export OPUS_NO_PKG_CONFIG=1
fi
bun run ci:build:native
- name: sccache stats
shell: bash
run: sccache --show-stats || true
- name: Save native addon(s) to in-cluster cache
if: inputs.skip_build != 'true' && steps.detect.outputs.on_infra == 'true'
shell: bash
env:
ARTIFACT_NAME: pi-natives-${{ inputs.platform }}-${{ inputs.libc && format('{0}-', inputs.libc) || '' }}${{ inputs.arch }}${{ inputs.variant && format('-{0}', inputs.variant) || '' }}-h${{ inputs.hash }}
run: bun scripts/ci-native-artifact-cache.ts save "${{ inputs.hash }}" "$ARTIFACT_NAME"
- name: Upload native addon(s)
if: inputs.skip_build != 'true'
uses: actions/upload-artifact@v4
with:
name: pi-natives-${{ inputs.platform }}-${{ inputs.libc && format('{0}-', inputs.libc) || '' }}${{ inputs.arch }}${{ inputs.variant && format('-{0}', inputs.variant) || '' }}-h${{ inputs.hash }}
path: packages/natives/native/pi_natives.${{ inputs.platform }}-${{ inputs.arch }}*.node
if-no-files-found: error
retention-days: 90
- name: Save target/ cache (omp-kata)
if: steps.detect.outputs.on_infra == 'true' && inputs.save_cache == 'true'
shell: bash
env:
TARGET_CACHE_KEY: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}
run: bun scripts/ci-target-cache.ts save "$TARGET_CACHE_KEY"
- name: Save rolling Rust target/ (GitHub-hosted)
if: steps.detect.outputs.on_infra == 'false' && inputs.save_cache == 'true' && steps.gha-target.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: target
key: native-target-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}-${{ hashFiles('rust-toolchain.toml') }}-h${{ inputs.hash }}
+6 -5
View File
@@ -22,11 +22,12 @@ runs:
else else
echo "setup_bun=true" >> "$GITHUB_OUTPUT" echo "setup_bun=true" >> "$GITHUB_OUTPUT"
fi fi
# The repo keys "are we on can.internal infra?" off $SCCACHE_BUCKET (see # The repo keys "are we on can.internal infra?" off $BAZEL_REMOTE_USER
# actions/build-native). RUNNER_ENVIRONMENT is empty on ARC pods, so it # (the bazel-remote-ci secret is envFrom-injected into every omp-kata
# is not a usable signal here. On infra, the ARC pod mounts the shared # runner pod). RUNNER_ENVIRONMENT is empty on ARC pods, so it is not a
# Bun store at the default cache path; off infra, actions/cache restores it. # usable signal here. On infra, the ARC pod mounts the shared Bun
if [ -n "${SCCACHE_BUCKET:-}" ]; then # store at the default cache path; off infra, actions/cache restores it.
if [ -n "${BAZEL_REMOTE_USER:-}" ]; then
echo "cache=mounted" >> "$GITHUB_OUTPUT" echo "cache=mounted" >> "$GITHUB_OUTPUT"
echo "bun cache backend: mounted PVC (${BUN_INSTALL_CACHE_DIR:-${HOME}/.bun/install/cache})" echo "bun cache backend: mounted PVC (${BUN_INSTALL_CACHE_DIR:-${HOME}/.bun/install/cache})"
else else
@@ -1,38 +0,0 @@
name: "ensure cargo tool"
description: Ensure a cargo-installed CLI is present.
inputs:
binary:
required: true
description: Binary name expected on PATH
crate:
required: false
default: ""
description: Crate name to cargo install; defaults to the binary name
version:
required: false
default: ""
description: Optional crate version
runs:
using: composite
steps:
- shell: bash
env:
BINARY: ${{ inputs.binary }}
CRATE: ${{ inputs.crate }}
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if command -v "$BINARY" >/dev/null 2>&1; then
echo "Using baked cargo tool: $BINARY"
exit 0
fi
crate="${CRATE:-$BINARY}"
install_args=(install --locked "$crate")
if [ -n "$VERSION" ]; then
install_args+=(--version "$VERSION")
fi
cargo "${install_args[@]}"
echo "Installed cargo tool: $BINARY"
-80
View File
@@ -1,80 +0,0 @@
name: "ensure cmake"
description: >-
Ensure cmake (and ninja on Linux) are on PATH for native builds that compile
bundled C libraries (audiopus_sys builds libopus via CMake; MSVC cross builds
generate with Ninja). No-op when the runner image already ships them
(GitHub-hosted images do); self-heals on the omp-kata pods by installing
pinned binaries into ~/.local.
inputs:
cmake-version:
required: false
default: "4.1.2"
description: CMake release version installed when cmake is missing
ninja-version:
required: false
default: "1.13.1"
description: Ninja release version installed when ninja is missing (Linux only)
runs:
using: composite
steps:
- shell: bash
env:
CMAKE_VERSION: ${{ inputs.cmake-version }}
NINJA_VERSION: ${{ inputs.ninja-version }}
run: |
set -euo pipefail
destdir="${HOME}/.local"
mkdir -p "$destdir"
if command -v cmake >/dev/null 2>&1 && cmake --version >/dev/null 2>&1; then
echo "Using preinstalled $(cmake --version | head -n1)"
else
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) archive="cmake-${CMAKE_VERSION}-linux-x86_64" ;;
Linux-aarch64) archive="cmake-${CMAKE_VERSION}-linux-aarch64" ;;
Darwin-*) archive="cmake-${CMAKE_VERSION}-macos-universal" ;;
*)
echo "Unsupported cmake host: $(uname -s)-$(uname -m)" >&2
exit 1
;;
esac
rm -rf "${destdir:?}/${archive}"
curl -fsSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${archive}.tar.gz" -o "${destdir}/cmake.tar.gz"
tar -xzf "${destdir}/cmake.tar.gz" -C "$destdir"
rm -f "${destdir}/cmake.tar.gz"
case "$archive" in
*macos*) bindir="${destdir}/${archive}/CMake.app/Contents/bin" ;;
*) bindir="${destdir}/${archive}/bin" ;;
esac
echo "$bindir" >> "$GITHUB_PATH"
echo "Installed $("${bindir}/cmake" --version | head -n1)"
fi
# Ninja is only needed on Linux hosts: cmake-rs generates MSVC cross
# builds (cargo-xwin) with the Ninja generator. macOS images ship it.
if [ "$(uname -s)" = "Linux" ] && ! command -v ninja >/dev/null 2>&1; then
case "$(uname -m)" in
x86_64) zip="ninja-linux.zip" ;;
aarch64) zip="ninja-linux-aarch64.zip" ;;
*)
echo "Unsupported ninja host: $(uname -m)" >&2
exit 1
;;
esac
bindir="${destdir}/ninja-${NINJA_VERSION}"
mkdir -p "$bindir"
curl -fsSL "https://github.com/ninja-build/ninja/releases/download/v${NINJA_VERSION}/${zip}" -o "${bindir}/ninja.zip"
if command -v unzip >/dev/null 2>&1; then
unzip -oq "${bindir}/ninja.zip" -d "$bindir"
elif command -v bsdtar >/dev/null 2>&1; then
bsdtar -xf "${bindir}/ninja.zip" -C "$bindir"
else
python3 -m zipfile -e "${bindir}/ninja.zip" "$bindir"
fi
rm -f "${bindir}/ninja.zip"
chmod +x "${bindir}/ninja"
echo "$bindir" >> "$GITHUB_PATH"
echo "Installed ninja $("${bindir}/ninja" --version)"
fi
@@ -1,59 +0,0 @@
name: "ensure rust toolchain"
description: >
Ensure a pinned rustup toolchain, optional components, and an optional target
are present, then prepend the real toolchain bin dir to PATH.
inputs:
toolchain:
required: true
description: Rust toolchain name (for example nightly-2026-04-29)
components:
required: false
default: ""
description: Optional comma-separated rustup components
target:
required: false
default: ""
description: Optional rustup target triple
runs:
using: composite
steps:
- shell: bash
env:
TOOLCHAIN: ${{ inputs.toolchain }}
COMPONENTS: ${{ inputs.components }}
TARGET: ${{ inputs.target }}
run: |
set -euo pipefail
if ! command -v rustup >/dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs \
| sh -s -- -y --default-toolchain "$TOOLCHAIN" --profile minimal
fi
if ! rustc +"$TOOLCHAIN" --version >/dev/null 2>&1; then
rustup toolchain install "$TOOLCHAIN" --profile minimal --no-self-update
fi
rustup default "$TOOLCHAIN"
missing_components=()
if [ -n "$COMPONENTS" ]; then
IFS=',' read -r -a wanted_components <<< "$COMPONENTS"
for component in "${wanted_components[@]}"; do
[ -z "$component" ] && continue
if ! rustup component list --toolchain "$TOOLCHAIN" --installed | grep -qE "^${component}(-|$)"; then
missing_components+=("$component")
fi
done
fi
if [ ${#missing_components[@]} -gt 0 ]; then
rustup component add --toolchain "$TOOLCHAIN" "${missing_components[@]}"
fi
if [ -n "$TARGET" ] && ! rustup target list --toolchain "$TOOLCHAIN" --installed | grep -qx "$TARGET"; then
rustup target add --toolchain "$TOOLCHAIN" "$TARGET"
fi
toolchain_bin="$(dirname "$(rustup which cargo --toolchain "$TOOLCHAIN")")"
echo "$toolchain_bin" >> "$GITHUB_PATH"
echo "Using Rust toolchain: $(rustc +"$TOOLCHAIN" --version)"
-47
View File
@@ -1,47 +0,0 @@
name: "ensure sccache"
description: Ensure a pinned sccache binary is on PATH.
inputs:
version:
required: false
default: "0.15.0"
description: sccache release version without the leading v
runs:
using: composite
steps:
- shell: bash
env:
SCCACHE_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if command -v sccache >/dev/null 2>&1; then
current="$(sccache --version | awk '{print $2}')"
if [ "$current" = "$SCCACHE_VERSION" ]; then
echo "Using baked sccache $current"
exit 0
fi
fi
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) triple=x86_64-unknown-linux-musl ;;
Darwin-arm64) triple=aarch64-apple-darwin ;;
Darwin-x86_64) triple=x86_64-apple-darwin ;;
*) triple="" ;;
esac
if [ -n "$triple" ]; then
url="https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-${triple}.tar.gz"
tmpdir="${RUNNER_TEMP:-/tmp}/sccache-${SCCACHE_VERSION}"
bindir="${HOME}/.local/bin"
rm -rf "$tmpdir"
mkdir -p "$tmpdir" "$bindir"
curl -fsSL "$url" | tar -xz -C "$tmpdir"
install -m755 "$tmpdir"/sccache-v${SCCACHE_VERSION}-${triple}/sccache "$bindir/sccache"
echo "$bindir" >> "$GITHUB_PATH"
echo "Installed sccache $("$bindir/sccache" --version)"
exit 0
fi
cargo install --locked sccache --version "$SCCACHE_VERSION"
echo "Installed sccache $(sccache --version)"
-39
View File
@@ -1,39 +0,0 @@
name: "ensure zig"
description: Ensure a pinned Zig binary is on PATH.
inputs:
version:
required: true
description: Zig release version
runs:
using: composite
steps:
- shell: bash
env:
ZIG_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if command -v zig >/dev/null 2>&1 && [ "$(zig version)" = "$ZIG_VERSION" ]; then
echo "Using baked zig $ZIG_VERSION"
exit 0
fi
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) archive="zig-x86_64-linux-${ZIG_VERSION}" ;;
Darwin-arm64) archive="zig-aarch64-macos-${ZIG_VERSION}" ;;
Darwin-x86_64) archive="zig-x86_64-macos-${ZIG_VERSION}" ;;
*)
echo "Unsupported zig host: $(uname -s)-$(uname -m)" >&2
exit 1
;;
esac
destdir="${HOME}/.local"
mkdir -p "$destdir"
rm -rf "${destdir:?}/${archive}"
curl -fsSL "https://ziglang.org/download/${ZIG_VERSION}/${archive}.tar.xz" -o "${destdir}/zig.tar.xz"
tar -xJf "${destdir}/zig.tar.xz" -C "$destdir"
rm -f "${destdir}/zig.tar.xz"
echo "${destdir}/${archive}" >> "$GITHUB_PATH"
echo "Installed zig $("${destdir}/${archive}/zig" version)"
@@ -1,99 +0,0 @@
name: Find reusable native artifacts
description: Find complete trusted native artifact sets for one source hash, including canceled main runs.
inputs:
hash:
description: Native source hash embedded in artifact names
required: true
outputs:
linux-x64-run-id:
description: Run containing both Linux x64 variants
value: ${{ steps.find.outputs.linux-x64-run-id }}
cross-platform-run-id:
description: Run containing every cross-platform artifact
value: ${{ steps.find.outputs.cross-platform-run-id }}
validation-run-id:
description: Run containing the successful Rust validation marker
value: ${{ steps.find.outputs.validation-run-id }}
runs:
using: composite
steps:
- name: Find complete artifact sets
id: find
shell: bash
env:
GH_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
REPOSITORY_ID: ${{ github.repository_id }}
SOURCE_HASH: ${{ inputs.hash }}
run: |
set -euo pipefail
artifact_run_ids() {
local artifact_name="$1"
gh api --paginate "/repos/${REPOSITORY}/actions/artifacts?name=${artifact_name}&per_page=100" \
--jq ".artifacts[] | select(.expired == false and .workflow_run.head_branch == \"main\" and .workflow_run.head_repository_id == ${REPOSITORY_ID}) | .workflow_run.id" \
| sort -rn | uniq
}
find_complete_run() {
local canary="$1"
shift
local candidate names required complete
while read -r candidate; do
[ -n "$candidate" ] || continue
names="$(gh api "/repos/${REPOSITORY}/actions/runs/${candidate}/artifacts?per_page=100" \
--jq '.artifacts[] | select(.expired == false) | .name')"
complete=true
for required in "$@"; do
if ! grep -qFx "$required" <<<"$names"; then
complete=false
break
fi
done
if $complete; then
echo "$candidate"
return 0
fi
done < <(artifact_run_ids "$canary")
}
linux_baseline="pi-natives-linux-x64-baseline-h${SOURCE_HASH}"
linux_modern="pi-natives-linux-x64-modern-h${SOURCE_HASH}"
cross_required=(
"pi-natives-linux-arm64-h${SOURCE_HASH}"
"pi-natives-linux-musl-x64-baseline-h${SOURCE_HASH}"
"pi-natives-linux-musl-arm64-h${SOURCE_HASH}"
"pi-natives-darwin-x64-baseline-h${SOURCE_HASH}"
"pi-natives-darwin-arm64-h${SOURCE_HASH}"
"pi-natives-win32-x64-baseline-h${SOURCE_HASH}"
)
validation_marker="pi-natives-rust-validation-h${SOURCE_HASH}"
linux_x64_run_id="$(find_complete_run "$linux_modern" "$linux_baseline" "$linux_modern")"
cross_platform_run_id="$(find_complete_run "${cross_required[3]}" "${cross_required[@]}")"
validation_run_id="$(find_complete_run "$validation_marker" "$validation_marker")"
if [ -n "$linux_x64_run_id" ]; then
echo "Reusing Linux x64 native artifacts from run $linux_x64_run_id"
else
echo "No complete Linux x64 artifact set for hash $SOURCE_HASH"
fi
if [ -n "$cross_platform_run_id" ]; then
echo "Reusing cross-platform native artifacts from run $cross_platform_run_id"
else
echo "No complete cross-platform artifact set for hash $SOURCE_HASH"
fi
if [ -n "$validation_run_id" ]; then
echo "Reusing Rust validation from run $validation_run_id"
else
echo "No Rust validation marker for hash $SOURCE_HASH"
fi
{
echo "linux-x64-run-id=$linux_x64_run_id"
echo "cross-platform-run-id=$cross_platform_run_id"
echo "validation-run-id=$validation_run_id"
} >> "$GITHUB_OUTPUT"
@@ -1,30 +0,0 @@
name: Compute native source hash
description: Hash every source, toolchain, and build-or-validation input that governs reusable native artifacts.
outputs:
source-hash:
description: Stable 16-hex native source fingerprint
value: ${{ steps.compute.outputs.source-hash }}
runs:
using: composite
steps:
- name: Compute native source hash
id: compute
shell: bash
run: |
set -euo pipefail
source_hash=$(find \
crates \
packages/natives/scripts \
Cargo.toml Cargo.lock rust-toolchain.toml rustfmt.toml \
packages/natives/package.json \
scripts/ci-build-native.ts scripts/ci-target-cache.ts scripts/host-detect.ts scripts/run-rs-task.ts \
.github/actions/build-native/action.yml .github/actions/native-source-hash/action.yml \
-type f -print0 \
| sort -z \
| xargs -0 sha256sum \
| sha256sum \
| cut -c1-16)
echo "source-hash=$source_hash" >> "$GITHUB_OUTPUT"
echo "Native source hash: $source_hash"
@@ -1,54 +0,0 @@
name: Restore Linux x64 native addons
description: Restore both Linux x64 variants from the in-cluster cache or a trusted GitHub artifact run.
inputs:
hash:
description: Native source hash embedded in artifact names
required: true
native-job-result:
description: Result of the current run's Linux x64 native matrix
required: true
cached-run-id:
description: Prior run containing both Linux x64 variants
required: false
default: ""
runs:
using: composite
steps:
- name: Restore native addons from in-cluster cache
id: local
shell: bash
run: |
bun scripts/ci-native-artifact-cache.ts restore \
"${{ inputs.hash }}" \
packages/natives/native \
"pi-natives-linux-x64-baseline-h${{ inputs.hash }}" \
"pi-natives-linux-x64-modern-h${{ inputs.hash }}"
- name: Resolve GitHub artifact run
if: steps.local.outputs.hit != 'true'
id: source
shell: bash
run: |
set -euo pipefail
if [ "${{ inputs.native-job-result }}" = "success" ]; then
run_id="${{ github.run_id }}"
else
run_id="${{ inputs.cached-run-id }}"
fi
if [ -z "$run_id" ]; then
echo "No Linux x64 native artifact source is available" >&2
exit 1
fi
echo "run-id=$run_id" >> "$GITHUB_OUTPUT"
- name: Download native addons from GitHub
if: steps.local.outputs.hit != 'true'
uses: actions/download-artifact@v4
with:
pattern: pi-natives-linux-x64-*-h${{ inputs.hash }}
path: packages/natives/native
merge-multiple: true
run-id: ${{ steps.source.outputs.run-id }}
github-token: ${{ github.token }}
+117 -246
View File
@@ -5,10 +5,32 @@ on:
branches: [main] branches: [main]
paths: paths:
- "packages/**" - "packages/**"
- "crates/**"
- "scripts/**"
- "bazel/**"
- "MODULE.bazel"
- "BUILD.bazel"
- ".bazelrc"
- ".bazelversion"
- "Cargo.toml"
- "Cargo.lock"
- "Cargo.Bazel.lock"
- ".github/**"
pull_request: pull_request:
branches: [main] branches: [main]
paths: paths:
- "packages/**" - "packages/**"
- "crates/**"
- "scripts/**"
- "bazel/**"
- "MODULE.bazel"
- "BUILD.bazel"
- ".bazelrc"
- ".bazelversion"
- "Cargo.toml"
- "Cargo.lock"
- "Cargo.Bazel.lock"
- ".github/**"
workflow_dispatch: workflow_dispatch:
inputs: inputs:
skip_npm: skip_npm:
@@ -30,14 +52,9 @@ concurrency:
env: env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
# audiopus_sys bundles an opus tree whose CMakeLists declares a
# cmake_minimum_required below 3.5; CMake 4.x refuses to configure it
# without this override (macOS runner images ship CMake 4).
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
permissions: permissions:
contents: read contents: read
actions: read
jobs: jobs:
# scripts/release.ts pushes the version-bump commit and its `v*` tag # scripts/release.ts pushes the version-bump commit and its `v*` tag
@@ -90,33 +107,6 @@ jobs:
echo "release-tag=$release_tag" echo "release-tag=$release_tag"
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
# Compute one native source hash, then validate complete artifact sets from
# any trusted main-branch run. Run conclusion is deliberately irrelevant:
# an upload proves that build step completed before a later job failed or a
# newer push canceled the workflow.
#
# Linux x64, the full cross-platform matrix, and Rust validation are tracked
# independently. Consumers either use a complete prior set or build the
# missing set in this run; no single canary can hide a partial matrix.
native_artifact_lookup:
name: Look up cached native artifacts
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
outputs:
source-hash: ${{ steps.compute.outputs.source-hash }}
linux-x64-run-id: ${{ steps.find.outputs.linux-x64-run-id }}
cross-platform-run-id: ${{ steps.find.outputs.cross-platform-run-id }}
validation-run-id: ${{ steps.find.outputs.validation-run-id }}
steps:
- uses: actions/checkout@v4
- name: Compute native source hash
id: compute
uses: ./.github/actions/native-source-hash
- name: Find trusted reusable artifacts
id: find
uses: ./.github/actions/find-native-artifacts
with:
hash: ${{ steps.compute.outputs.source-hash }}
check: check:
name: Lint, type check & web build name: Lint, type check & web build
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
@@ -128,121 +118,58 @@ jobs:
- name: Build collab web - name: Build collab web
run: bun run collab:web:build run: bun run collab:web:build
rust_validation: # Bazel validation and cache warm — replaces the old cargo pipeline
name: Validate Rust workspace # (rust_validation + native build matrices + hand-rolled artifact caching).
needs: [native_artifact_lookup] # `bazel test` covers the Rust suite, the clippy/rustfmt aspect configs cover
if: ${{ needs.native_artifact_lookup.outputs.validation-run-id == '' }} # linting, and on main pushes (omp-kata, read-write cache) an additional
# //:natives-linux-all build populates the shared bazel-remote cache so every
# downstream job — TS tests, releases, PR runners — gets cache hits instead
# of rebuilding. No toolchain setup: bazelisk is on the GitHub images and
# baked into the kata runner image; bazel fetches the rest hermetically.
rust:
name: Validate Rust workspace (bazel)
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/build-native - uses: ./.github/actions/bun-install
- id: cache
uses: ./.github/actions/bazel-cache
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} scope: validation
platform: linux - name: Rust tests
arch: x64 run: bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" test //crates/...
variant: baseline # Clippy scope mirrors `cargo clippy --workspace` (libraries only, no
rust_checks: "true" # test targets) plus the strict/default split: crates with
skip_build: "true" # `[lints] workspace = true` get the workspace policy, the vendored
cache_scope: validation # brush fork is exempt (same as run-rs-task.ts's cargo excludes).
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} - name: Clippy (workspace lint policy on opted-in crates)
- name: Create validation marker run: |
shell: bash bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...)" \
run: echo "${{ needs.native_artifact_lookup.outputs.source-hash }}" > "$RUNNER_TEMP/rust-validation" | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy-strict --
- name: Upload validation marker - name: Clippy (default lints elsewhere)
uses: actions/upload-artifact@v4 run: |
with: bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (//crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \
name: pi-natives-rust-validation-h${{ needs.native_artifact_lookup.outputs.source-hash }} | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy --
path: ${{ runner.temp }}/rust-validation - name: Rustfmt
retention-days: 90 run: bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=rustfmt //crates/...
- name: Warm native addon cache (main push)
# Linux x64 baseline + modern supply the TS and install jobs. Rust validation if: github.event_name != 'pull_request'
# is a separate parallel job, so both matrix entries are build-only. run: bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build //:natives-linux-all
native_linux_x64:
name: "Native: Linux x64 (${{ matrix.variant }})"
needs: [native_artifact_lookup]
if: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id == '' }}
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
strategy:
fail-fast: false
matrix:
variant: [baseline, modern]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-native
with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
platform: linux
arch: x64
variant: ${{ matrix.variant }}
skip_validation: "true"
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
# Cross-platform builds stay in this workflow only as a release fallback.
# Successful main CI runs launch the non-blocking native-prewarm workflow.
native_cross_platform_kata:
name: "Native: ${{ matrix.platform }} ${{ matrix.libc || '' }} ${{ matrix.arch }}"
needs: [release_metadata, native_artifact_lookup]
if: ${{ needs.release_metadata.outputs.is-release == 'true' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '' }}
strategy:
fail-fast: false
matrix:
include:
- { os: omp-kata, platform: linux, arch: arm64, target: aarch64-unknown-linux-gnu }
- { os: omp-kata, platform: linux, libc: musl, arch: x64, target: x86_64-unknown-linux-musl, variant: baseline }
- { os: omp-kata, platform: linux, libc: musl, arch: arm64, target: aarch64-unknown-linux-musl }
- { os: omp-kata, platform: win32, arch: x64, target: x86_64-pc-windows-msvc, variant: baseline }
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-native
with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
platform: ${{ matrix.platform }}
arch: ${{ matrix.arch }}
libc: ${{ matrix.libc }}
variant: ${{ matrix.variant }}
target: ${{ matrix.target }}
skip_validation: "true"
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
native_cross_platform_macos:
name: "Native: ${{ matrix.platform }} ${{ matrix.arch }}"
needs: [release_metadata, native_artifact_lookup]
if: ${{ needs.release_metadata.outputs.is-release == 'true' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '' }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-14, platform: darwin, arch: x64, target: x86_64-apple-darwin, variant: baseline }
- { os: macos-14, platform: darwin, arch: arm64 }
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-native
with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
platform: ${{ matrix.platform }}
arch: ${{ matrix.arch }}
variant: ${{ matrix.variant }}
target: ${{ matrix.target }}
skip_validation: "true"
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
test_workspace: test_workspace:
name: Test TS workspace fast name: Test TS workspace fast
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Test workspace packages and repo scripts (TS) - name: Test workspace packages and repo scripts (TS)
env: env:
OMP_TEST_CONCURRENCY: "4" OMP_TEST_CONCURRENCY: "4"
@@ -251,18 +178,17 @@ jobs:
test_coding_agent_singleton: test_coding_agent_singleton:
name: Test coding-agent singleton/global-state (TS) name: Test coding-agent singleton/global-state (TS)
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Test coding-agent singleton/global-state bucket - name: Test coding-agent singleton/global-state bucket
# Keep global Settings/env/fake-timer tests serial; native addon # Keep global Settings/env/fake-timer tests serial; native addon
# artifacts are still available like every other coding-agent bucket. # artifacts are still available like every other coding-agent bucket.
@@ -271,19 +197,17 @@ jobs:
test_ts_native: test_ts_native:
name: Test TS native/integration packages name: Test TS native/integration packages
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 25 timeout-minutes: 25
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Test native/TUI/browser-ish packages (TS) - name: Test native/TUI/browser-ish packages (TS)
env: env:
OMP_TEST_CONCURRENCY: "4" OMP_TEST_CONCURRENCY: "4"
@@ -292,19 +216,17 @@ jobs:
test_coding_agent_ui: test_coding_agent_ui:
name: Test coding-agent UI/TUI (TS) name: Test coding-agent UI/TUI (TS)
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 25 timeout-minutes: 25
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Test coding-agent UI/TUI bucket - name: Test coding-agent UI/TUI bucket
env: env:
OMP_TEST_CONCURRENCY: "2" OMP_TEST_CONCURRENCY: "2"
@@ -313,18 +235,17 @@ jobs:
test_coding_agent_runtime: test_coding_agent_runtime:
name: Test coding-agent runtime/session (TS) name: Test coding-agent runtime/session (TS)
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 25 timeout-minutes: 25
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Test coding-agent runtime bucket - name: Test coding-agent runtime bucket
# Runtime/session tests import native-backed barrels too; keep this # Runtime/session tests import native-backed barrels too; keep this
# separate for concurrency, not as a native-free guardrail. # separate for concurrency, not as a native-free guardrail.
@@ -335,19 +256,17 @@ jobs:
test_coding_agent_native: test_coding_agent_native:
name: Test coding-agent native/unit (TS) name: Test coding-agent native/unit (TS)
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 25 timeout-minutes: 25
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Test coding-agent native/unit bucket - name: Test coding-agent native/unit bucket
env: env:
OMP_TEST_CONCURRENCY: "4" OMP_TEST_CONCURRENCY: "4"
@@ -356,49 +275,42 @@ jobs:
test_smoke: test_smoke:
name: Test CLI smoke (TS) name: Test CLI smoke (TS)
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
timeout-minutes: 15 timeout-minutes: 15
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: CLI smoke test - name: CLI smoke test
run: bun run ci:test:smoke run: bun run ci:test:smoke
install_methods: install_methods:
name: Install method smoke tests name: Install method smoke tests
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
needs: [native_linux_x64, native_artifact_lookup] needs: [rust]
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} if: ${{ !cancelled() && needs.rust.result == 'success' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: ./.github/actions/setup-system-deps - uses: ./.github/actions/setup-system-deps
- uses: ./.github/actions/bun-install - uses: ./.github/actions/bun-install
- uses: ./.github/actions/restore-linux-native - uses: ./.github/actions/bazel-natives
with: with:
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
native-job-result: ${{ needs.native_linux_x64.result }} cache-scope: linux-x64-pair
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
- name: Install method smoke tests - name: Install method smoke tests
env: env:
OMP_INSTALL_TEST_SKIP_NATIVE_BUILD: "1" OMP_INSTALL_TEST_SKIP_NATIVE_BUILD: "1"
run: bun run ci:test:install-methods run: bun run ci:test:install-methods
release_binary: release_binary:
name: "Release binary: ${{ matrix.target_id }}" name: "Release binary: ${{ matrix.target_id }}"
if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() &&
needs.rust_validation.result != 'failure' && needs.rust.result == 'success' &&
needs.native_linux_x64.result != 'failure' &&
needs.native_cross_platform_kata.result != 'failure' &&
needs.native_cross_platform_macos.result != 'failure' &&
needs.test_workspace.result == 'success' && needs.test_workspace.result == 'success' &&
needs.test_coding_agent_singleton.result == 'success' && needs.test_coding_agent_singleton.result == 'success' &&
needs.test_ts_native.result == 'success' && needs.test_ts_native.result == 'success' &&
@@ -407,7 +319,7 @@ jobs:
needs.test_coding_agent_native.result == 'success' && needs.test_coding_agent_native.result == 'success' &&
needs.test_smoke.result == 'success' && needs.check.result == 'success' && needs.test_smoke.result == 'success' && needs.check.result == 'success' &&
needs.install_methods.result == 'success' }} needs.install_methods.result == 'success' }}
needs: [release_metadata, check, rust_validation, native_linux_x64, native_cross_platform_kata, native_cross_platform_macos, test_workspace, test_coding_agent_singleton, test_ts_native, test_coding_agent_ui, test_coding_agent_runtime, test_coding_agent_native, test_smoke, install_methods, native_artifact_lookup] needs: [release_metadata, check, rust, test_workspace, test_coding_agent_singleton, test_ts_native, test_coding_agent_ui, test_coding_agent_runtime, test_coding_agent_native, test_smoke, install_methods]
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -418,7 +330,7 @@ jobs:
arch: x64, arch: x64,
target_id: linux-x64, target_id: linux-x64,
binary_path: packages/coding-agent/binaries/omp-linux-x64, binary_path: packages/coding-agent/binaries/omp-linux-x64,
native_artifact_pattern: pi-natives-linux-x64-*, native_targets: linux-x64-baseline linux-x64-modern,
} }
- { - {
os: ubuntu-22.04, os: ubuntu-22.04,
@@ -427,7 +339,7 @@ jobs:
arch: x64, arch: x64,
target_id: linux-musl-x64, target_id: linux-musl-x64,
binary_path: packages/coding-agent/binaries/omp-linux-musl-x64, binary_path: packages/coding-agent/binaries/omp-linux-musl-x64,
native_artifact_pattern: pi-natives-linux-musl-x64-*, native_targets: linux-musl-x64-baseline,
} }
- { - {
os: ubuntu-24.04-arm, os: ubuntu-24.04-arm,
@@ -435,7 +347,7 @@ jobs:
arch: arm64, arch: arm64,
target_id: linux-arm64, target_id: linux-arm64,
binary_path: packages/coding-agent/binaries/omp-linux-arm64, binary_path: packages/coding-agent/binaries/omp-linux-arm64,
native_artifact_pattern: pi-natives-linux-arm64*, native_targets: linux-arm64,
} }
- { - {
os: ubuntu-24.04-arm, os: ubuntu-24.04-arm,
@@ -444,7 +356,7 @@ jobs:
arch: arm64, arch: arm64,
target_id: linux-musl-arm64, target_id: linux-musl-arm64,
binary_path: packages/coding-agent/binaries/omp-linux-musl-arm64, binary_path: packages/coding-agent/binaries/omp-linux-musl-arm64,
native_artifact_pattern: pi-natives-linux-musl-arm64*, native_targets: linux-musl-arm64,
} }
- { - {
os: macos-15-intel, os: macos-15-intel,
@@ -452,7 +364,7 @@ jobs:
arch: x64, arch: x64,
target_id: darwin-x64, target_id: darwin-x64,
binary_path: packages/coding-agent/binaries/omp-darwin-x64, binary_path: packages/coding-agent/binaries/omp-darwin-x64,
native_artifact_pattern: pi-natives-darwin-x64*, native_targets: darwin-all,
} }
- { - {
os: macos-14, os: macos-14,
@@ -460,7 +372,7 @@ jobs:
arch: arm64, arch: arm64,
target_id: darwin-arm64, target_id: darwin-arm64,
binary_path: packages/coding-agent/binaries/omp-darwin-arm64, binary_path: packages/coding-agent/binaries/omp-darwin-arm64,
native_artifact_pattern: pi-natives-darwin-arm64*, native_targets: darwin-all,
} }
- { - {
os: ubuntu-22.04, os: ubuntu-22.04,
@@ -468,12 +380,11 @@ jobs:
arch: x64, arch: x64,
target_id: win32-x64, target_id: win32-x64,
binary_path: packages/coding-agent/binaries/omp-windows-x64.exe, binary_path: packages/coding-agent/binaries/omp-windows-x64.exe,
native_artifact_pattern: pi-natives-win32-x64*, native_targets: win32-x64-baseline,
} }
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
permissions: permissions:
contents: read contents: read
actions: read
id-token: write id-token: write
env: env:
MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }} MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }}
@@ -482,9 +393,6 @@ jobs:
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
bun-version: "1.3" bun-version: "1.3"
env:
SCCACHE_BUCKET: ""
AWS_ACCESS_KEY_ID: ""
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with: with:
node-version: "24" node-version: "24"
@@ -500,36 +408,14 @@ jobs:
path: ~/.bun/install/cache path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
- run: bun install --frozen-lockfile - run: bun install --frozen-lockfile
- name: Resolve native artifact run # Release runners are GitHub-hosted and never touch the private
id: native-source # cluster cache: they build with the actions/cache-backed disk cache,
shell: bash # so repeat releases with unchanged Rust are mostly local cache hits.
run: | - name: Build native addon(s) (bazel)
set -euo pipefail uses: ./.github/actions/bazel-natives
if [ "${{ matrix.target_id }}" = "linux-x64" ]; then
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
run_id="${{ github.run_id }}"
else
run_id="${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}"
fi
elif [ "${{ needs.native_cross_platform_kata.result }}" = "success" ] || \
[ "${{ needs.native_cross_platform_macos.result }}" = "success" ]; then
run_id="${{ github.run_id }}"
else
run_id="${{ needs.native_artifact_lookup.outputs.cross-platform-run-id }}"
fi
if [ -z "$run_id" ]; then
echo "No native artifact run for ${{ matrix.target_id }}" >&2
exit 1
fi
echo "run-id=$run_id" >> "$GITHUB_OUTPUT"
- name: Download native addon(s)
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with: with:
pattern: ${{ matrix.native_artifact_pattern }}-h${{ needs.native_artifact_lookup.outputs.source-hash }} targets: ${{ matrix.native_targets }}
path: packages/natives/native cache-scope: release-${{ matrix.target_id }}
merge-multiple: true
run-id: ${{ steps.native-source.outputs.run-id }}
github-token: ${{ github.token }}
- name: Build release binary - name: Build release binary
env: env:
RELEASE_TARGETS: ${{ matrix.target_id }} RELEASE_TARGETS: ${{ matrix.target_id }}
@@ -548,8 +434,7 @@ jobs:
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
run: bash scripts/ci-macos-sign.sh "${{ matrix.binary_path }}" run: bash scripts/ci-macos-sign.sh "${{ matrix.binary_path }}"
# Windows binary is cross-built on Linux, so we have no Windows runner # Windows binary is cross-built on Linux, so we have no Windows runner
# to smoke it on. Cross-build correctness is verified via the napi # to smoke it on. Cross-build correctness is verified via the bun
# entry-point exports (see build-native action) and the bun
# `--compile --target=bun-windows-x64-*` cross-compile. Musl binaries # `--compile --target=bun-windows-x64-*` cross-compile. Musl binaries
# need the musl loader, which glibc runners lack — they are smoked in # need the musl loader, which glibc runners lack — they are smoked in
# the Alpine container step below instead. # the Alpine container step below instead.
@@ -622,7 +507,6 @@ jobs:
body_path: release-notes.md body_path: release-notes.md
generate_release_notes: true generate_release_notes: true
release_github_verify: release_github_verify:
name: Verify published release (macOS) name: Verify published release (macOS)
if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() &&
@@ -663,7 +547,7 @@ jobs:
needs.release_binary.result == 'success' && needs.release_binary.result == 'success' &&
needs.release_github_verify.result == 'success' && needs.release_github_verify.result == 'success' &&
!inputs.skip_npm }} !inputs.skip_npm }}
needs: [release_metadata, release_binary, release_github_verify, native_linux_x64, native_artifact_lookup] needs: [release_metadata, release_binary, release_github_verify]
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# `id-token: write` lets npm mint the GitHub OIDC token it exchanges for a # `id-token: write` lets npm mint the GitHub OIDC token it exchanges for a
# short-lived publish token (trusted publishing + provenance). When a # short-lived publish token (trusted publishing + provenance). When a
@@ -672,7 +556,6 @@ jobs:
permissions: permissions:
id-token: write id-token: write
contents: read contents: read
actions: read
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
@@ -695,23 +578,11 @@ jobs:
# The pi-coding-agent prepack executes workspace code (bundle-dist # The pi-coding-agent prepack executes workspace code (bundle-dist
# imports the pi-utils barrel, which loads the pi-natives addon), so # imports the pi-utils barrel, which loads the pi-natives addon), so
# this job needs the Linux x64 native addons just like TS tests do. # this job needs the Linux x64 native addons just like TS tests do.
- name: Resolve Linux x64 native artifact run - name: Build native addons (bazel)
id: native-source uses: ./.github/actions/bazel-natives
shell: bash
run: |
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
else
echo "run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
fi
- name: Download native addons
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with: with:
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} targets: linux-x64-baseline linux-x64-modern
path: packages/natives/native cache-scope: linux-x64-pair
merge-multiple: true
run-id: ${{ steps.native-source.outputs.run-id }}
github-token: ${{ github.token }}
- name: Publish to npm - name: Publish to npm
env: env:
# Fallback auth: setup-node wrote an .npmrc referencing # Fallback auth: setup-node wrote an .npmrc referencing
-90
View File
@@ -1,90 +0,0 @@
name: Native prewarm
on:
workflow_run:
workflows: [CI]
types: [completed]
workflow_dispatch:
# Prewarming must never extend the required CI workflow. Keep one warmup running
# to completion so it publishes the target snapshot; GitHub coalesces newer
# pending runs in this concurrency group.
concurrency:
group: native-prewarm-main
cancel-in-progress: false
permissions:
actions: read
contents: read
jobs:
lookup:
name: Look up cross-platform artifacts
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main') }}
runs-on: omp-kata
outputs:
source-hash: ${{ steps.compute.outputs.source-hash }}
cross-platform-run-id: ${{ steps.find.outputs.cross-platform-run-id }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- id: compute
uses: ./.github/actions/native-source-hash
- id: find
uses: ./.github/actions/find-native-artifacts
with:
hash: ${{ steps.compute.outputs.source-hash }}
cross_platform_kata:
name: "Prewarm native: ${{ matrix.platform }} ${{ matrix.libc || '' }} ${{ matrix.arch }}"
needs: [lookup]
if: ${{ needs.lookup.outputs.cross-platform-run-id == '' }}
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- { platform: linux, arch: arm64, target: aarch64-unknown-linux-gnu }
- { platform: linux, libc: musl, arch: x64, target: x86_64-unknown-linux-musl, variant: baseline }
- { platform: linux, libc: musl, arch: arm64, target: aarch64-unknown-linux-musl }
- { platform: win32, arch: x64, target: x86_64-pc-windows-msvc, variant: baseline }
runs-on: omp-kata
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- uses: ./.github/actions/build-native
with:
hash: ${{ needs.lookup.outputs.source-hash }}
platform: ${{ matrix.platform }}
libc: ${{ matrix.libc }}
arch: ${{ matrix.arch }}
variant: ${{ matrix.variant }}
target: ${{ matrix.target }}
skip_validation: "true"
save_cache: "true"
cross_platform_macos:
name: "Prewarm native: darwin ${{ matrix.arch }}"
needs: [lookup]
if: ${{ needs.lookup.outputs.cross-platform-run-id == '' }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-14, arch: x64, target: x86_64-apple-darwin, variant: baseline }
- { os: macos-14, arch: arm64 }
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- uses: ./.github/actions/build-native
with:
hash: ${{ needs.lookup.outputs.source-hash }}
platform: darwin
arch: ${{ matrix.arch }}
variant: ${{ matrix.variant }}
target: ${{ matrix.target }}
skip_validation: "true"
save_cache: "true"
+7
View File
@@ -78,3 +78,10 @@ python/robomp/.env
# Local, machine-specific boot perf baseline (see packages/coding-agent/scripts/bench-guard.ts) # Local, machine-specific boot perf baseline (see packages/coding-agent/scripts/bench-guard.ts)
packages/coding-agent/bench/boot-baseline.json packages/coding-agent/bench/boot-baseline.json
# Bazel
/bazel-bin
/bazel-out
/bazel-testlogs
/bazel-pi
/.bazelrc.user
+58
View File
@@ -0,0 +1,58 @@
# Shipping pi_natives addons, one per (platform, arch, ISA-variant).
# `bazel build //:natives-<target>` yields the canonically named .node file;
# packages/natives/scripts/build-native.ts copies it into packages/natives/native/.
# Note: musl addons intentionally reuse the plain linux-<arch> filenames — the
# loader never sees gnu and musl side by side; release jobs keep them apart.
load("//bazel:defs.bzl", "native_addon")
package(default_visibility = ["//visibility:public"])
exports_files([
"Cargo.toml",
"Cargo.lock",
"Cargo.Bazel.lock",
"rustfmt.toml",
])
_ADDONS = {
"linux-x64-baseline": ("//bazel/platforms:linux-x64-baseline", "pi_natives.linux-x64-baseline.node"),
"linux-x64-modern": ("//bazel/platforms:linux-x64-modern", "pi_natives.linux-x64-modern.node"),
"linux-arm64": ("//bazel/platforms:linux-arm64", "pi_natives.linux-arm64.node"),
"linux-musl-x64-baseline": ("//bazel/platforms:linux-musl-x64-baseline", "pi_natives.linux-x64-baseline.node"),
"linux-musl-arm64": ("//bazel/platforms:linux-musl-arm64", "pi_natives.linux-arm64.node"),
"darwin-x64-baseline": ("//bazel/platforms:darwin-x64-baseline", "pi_natives.darwin-x64-baseline.node"),
"darwin-arm64": ("//bazel/platforms:darwin-arm64", "pi_natives.darwin-arm64.node"),
"win32-x64-baseline": ("//bazel/platforms:win32-x64-baseline", "pi_natives.win32-x64-baseline.node"),
}
[
native_addon(
name = "natives-" + target,
lib = "//crates/pi-natives:pi_natives",
out = out,
platform = platform,
)
for target, (platform, out) in _ADDONS.items()
]
# Every addon buildable from a linux-x64 host (the omp-kata pods): all linux
# targets plus the msvc cross build. darwin addons build on mac hosts.
filegroup(
name = "natives-linux-all",
srcs = [
":natives-linux-arm64",
":natives-linux-musl-arm64",
":natives-linux-musl-x64-baseline",
":natives-linux-x64-baseline",
":natives-linux-x64-modern",
":natives-win32-x64-baseline",
],
)
filegroup(
name = "natives-darwin-all",
srcs = [
":natives-darwin-arm64",
":natives-darwin-x64-baseline",
],
)
+61561
View File
File diff suppressed because it is too large Load Diff
Generated
+26 -3
View File
@@ -502,8 +502,6 @@ dependencies = [
"cexpr", "cexpr",
"clang-sys", "clang-sys",
"itertools 0.13.0", "itertools 0.13.0",
"log",
"prettyplease",
"proc-macro2", "proc-macro2",
"quote", "quote",
"regex", "regex",
@@ -654,6 +652,7 @@ dependencies = [
name = "brush-builtins" name = "brush-builtins"
version = "0.2.0" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow",
"brush-core", "brush-core",
"brush-parser 0.4.0", "brush-parser 0.4.0",
"cfg-if", "cfg-if",
@@ -663,6 +662,7 @@ dependencies = [
"futures", "futures",
"itertools 0.14.0", "itertools 0.14.0",
"nix 0.31.3", "nix 0.31.3",
"pretty_assertions",
"procfs", "procfs",
"rlimit", "rlimit",
"strum", "strum",
@@ -677,6 +677,7 @@ dependencies = [
name = "brush-core" name = "brush-core"
version = "0.5.0" version = "0.5.0"
dependencies = [ dependencies = [
"anyhow",
"async-recursion", "async-recursion",
"async-trait", "async-trait",
"bon", "bon",
@@ -697,10 +698,13 @@ dependencies = [
"libc", "libc",
"nix 0.31.3", "nix 0.31.3",
"normalize-path", "normalize-path",
"pretty_assertions",
"rand 0.10.2", "rand 0.10.2",
"rpds", "rpds",
"serde",
"strum", "strum",
"strum_macros", "strum_macros",
"tempfile",
"terminfo", "terminfo",
"thiserror 2.0.19", "thiserror 2.0.19",
"tokio", "tokio",
@@ -739,10 +743,12 @@ dependencies = [
"indenter", "indenter",
"insta", "insta",
"peg", "peg",
"serde",
"thiserror 2.0.19", "thiserror 2.0.19",
"tracing", "tracing",
"utf8-chars", "utf8-chars",
"uuid", "uuid",
"winnow 1.0.4",
] ]
[[package]] [[package]]
@@ -1029,6 +1035,7 @@ dependencies = [
"iana-time-zone", "iana-time-zone",
"js-sys", "js-sys",
"num-traits", "num-traits",
"serde",
"wasm-bindgen", "wasm-bindgen",
"windows-link 0.2.1", "windows-link 0.2.1",
] ]
@@ -1638,6 +1645,12 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.7" version = "0.10.7"
@@ -3648,7 +3661,6 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00ae1969d0a389937161b834623e5cba2d8449752a0970d71382cf9a905bb35" checksum = "f00ae1969d0a389937161b834623e5cba2d8449752a0970d71382cf9a905bb35"
dependencies = [ dependencies = [
"bindgen",
"cc", "cc",
] ]
@@ -5183,6 +5195,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "pretty_assertions"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
dependencies = [
"diff",
"yansi",
]
[[package]] [[package]]
name = "prettyplease" name = "prettyplease"
version = "0.2.37" version = "0.2.37"
@@ -5615,6 +5637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e025feb26210bc196b908e72deb063b1b4000754304341cbc168a1e72c857ebc" checksum = "e025feb26210bc196b908e72deb063b1b4000754304341cbc168a1e72c857ebc"
dependencies = [ dependencies = [
"archery", "archery",
"serde",
"smallvec", "smallvec",
] ]
+3 -2
View File
@@ -1,6 +1,5 @@
[workspace] [workspace]
members = ["crates/pi-*", "crates/vendor/*"] members = ["crates/pi-*", "crates/vendor/*"]
exclude = ["crates/vendor/brush-core", "crates/vendor/brush-builtins"]
resolver = "3" resolver = "3"
[workspace.package] [workspace.package]
@@ -242,7 +241,9 @@ xxhash-rust = { version = "0.8", features = ["xxh64"] }
# Audio & Realtime Media # Audio & Realtime Media
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
audiopus_sys = { version = "0.2.2", features = ["static"] } audiopus_sys = { version = "0.2.2", features = ["static"] }
maudio = { version = "0.1.6", features = ["generate-bindings"] } # Pregenerated bindings (crate default): keeps bindgen/libclang out of the
# build graph so Bazel actions stay hermetic.
maudio = "0.1.6"
opus = "0.3.1" opus = "0.3.1"
webrtc = "0.17.2" webrtc = "0.17.2"
+187
View File
@@ -0,0 +1,187 @@
"""oh-my-pi — Bazel build for the native (Rust) side of the workspace.
Builds the pi_natives NAPI cdylib for every shipped target with hermetic
toolchains, replacing cargo-zigbuild/cargo-xwin/sccache plus the hand-rolled
CI caches with Bazel's content-addressed action cache (see infra/bazel-remote.yaml).
Layout:
//:natives-<target> release-grade renamed .node artifacts (root BUILD.bazel)
//crates/... first-party crate targets
//bazel/... platforms, ISA-variant constraints, toolchains, rules
@crates//... third-party crates from Cargo.lock via crate_universe
The cargo workspace stays authoritative for local iteration (rust-analyzer,
`cargo nextest`, napi typedef regeneration); Bazel is the artifact and CI
pipeline. Keep Cargo.toml/Cargo.lock and this module in sync: after editing
either, run `bun run bazel:repin` (CARGO_BAZEL_REPIN=1) to refresh Cargo.Bazel.lock.
"""
module(name = "oh-my-pi")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "1.1.0")
bazel_dep(name = "rules_rust", version = "0.71.3")
bazel_dep(name = "hermetic_cc_toolchain", version = "4.2.0")
# --- Rust toolchains ----------------------------------------------------------
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = "2024",
versions = ["nightly/2026-04-29"],
extra_target_triples = [
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-musl",
"x86_64-apple-darwin",
"aarch64-apple-darwin",
"x86_64-pc-windows-msvc",
],
)
use_repo(
rust,
"rust_toolchains",
# musl rustc toolchains, re-registered in //bazel/toolchains with an
# explicit @zig_sdk//libc:musl constraint: rules_rust's generated gnu and
# musl toolchains share (os, cpu) constraints, so without the extra
# constraint whichever registers first would win for both libcs.
"rust_linux_x86_64__x86_64-unknown-linux-musl__nightly_tools",
"rust_linux_x86_64__aarch64-unknown-linux-musl__nightly_tools",
"rust_macos_aarch64__x86_64-unknown-linux-musl__nightly_tools",
"rust_macos_aarch64__aarch64-unknown-linux-musl__nightly_tools",
"rust_linux_aarch64__aarch64-unknown-linux-musl__nightly_tools",
"rust_linux_aarch64__x86_64-unknown-linux-musl__nightly_tools",
)
# Order matters: repo-local toolchains (musl disambiguation wrappers, msvc
# cross cc toolchain) MUST resolve before the generated @rust_toolchains set.
register_toolchains("//bazel/toolchains:all")
register_toolchains("@rust_toolchains//:all")
# --- C/C++ toolchains ---------------------------------------------------------
# zig cc provides hermetic linux-gnu (pinned glibc 2.17 portability floor, same
# floor cargo-zigbuild used) and linux-musl cross toolchains, executable from
# both linux-x64 CI pods and darwin dev hosts. darwin targets use the host
# Xcode toolchain (Apple frameworks are not redistributable); win32-msvc uses
# the hermetic clang-cl+xwin toolchain in //bazel/toolchains/msvc.
zig = use_extension("@hermetic_cc_toolchain//toolchain:ext.bzl", "toolchains")
use_repo(zig, "zig_sdk")
register_toolchains(
"@zig_sdk//libc_aware/toolchain:linux_amd64_gnu.2.17",
"@zig_sdk//libc_aware/toolchain:linux_arm64_gnu.2.17",
"@zig_sdk//libc_aware/toolchain:linux_amd64_musl",
"@zig_sdk//libc_aware/toolchain:linux_arm64_musl",
)
# --- Third-party crates (crate_universe over the cargo workspace) --------------
crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
crate.render_config(
# rules_rust's builtin platform settings have no musl triples; ours in
# //bazel/triples add the @zig_sdk//libc axis.
platforms_template = "@@//bazel/triples:{triple}",
)
crate.from_cargo(
name = "crates",
cargo_lockfile = "//:Cargo.lock",
lockfile = "//:Cargo.Bazel.lock",
# Exactly the shipped addon triples: crate BUILD files get
# target_compatible_with selects over this set (defaults omit darwin-x64
# and musl), and features/deps resolve per-triple from Cargo.lock.
supported_platform_triples = [
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-musl",
"x86_64-apple-darwin",
"aarch64-apple-darwin",
"x86_64-pc-windows-msvc",
],
# The root manifest covers all workspace members, including the vendored
# brush fork (members so their sources render hermetically; the
# [patch.crates-io] entries redirect brush-builtins' registry dep to them).
manifests = ["//:Cargo.toml"],
)
# audiopus_sys builds its vendored opus via the `cmake` crate: give the build
# script a PATH that resolves cmake/make (runner image, GH runners, dev hosts)
# and the policy override its old CMakeLists needs under CMake 4.x. The cmake
# crate picks up CC/CFLAGS from the Bazel cc toolchain on its own.
crate.annotation(
crate = "audiopus_sys",
build_script_env = {
"CMAKE_POLICY_VERSION_MINIMUM": "3.5",
# msvc cross only (cmake-rs reads VAR_<triple> before VAR; the key is
# inert for every other target): without a generator override cmake-rs
# insists on a Visual Studio generator for msvc targets, which cannot
# exist on linux/mac hosts. Ninja must be on the PATH below.
"CMAKE_GENERATOR_x86_64_pc_windows_msvc": "Ninja",
# msvc cross only: cmake's vs_link_exe insists on rc/mt tools for
# MSVC-ABI exe links (try_compile), which find_program can't locate on
# linux/mac PATH. @msvc_cc's toolchain.cmake pins compiler/linker/
# rc/mt to the wrapper dir (self-locating via CMAKE_CURRENT_LIST_DIR).
# $${pwd} → exec root in the rules_rust runner; the canonical repo
# path must track the repo rule/name in the msvc section below.
"CMAKE_TOOLCHAIN_FILE_x86_64_pc_windows_msvc": "$${pwd}/external/+msvc_cc_repository+msvc_cc/toolchain.cmake",
# zig cc enables UBSan by default; cmake's try-compile links a test
# exe with the raw wrapper (no toolchain features), which would demand
# the UBSan runtime. Opus shipped without sanitizers under
# cargo-zigbuild too.
"CFLAGS": "-fno-sanitize=undefined",
"PATH": "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin",
},
)
# Release addons must never pick up a host libpcre2 (Homebrew paths leaked into
# shipped dylibs before); always build the vendored static copy.
crate.annotation(
crate = "pcre2-sys",
build_script_env = {"PCRE2_SYS_STATIC": "1"},
)
# tree-sitter-just's scanner.c hard-errors when NDEBUG is set (opt-mode cc
# default). cc-rs appends env CFLAGS after its computed flags, so -UNDEBUG wins.
crate.annotation(
crate = "tree-sitter-just",
build_script_env = {"CFLAGS": "-UNDEBUG"},
)
use_repo(crate, "crates")
# --- msvc cross toolchain (owned by bazel/toolchains/msvc) ---------------------
# Hermetic clang-cl + lld-link + xwin CRT/SDK toolchain for x86_64-pc-windows-msvc
# (replaces cargo-xwin). Three repos so flag iteration in cc.bzl never
# invalidates the ~2 GiB LLVM download or the ~1 GiB xwin splat:
# @llvm_msvc_tools pruned LLVM 20.1.7 release binaries for the exec host
# @xwin_sysroot MSVC CRT + Windows SDK splatted by pinned xwin 0.6.5
# @msvc_cc wrappers + MSVC-flavored cc_toolchain (rules_cc config)
# toolchain() registrations live in //bazel/toolchains (one per exec host).
# rules_cc pin matches Bazel 9.2's own builtin dependency.
bazel_dep(name = "rules_cc", version = "0.2.17")
llvm_msvc_tools = use_repo_rule("//bazel/toolchains/msvc:llvm.bzl", "llvm_msvc_tools_repository")
llvm_msvc_tools(name = "llvm_msvc_tools")
xwin_sysroot = use_repo_rule("//bazel/toolchains/msvc:sysroot.bzl", "xwin_sysroot_repository")
xwin_sysroot(name = "xwin_sysroot")
msvc_cc = use_repo_rule("//bazel/toolchains/msvc:cc.bzl", "msvc_cc_repository")
msvc_cc(name = "msvc_cc")
# blake3 assembles MASM .asm for x64 msvc targets; cc-rs resolves `ml64.exe`
# from the build-script PATH on non-windows hosts. Prepend @msvc_cc's wrapper
# dir (bin/ml64.exe → llvm-ml -m64; the dir rides into the sandbox with the
# resolved cc toolchain's all_files). ${pwd} expands to the exec root in the
# rules_rust build-script runner. The leading entry is the canonical repo path
# of @msvc_cc (`+<repo rule>+<name>`) — keep in sync if the rule or repo in
# this section is ever renamed. On non-msvc targets the dir simply does not
# exist and the rest of the PATH matches the audiopus_sys annotation above.
crate.annotation(
crate = "blake3",
build_script_env = {
"PATH": "$${pwd}/external/+msvc_cc_repository+msvc_cc/bin:/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin",
},
)
# --- end msvc cross toolchain ---------------------------------------------------
+460
View File
@@ -0,0 +1,460 @@
{
"lockFileVersion": 28,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
"https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
"https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
"https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
"https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215",
"https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2",
"https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c",
"https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896",
"https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
"https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e",
"https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1",
"https://bcr.bazel.build/modules/apple_support/1.24.1/MODULE.bazel": "f46e8ddad60aef170ee92b2f3d00ef66c147ceafea68b6877cb45bd91737f5f8",
"https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4",
"https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d",
"https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
"https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
"https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
"https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
"https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
"https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
"https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b",
"https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a",
"https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65",
"https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d",
"https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
"https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6",
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
"https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080",
"https://bcr.bazel.build/modules/bazel_features/1.50.0/MODULE.bazel": "2083ef9c7a469f520890483ccf8e0189d6e71e2117e7752e15e6554433d5ae3e",
"https://bcr.bazel.build/modules/bazel_features/1.50.0/source.json": "e0ee3debde2789ff56e4452e612d126925ba9ab64d4bde79c67f099d2902df9b",
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
"https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
"https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb",
"https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f",
"https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd",
"https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
"https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
"https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108",
"https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46",
"https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713",
"https://bcr.bazel.build/modules/hermetic_cc_toolchain/4.2.0/MODULE.bazel": "368720c724c9c0afef18dcb0782ab25294275159bc6e88fa61745d63ba79aa9d",
"https://bcr.bazel.build/modules/hermetic_cc_toolchain/4.2.0/source.json": "05535cb7f04d8c92174681d62b807d0166356d5461e0f376b789214d6696c08f",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
"https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0",
"https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000",
"https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
"https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74",
"https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9",
"https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83",
"https://bcr.bazel.build/modules/package_metadata/0.0.3/source.json": "742075a428ad12a3fa18a69014c2f57f01af910c6d9d18646c990200853e641a",
"https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
"https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
"https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
"https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
"https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
"https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
"https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
"https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580",
"https://bcr.bazel.build/modules/platforms/1.1.0/MODULE.bazel": "1c0c09f5bdcf4b3f924720d2478a3711cb39f4977019ca5988685e5b7e18b3d2",
"https://bcr.bazel.build/modules/platforms/1.1.0/source.json": "fcf351c47596c939140ab0d333dfdd08ed1ea6ce33c2fe70c12493a301cf1344",
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
"https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
"https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
"https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92",
"https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95",
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d",
"https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42",
"https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
"https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
"https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680",
"https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
"https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a",
"https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4",
"https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
"https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
"https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
"https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a",
"https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68",
"https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
"https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
"https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
"https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
"https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a",
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
"https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
"https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0",
"https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8",
"https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c",
"https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37",
"https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8",
"https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84",
"https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07",
"https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc",
"https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642",
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
"https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
"https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
"https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
"https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
"https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
"https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2",
"https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d",
"https://bcr.bazel.build/modules/rules_java/9.1.0/source.json": "da589573c1dee2c9ac4a568b301269a2e8191110ff0345c1a959fa7ea6c4dfd6",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
"https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
"https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
"https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd",
"https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
"https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
"https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
"https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
"https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
"https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483",
"https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
"https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96",
"https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e",
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
"https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
"https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
"https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
"https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
"https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937",
"https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
"https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13",
"https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6",
"https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8",
"https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8",
"https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32",
"https://bcr.bazel.build/modules/rules_rust/0.71.3/MODULE.bazel": "e2390c96f77d65f00c769bf665678c5424188e9c777239cfaae2a8d2dde7b981",
"https://bcr.bazel.build/modules/rules_rust/0.71.3/source.json": "5eb5d8068571725bc893045f8137ed7937988f23d73c53ea443470e8047598ad",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
"https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b",
"https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b",
"https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c",
"https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca",
"https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046",
"https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd",
"https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400",
"https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66",
"https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
"https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
"https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
"https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5",
"https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216",
"https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91",
"https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f",
"https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b",
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
"https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
},
"selectedYankedVersions": {},
"moduleExtensions": {
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
"general": {
"bzlTransitiveDigest": "+Kp6j204mBZ3mxlIDDR0gBoP45BZ4jYRhRAcB8sU0qc=",
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
"recordedInputs": [
"REPO_MAPPING:rules_kotlin+,bazel_tools bazel_tools"
],
"generatedRepoSpecs": {
"com_github_jetbrains_kotlin_git": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
"attributes": {
"urls": [
"https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
],
"sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
}
},
"com_github_jetbrains_kotlin": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
"attributes": {
"git_repository_name": "com_github_jetbrains_kotlin_git",
"compiler_version": "1.9.23"
}
},
"com_github_google_ksp": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
"attributes": {
"urls": [
"https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
],
"sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
"strip_version": "1.9.23-1.0.20"
}
},
"com_github_pinterest_ktlint": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
"urls": [
"https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
],
"executable": true
}
},
"rules_android": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
"strip_prefix": "rules_android-0.1.1",
"urls": [
"https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
]
}
}
}
}
},
"@@rules_python+//python/extensions:config.bzl%config": {
"general": {
"bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=",
"usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=",
"recordedInputs": [
"REPO_MAPPING:rules_python+,bazel_tools bazel_tools",
"REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build",
"REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click",
"REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama",
"REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata",
"REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer",
"REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools",
"REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging",
"REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517",
"REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip",
"REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools",
"REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks",
"REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools",
"REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli",
"REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel",
"REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp"
],
"generatedRepoSpecs": {
"rules_python_internal": {
"repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo",
"attributes": {
"transition_setting_generators": {},
"transition_settings": []
}
},
"pypi__build": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl",
"sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__click": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl",
"sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__colorama": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",
"sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__importlib_metadata": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl",
"sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__installer": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl",
"sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__more_itertools": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl",
"sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__packaging": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl",
"sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pep517": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl",
"sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pip": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl",
"sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pip_tools": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl",
"sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pyproject_hooks": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl",
"sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__setuptools": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl",
"sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__tomli": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
"sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__wheel": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl",
"sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__zipp": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl",
"sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
}
}
}
},
"@@rules_python+//python/uv:uv.bzl%uv": {
"general": {
"bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=",
"usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=",
"recordedInputs": [
"REPO_MAPPING:rules_python+,bazel_tools bazel_tools",
"REPO_MAPPING:rules_python+,platforms platforms"
],
"generatedRepoSpecs": {
"uv": {
"repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo",
"attributes": {
"toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'",
"toolchain_names": [
"none"
],
"toolchain_implementations": {
"none": "'@@rules_python+//python:none'"
},
"toolchain_compatible_with": {
"none": [
"@platforms//:incompatible"
]
},
"toolchain_target_settings": {}
}
}
}
}
}
},
"facts": {},
"factsVersions": {}
}
+1
View File
@@ -0,0 +1 @@
# Namespace package for repo-local Bazel rules (defs.bzl).
+48
View File
@@ -0,0 +1,48 @@
# Generated from [workspace.lints] in Cargo.toml (see .bazelrc clippy-strict).
# Applies only to crates that opt in via `[lints] workspace = true`.
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Amismatched_lifetime_syntaxes
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::all
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Dclippy::correctness
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::nursery
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::pedantic
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::perf
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::style
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Dclippy::suspicious
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::allow_attributes_without_reason
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::borrow_as_ptr
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::cast_lossless
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::cast_possible_truncation
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::cast_possible_wrap
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::cast_precision_loss
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::cast_ptr_alignment
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::cast_sign_loss
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::default_trait_access
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::enum_glob_use
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::float_cmp
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::inconsistent_struct_constructor
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::inline_always
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::items_after_statements
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::let_underscore_untyped
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::match_same_arms
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::match_wildcard_for_single_variants
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::missing_errors_doc
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::missing_fields_in_debug
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::missing_panics_doc
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::must_use_candidate
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::needless_pass_by_value
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::option_if_let_else
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::ptr_as_ptr
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::redundant_closure_for_method_calls
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::ref_as_ptr
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::return_self_not_must_use
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::significant_drop_tightening
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::similar_names
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::struct_excessive_bools
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::too_many_arguments
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::too_many_lines
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::tuple_array_conversions
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Wclippy::undocumented_unsafe_blocks
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::unreadable_literal
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::unsafe_derive_deserialize
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::verbose_bit_mask
build:clippy-strict --@rules_rust//rust/settings:clippy_flag=-Aclippy::wildcard_imports
+78
View File
@@ -0,0 +1,78 @@
"""Rules for producing release-grade, canonically named pi_natives addons.
`native_addon` transitions //crates/pi-natives:pi_natives onto a shipping
platform with the release codegen profile (opt, thin LTO, cgu=16, stripped —
mirrors the cargo `ci` profile) and renames the produced shared library to the
loader's canonical `pi_natives.<platform>-<arch>[-<variant>].node` filename.
Encoding the profile in the transition means `bazel build //:natives-<t>` is
always release-grade regardless of -c, and every addon shares one cache entry
per (platform, source) pair.
"""
_ADDON_RUSTC_FLAGS = [
"-Ccodegen-units=16",
"-Cstrip=symbols",
]
def _addon_transition_impl(settings, attr):
return {
"//command_line_option:platforms": str(attr.platform),
"//command_line_option:compilation_mode": "opt",
"@rules_rust//rust/settings:lto": "thin",
"@rules_rust//rust/settings:extra_rustc_flags": _ADDON_RUSTC_FLAGS,
}
_addon_transition = transition(
implementation = _addon_transition_impl,
inputs = [],
outputs = [
"//command_line_option:platforms",
"//command_line_option:compilation_mode",
"@rules_rust//rust/settings:lto",
"@rules_rust//rust/settings:extra_rustc_flags",
],
)
_SHARED_LIB_EXTENSIONS = ("so", "dylib", "dll")
def _native_addon_impl(ctx):
libs = [
f
for f in ctx.attr.lib[0][DefaultInfo].files.to_list()
if f.extension in _SHARED_LIB_EXTENSIONS
]
if len(libs) != 1:
fail("expected exactly one shared library from {}, got: {}".format(
ctx.attr.lib[0].label,
[f.short_path for f in libs],
))
# Scope under the rule name: gnu and musl addons share canonical filenames
# (the loader never sees both), so bare package-level outputs would collide.
out = ctx.actions.declare_file(ctx.label.name + "/" + ctx.attr.out)
ctx.actions.symlink(output = out, target_file = libs[0])
return [DefaultInfo(files = depset([out]))]
native_addon = rule(
implementation = _native_addon_impl,
doc = "Release build of the pi_natives cdylib for one shipping platform, " +
"renamed to the loader's canonical .node filename.",
attrs = {
"lib": attr.label(
cfg = _addon_transition,
mandatory = True,
doc = "The rust_shared_library target (//crates/pi-natives:pi_natives).",
),
"platform": attr.label(
mandatory = True,
doc = "//bazel/platforms platform to build for.",
),
"out": attr.string(
mandatory = True,
doc = "Canonical addon filename, e.g. pi_natives.linux-x64-baseline.node.",
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
)
+61
View File
@@ -0,0 +1,61 @@
# One platform per shipped pi_natives addon. linux platforms inherit the zig
# libc-aware platforms so cc toolchain resolution pins glibc 2.17 (the shipped
# portability floor) or musl; the cpu_variant constraint selects -Ctarget-cpu
# in //crates/pi-natives. darwin/win32 resolve against the host Xcode toolchain
# and //bazel/toolchains/msvc respectively.
package(default_visibility = ["//visibility:public"])
platform(
name = "linux-x64-baseline",
constraint_values = ["//bazel/variants:baseline"],
parents = ["@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.17"],
)
platform(
name = "linux-x64-modern",
constraint_values = ["//bazel/variants:modern"],
parents = ["@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.17"],
)
platform(
name = "linux-arm64",
parents = ["@zig_sdk//libc_aware/platform:linux_arm64_gnu.2.17"],
)
platform(
name = "linux-musl-x64-baseline",
constraint_values = ["//bazel/variants:baseline"],
parents = ["@zig_sdk//libc_aware/platform:linux_amd64_musl"],
)
platform(
name = "linux-musl-arm64",
parents = ["@zig_sdk//libc_aware/platform:linux_arm64_musl"],
)
platform(
name = "darwin-x64-baseline",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:x86_64",
"//bazel/variants:baseline",
],
)
platform(
name = "darwin-arm64",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:arm64",
],
)
platform(
name = "win32-x64-baseline",
constraint_values = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
"//bazel/variants:baseline",
],
)
+83
View File
@@ -0,0 +1,83 @@
# Repo-local toolchains, registered in MODULE.bazel BEFORE @rust_toolchains//:all.
#
# musl wrappers: rules_rust's generated gnu and musl rust toolchains share
# (os, cpu) constraints, so plain registration order would hand musl platforms
# the gnu std. These wrappers re-register the musl toolchains gated on
# @zig_sdk//libc:musl (carried by //bazel/platforms:linux-musl-*), and lose to
# nothing on gnu platforms because the constraint cannot match there.
#
# //bazel/toolchains/msvc: hermetic clang-cl + lld-link + xwin CRT/SDK
# cc toolchain for x86_64-pc-windows-msvc cross builds from linux.
package(default_visibility = ["//visibility:public"])
_MUSL_RUST_TOOLCHAINS = {
"linux-x64-to-musl-x64": (
["@platforms//os:linux", "@platforms//cpu:x86_64"],
["@platforms//os:linux", "@platforms//cpu:x86_64"],
"@rust_linux_x86_64__x86_64-unknown-linux-musl__nightly_tools//:rust_toolchain",
),
"linux-x64-to-musl-arm64": (
["@platforms//os:linux", "@platforms//cpu:x86_64"],
["@platforms//os:linux", "@platforms//cpu:aarch64"],
"@rust_linux_x86_64__aarch64-unknown-linux-musl__nightly_tools//:rust_toolchain",
),
"darwin-arm64-to-musl-x64": (
["@platforms//os:osx", "@platforms//cpu:aarch64"],
["@platforms//os:linux", "@platforms//cpu:x86_64"],
"@rust_macos_aarch64__x86_64-unknown-linux-musl__nightly_tools//:rust_toolchain",
),
"darwin-arm64-to-musl-arm64": (
["@platforms//os:osx", "@platforms//cpu:aarch64"],
["@platforms//os:linux", "@platforms//cpu:aarch64"],
"@rust_macos_aarch64__aarch64-unknown-linux-musl__nightly_tools//:rust_toolchain",
),
"linux-arm64-to-musl-arm64": (
["@platforms//os:linux", "@platforms//cpu:aarch64"],
["@platforms//os:linux", "@platforms//cpu:aarch64"],
"@rust_linux_aarch64__aarch64-unknown-linux-musl__nightly_tools//:rust_toolchain",
),
"linux-arm64-to-musl-x64": (
["@platforms//os:linux", "@platforms//cpu:aarch64"],
["@platforms//os:linux", "@platforms//cpu:x86_64"],
"@rust_linux_aarch64__x86_64-unknown-linux-musl__nightly_tools//:rust_toolchain",
),
}
[
toolchain(
name = "rust-musl-" + name,
exec_compatible_with = exec_cv,
target_compatible_with = target_cv + ["@zig_sdk//libc:musl"],
target_settings = ["@rules_rust//rust/toolchain/channel:nightly"],
toolchain = tools,
toolchain_type = "@rules_rust//rust:toolchain",
)
for name, (exec_cv, target_cv, tools) in _MUSL_RUST_TOOLCHAINS.items()
]
# msvc cross cc toolchain: @msvc_cc generates its wrappers for whichever host
# fetches it, so one toolchain() per supported exec host points at the same
# cc_toolchain — only the variant matching the local host can ever resolve.
# target_compatible_with pins these to windows/x86_64, so they can never
# shadow the zig cc toolchains on linux (or the host Xcode toolchain on mac).
_MSVC_EXEC_HOSTS = {
"linux-x64": ["@platforms//os:linux", "@platforms//cpu:x86_64"],
"linux-arm64": ["@platforms//os:linux", "@platforms//cpu:aarch64"],
"darwin-arm64": ["@platforms//os:osx", "@platforms//cpu:aarch64"],
"darwin-x64": ["@platforms//os:osx", "@platforms//cpu:x86_64"],
}
[
toolchain(
name = "msvc-cc-from-" + name,
exec_compatible_with = exec_cv,
target_compatible_with = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
toolchain = "@msvc_cc//:cc_toolchain",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
for name, exec_cv in _MSVC_EXEC_HOSTS.items()
]
+5
View File
@@ -0,0 +1,5 @@
# Hermetic clang-cl + lld-link + xwin (MSVC CRT/SDK) cross toolchain for
# x86_64-pc-windows-msvc, replacing cargo-xwin. The repository rules live in
# llvm.bzl / sysroot.bzl / cc.bzl (instantiated from MODULE.bazel); the
# toolchain() registrations live in //bazel/toolchains. See NOTES.md for the
# knobs and what still needs validation on can.internal.
+139
View File
@@ -0,0 +1,139 @@
# msvc cross toolchain — knobs & validation notes
Hermetic clang-cl + lld-link + xwin (MSVC CRT/SDK) cc toolchain for
`x86_64-pc-windows-msvc`, cross-linking from linux-x64 (CI) and darwin (dev)
exec hosts. Replaces cargo-xwin.
## Layout
| Piece | Where | Why separate |
| --- | --- | --- |
| `@llvm_msvc_tools` | `llvm.bzl` | LLVM 20.1.7 release archive for the fetching host, pruned to clang-cl/lld-link/llvm-lib/llvm-rc/llvm-mt + `lib/clang/*/include`. Downloads (~2 GiB) are sha256-pinned → Bazel repository cache. |
| `@xwin_sysroot` | `sysroot.bzl` | xwin 0.6.5 (pinned per-host sha256) runs `splat` in the repo rule. The ~1 GiB CRT/SDK payload comes from the Microsoft CDN via xwin itself and is **not** in Bazel's repo cache — a cold output base re-downloads it. Keep `sysroot.bzl` stable. |
| `@msvc_cc` | `cc.bzl` | Wrapper scripts + `cc_toolchain` + MSVC feature config (copied from the resolved rules_cc, like `@local_config_cc`). Cheap to regenerate — iterate flags here. |
| `toolchain()`s | `//bazel/toolchains` (`msvc-cc-from-*`) | One per exec host (linux-x64/arm64, darwin-arm64/x64), all pointing at `@msvc_cc//:cc_toolchain`; only the local host's variant can resolve. `target_compatible_with = [windows, x86_64]` ⇒ can never shadow zig on linux. |
| MODULE.bazel | `# --- msvc cross toolchain ---` section | `rules_cc` 0.2.17 (= Bazel 9.2's builtin pin) + the three `use_repo_rule` instantiations. Plus one target-suffixed env key inside the existing `audiopus_sys` annotation (see below). |
## Design decisions
- **No toolchains_llvm**: it wants to register full host cc toolchains, which
risks shadowing the zig linux toolchains. Direct LLVM release fetch instead.
- **Wrappers self-locate from `$0`** (execroot-relative sibling repos), so they
work from Bazel actions (cwd = execroot) *and* from build scripts, where
rules_rust `${pwd}`-expands `CC`/`AR` to absolute paths and cc-rs/cmake spawn
tools from other cwds.
- **CRT: dynamic `/MD`** (rules_cc's msvc branch default outside `dbg` without
the `static_link_msvcrt` feature) — matches what napi/cc-rs produced under
cargo-xwin (rust msvc targets default to dynamic CRT without `+crt-static`).
- **SSE floor in the wrapper, not annotations**: `-msse4.1 -msse4.2` live in the
clang-cl wrapper, which only ever targets win32-x64 (baseline = x86-64-v2 ⊇
SSE4.2). This is the old build-native.ts CFLAGS hack, windows-only by
construction.
- **cmake generator via target-suffixed env**: `crate_universe` cannot select()
annotations per platform, and a second `crate.annotation` for the same crate
hard-fails the extension (`_insert_annotation` dupe check; `annotation_select`
is unused/broken in rules_rust 0.71.3). Instead the existing `audiopus_sys`
annotation carries `CMAKE_GENERATOR_x86_64_pc_windows_msvc=Ninja` — cmake-rs
reads `VAR_<triple>` before `VAR`, so the key is inert for all other targets.
cmake-rs sets `CMAKE_SYSTEM_NAME=Windows` itself when target ≠ host.
- **cmake tool discovery**: wrappers are named bare `clang-cl`, `lld-link`,
`llvm-lib`, `llvm-rc`, `llvm-mt` (no `.sh`) because CMake's
`CMakeFindBinUtils`/`find_program` probes for those names next to
`CMAKE_C_COMPILER`, and cc-rs sniffs the MSVC/clang-cl tool family from the
basename. The clang-cl wrapper also exports link.exe-style `LIB` and passes
`-fuse-ld=lld-link` so compiler-driver links (cmake `try_compile` ABI checks)
resolve CRT import libs without a toolchain file.
- **ring 0.17.14 needs no perl/nasm**: verified in its build.rs — crates.io
tarballs use `pregenerated/*-nasm.o` objects directly for windows-msvc
(`use_nasm()` path only shells out during the maintainer packaging step).
The .o files flow through `cc::Build.object()` into llvm-lib.
## Reproducibility / cache implications
- First fetch per host: ~2 GiB LLVM (repo-cache backed) + ~15 MiB xwin +
~1 GiB MS CDN splat (not repo-cache backed). Splat repo ends up ~800 MiB.
- `--manifest-version 17` pins the VS2022 channel, but Microsoft advances the
channel payload over time → splat is stable day-to-day, not bit-reproducible
forever (same property cargo-xwin had). Action keys only depend on the files
actually read, so remote-cache hit rates degrade gracefully after an MS bump.
- Toolchain binaries differ per exec host (linux vs mac clang) → win32 link
actions do not share remote-cache entries across host OSes. CI is
linux-x64-only for this target, so this only affects dev machines.
## Already verified (darwin-arm64 dev host, 2026-07-27)
- `bazel build --nobuild //:natives-win32-x64-baseline` analyzes clean;
`cquery deps(...)` confirms `@msvc_cc//:cc_toolchain` (not the host Xcode
toolchain) resolved for the windows target. Full fetch + splat took ~2.5 min
on a fast link. Repin (`bun run bazel:repin`) already run for the
`CMAKE_GENERATOR_x86_64_pc_windows_msvc` annotation key.
- Wrapper smoke test outside Bazel: `clang-cl /MD` compiled a windows.h +
smmintrin.h SSE4.1 program and driver-linked it via `-fuse-ld=lld-link` +
`LIB` into a valid PE32+ exe; the standalone `lld-link` wrapper (rustc's
`-Clinker` path) and `llvm-lib` also produced a PE exe / ar archive.
- xwin's `10.0.26100 -> .` self-referential version symlinks broke Bazel's
glob ("too many levels of symbolic links"); `sysroot.bzl` now prunes any
readdir entry whose realpath equals its parent, post-splat.
- blake3 MASM (`ml64.exe` from cc-rs on non-windows hosts): `bin/ml64.exe` /
`bin/ml64` shims exec `llvm-ml -m64`. All four blake3 1.8.5
`blake3_*_x86-64_windows_msvc.asm` files assemble to valid amd64 COFF
objects through the shim (invoked cc-rs-style via PATH with joined `/Fo`).
cc-rs finds the shim through the blake3 crate.annotation, which prepends
`$${pwd}/external/+msvc_cc_repository+msvc_cc/bin` to the build-script PATH
(`$$` because annotation env runs through Bazel make-var expansion; the
rules_rust runner then substitutes `${pwd}` → exec root). The wrapper dir
reaches the sandbox via the cc toolchain's `all_files`. NOTE: the PATH entry
hardcodes @msvc_cc's canonical repo name — keep in sync if the repo rule or
repo name changes. Repin for this annotation already run.
- audiopus_sys/opus cmake exe links (can.internal finding #2): cmake's
`vs_link_exe` demands rc/mt tools that `find_program` can't locate on a
linux/mac PATH. @msvc_cc now generates `toolchain.cmake` (self-locating via
`CMAKE_CURRENT_LIST_DIR`: compiler/linker/rc/mt = the wrappers) handed to
cmake-rs through `CMAKE_TOOLCHAIN_FILE_x86_64_pc_windows_msvc` in the
audiopus_sys annotation (same `$${pwd}` + canonical-repo-path mechanism as
the blake3 shim). Second failure mode fixed in the same file: `try_compile`
defaults to the Debug config → `/MDd` → `msvcrtd.lib`, which the lean splat
(like cargo-xwin's) does not carry; toolchain.cmake pins
`CMAKE_TRY_COMPILE_CONFIGURATION=Release`, `CMAKE_POLICY_DEFAULT_CMP0091=NEW`
and `CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL` (/MD everywhere).
Verified on darwin: scratch `project(C)` + `add_executable` configures with
"Clang 20.1.7 with MSVC-like command-line" and links a valid PE32+ exe
through vs_link_exe with the wrapper rc/mt/linker. Repin already run.
## What to verify on can.internal (linux-x64)
1. `bazel build //:natives-win32-x64-baseline` end-to-end link; check the
produced `pi_natives.win32-x64-baseline.node` imports (dumpbin/llvm-readobj:
expect VCRUNTIME140/api-ms-win-crt-* → `/MD`, no static CRT).
2. LLVM 20.1.7 Linux-X64 binaries are built on a newish Ubuntu: confirm the
kata runner image's glibc is ≥ 2.35-ish and has `libtinfo6`/`libstdc++6`
(usual LLVM release-binary runtime deps).
3. `ninja` + `cmake` must be on the audiopus_sys build-script PATH
(`/usr/local/bin:/usr/bin:/bin`) on the kata image — same requirement the
old ensure-cmake action satisfied for cargo-xwin.
4. audiopus_sys configure: cmake should report
"Clang with MSVC-like command-line", take `toolchain.cmake` (log shows the
vs_link_exe --rc/--mt pointing into the wrapper dir), and produce opus.lib
with /MD objects. If mt is ever asked to actually merge manifests, note
the official LLVM llvm-mt lacks libxml2 and would error — not hit today.
5. tree-sitter grammar compiles via cc-rs: wrapper is picked up as `CC`
(family detection needs the basename to contain `clang-cl` — it does).
6. ring: no `nasm`/`perl` spawns in the build-script log; archive step uses
the `llvm-lib` wrapper.
7. blake3: build-script log should show `ml64.exe` resolving to the shim (no
"failed to find tool" error); spot-check the assembled objects land in the
rlib.
8. Repo fetch time/disk on the pods (first fetch ~3 GiB, ~25 min worst case);
consider pre-warming the bazel output base or a persistent
`--repository_cache` volume if it hurts.
## Knobs
- LLVM version/sha256s: `llvm.bzl` (`_LLVM_VERSION`, `_LLVM_DISTS`). 20.1.7 is
the newest release with archives for all four host tuples.
- xwin version + manifest channel: `sysroot.bzl` (`_XWIN_VERSION` 0.6.5 — last
release with darwin binaries; `_XWIN_MANIFEST_VERSION` "17").
- Compile/link flags, include/libpath set, CRT choice: wrapper templates and
`cc_toolchain_config` attrs in `cc.bzl`.
- Static CRT if ever needed: build with the standard `static_link_msvcrt`
feature (`--features=static_link_msvcrt`) instead of editing flags.
+279
View File
@@ -0,0 +1,279 @@
"""Repository rule generating the hermetic clang-cl + xwin MSVC cc toolchain.
The @msvc_cc repo holds only cheap generated files — wrapper shell scripts and
the cc_toolchain/cc_toolchain_config BUILD — so iterating on flags here never
invalidates the big @llvm_msvc_tools / @xwin_sysroot downloads (their rules
live in llvm.bzl / sysroot.bzl on purpose).
Wrappers derive every path from $0 (execroot-relative sibling repos), so they
work from Bazel actions (cwd = execroot) and from build scripts, where
rules_rust ${pwd}-expands CC/AR to absolute paths and cc-rs/cmake spawn the
tools from other working directories:
bin/clang-cl --target=x86_64-pc-windows-msvc, /imsvc CRT+SDK includes,
-msse4.1 -msse4.2 (win32-x64 baseline floor; clang-cl
enforces per-function target features, real MSVC does not),
-fuse-ld=lld-link + exported link.exe-style LIB so driver
links (cmake try_compile) resolve the CRT import libs.
bin/lld-link /libpath for CRT + SDK libs, then pass-through; rustc uses
it via -Clinker for the msvc linker flavor.
bin/llvm-lib archiver (lib.exe replacement, cc-rs AR + cmake CMAKE_AR).
bin/llvm-rc resource compiler (cmake finds it next to the compiler).
bin/llvm-mt manifest tool (cmake CMAKE_MT probe).
bin/ml64.exe MASM shim → llvm-ml -m64 (also bare `ml64`): cc-rs looks
bin/ml64 up `ml64.exe` on PATH for x64 msvc .asm (blake3); the
blake3 crate.annotation prepends this dir to PATH.
The MSVC-flavored feature/action config (dynamic CRT /MD by default — matching
what napi/cc-rs produced under cargo-xwin; /MT only via the standard
static_link_msvcrt feature) comes from rules_cc's own
windows_cc_toolchain_config.bzl, copied into the repo exactly like
@local_config_cc does, so it always matches the resolved rules_cc version.
"""
_CLANG_CL_WRAPPER = """\
#!/bin/sh
# Generated by //bazel/toolchains/msvc:cc.bzl. clang-cl driver for
# x86_64-pc-windows-msvc against the @xwin_sysroot MSVC CRT + Windows SDK.
set -eu
execroot="$(cd "$(dirname "$0")/../../.." && pwd)"
llvm="$execroot/external/{llvm}"
splat="$execroot/external/{xwin}/splat"
# lld-link (spawned through -fuse-ld for compiler-driver links, e.g. cmake
# try_compile) resolves CRT/SDK import libs via the link.exe-style LIB env.
LIB="$splat/crt/lib/x86_64;$splat/sdk/lib/um/x86_64;$splat/sdk/lib/ucrt/x86_64"
export LIB
# -msse4.1/-msse4.2: clang-cl enforces per-function target features (real MSVC
# does not); opus' silk/x86 SSE4.1 units fail without the feature enabled
# globally. The win32-x64 addon floor is x86-64-v2 (SSE4.2 inclusive), so this
# is safe for every C dep — same flags the cargo-xwin pipeline exported.
exec "$llvm/bin/clang-cl" \\
--target=x86_64-pc-windows-msvc \\
-fuse-ld=lld-link \\
-msse4.1 \\
-msse4.2 \\
-Wno-unused-command-line-argument \\
"/imsvc$splat/crt/include" \\
"/imsvc$splat/sdk/include/ucrt" \\
"/imsvc$splat/sdk/include/um" \\
"/imsvc$splat/sdk/include/shared" \\
"/imsvc$splat/sdk/include/winrt" \\
"/imsvc$splat/sdk/include/cppwinrt" \\
"$@"
"""
_LLD_LINK_WRAPPER = """\
#!/bin/sh
# Generated by //bazel/toolchains/msvc:cc.bzl. lld-link with the @xwin_sysroot
# CRT + SDK libpaths; rustc invokes it via -Clinker (msvc linker flavor).
set -eu
execroot="$(cd "$(dirname "$0")/../../.." && pwd)"
llvm="$execroot/external/{llvm}"
splat="$execroot/external/{xwin}/splat"
# rustc addresses lld in generic multi-flavor style ("-flavor link" first);
# the single-flavor lld-link binary would treat "link" as an input file.
if [ "${{1:-}}" = "-flavor" ]; then shift 2; fi
exec "$llvm/bin/lld-link" \\
"/libpath:$splat/crt/lib/x86_64" \\
"/libpath:$splat/sdk/lib/um/x86_64" \\
"/libpath:$splat/sdk/lib/ucrt/x86_64" \\
"$@"
"""
_PASSTHROUGH_WRAPPER = """\
#!/bin/sh
# Generated by //bazel/toolchains/msvc:cc.bzl.
set -eu
execroot="$(cd "$(dirname "$0")/../../.." && pwd)"
exec "$execroot/external/{llvm}/bin/{tool}" "$@"
"""
_ML64_WRAPPER = """\
#!/bin/sh
# Generated by //bazel/toolchains/msvc:cc.bzl. MASM shim: cc-rs assembles .asm
# for x64 msvc targets (blake3's blake3_*_x86-64_windows_msvc.asm) by invoking
# `ml64.exe` from PATH on non-windows hosts; llvm-ml is a MASM-compatible
# replacement — same shim cargo-xwin installed. The blake3 crate.annotation in
# MODULE.bazel prepends this bin/ dir to the build script PATH.
set -eu
execroot="$(cd "$(dirname "$0")/../../.." && pwd)"
exec "$execroot/external/{llvm}/bin/llvm-ml" -m64 "$@"
"""
_NOP_WRAPPER = """\
#!/bin/sh
# Generated by //bazel/toolchains/msvc:cc.bzl. Placeholder for tools the MSVC
# toolchain does not have (gcov/nm/objcopy/objdump/strip).
exit 0
"""
# CMake toolchain file for the `cmake` crate (audiopus_sys' bundled opus).
# cmake's vs_link_exe helper insists on rc/mt tools for MSVC-ABI exe links
# (try_compile links a test exe), and CMake's own find_program would only look
# for `rc`/`mt` on PATH. CMAKE_CURRENT_LIST_DIR makes the file self-locating —
# no canonical repo names involved. Handed to build scripts via the
# CMAKE_TOOLCHAIN_FILE_x86_64_pc_windows_msvc annotation env in MODULE.bazel.
_TOOLCHAIN_CMAKE = """\
# Generated by //bazel/toolchains/msvc:cc.bzl — clang-cl + lld-link + xwin
# CRT/SDK cross toolchain for x86_64-pc-windows-msvc (mirrors the toolchain
# file cargo-xwin used to generate).
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR AMD64)
set(CMAKE_C_COMPILER "${CMAKE_CURRENT_LIST_DIR}/bin/clang-cl")
set(CMAKE_CXX_COMPILER "${CMAKE_CURRENT_LIST_DIR}/bin/clang-cl")
set(CMAKE_LINKER "${CMAKE_CURRENT_LIST_DIR}/bin/lld-link")
set(CMAKE_RC_COMPILER "${CMAKE_CURRENT_LIST_DIR}/bin/llvm-rc")
set(CMAKE_MT "${CMAKE_CURRENT_LIST_DIR}/bin/llvm-mt")
# The xwin splat carries release CRT import libs only (msvcrt.lib, no
# msvcrtd.lib — same as cargo-xwin). try_compile defaults to the Debug
# configuration, whose /MDd would demand the debug CRT; pin try_compile to
# Release and the runtime library to dynamic release /MD for every config
# (CMP0091 NEW makes CMAKE_MSVC_RUNTIME_LIBRARY authoritative even for
# projects with ancient cmake_minimum_required, e.g. bundled opus).
set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
set(CMAKE_POLICY_DEFAULT_CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
"""
_BUILD = """\
# Generated by //bazel/toolchains/msvc:cc.bzl — hermetic clang-cl + lld-link +
# xwin CRT/SDK cc toolchain for x86_64-pc-windows-msvc. The toolchain() targets
# registering this live in //bazel/toolchains (one per supported exec host).
load("@rules_cc//cc/toolchains:cc_toolchain.bzl", "cc_toolchain")
load(":windows_cc_toolchain_config.bzl", "cc_toolchain_config")
package(default_visibility = ["//visibility:public"])
filegroup(name = "empty")
filegroup(
name = "wrappers",
srcs = glob(["bin/*"]) + ["toolchain.cmake"],
)
filegroup(
name = "all_files",
srcs = [
":wrappers",
"@llvm_msvc_tools//:all",
"@xwin_sysroot//:sysroot",
],
)
cc_toolchain_config(
name = "clang_cl_xwin_config",
abi_libc_version = "local",
abi_version = "local",
archiver_flags = ["/MACHINE:X64"],
compiler = "clang-cl",
cpu = "x64_windows",
dbg_mode_debug_flag = "/DEBUG",
default_link_flags = ["/MACHINE:X64"],
fastbuild_mode_debug_flag = "/DEBUG",
host_system_name = "local",
msvc_cl_path = "bin/clang-cl",
msvc_env_include = "{env_include}",
msvc_env_lib = "{env_lib}",
msvc_env_path = "/usr/bin:/bin",
msvc_env_tmp = "/tmp",
msvc_lib_path = "bin/llvm-lib",
msvc_link_path = "bin/lld-link",
msvc_ml_path = "bin/ml64.exe",
supports_parse_showincludes = False,
target_libc = "msvcrt",
target_system_name = "x86_64-pc-windows-msvc",
tool_paths = {{
"ar": "bin/llvm-lib",
"cpp": "bin/clang-cl",
"gcc": "bin/clang-cl",
"gcov": "bin/msvc-nop",
"ld": "bin/lld-link",
"ml": "bin/ml64.exe",
"nm": "bin/msvc-nop",
"objcopy": "bin/msvc-nop",
"objdump": "bin/msvc-nop",
"strip": "bin/msvc-nop",
}},
toolchain_identifier = "clang_cl_xwin_x64",
)
cc_toolchain(
name = "cc_toolchain",
all_files = ":all_files",
ar_files = ":all_files",
as_files = ":all_files",
compiler_files = ":all_files",
dwp_files = ":empty",
linker_files = ":all_files",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 1,
toolchain_config = ":clang_cl_xwin_config",
toolchain_identifier = "clang_cl_xwin_x64",
)
"""
def _msvc_cc_impl(rctx):
llvm = rctx.attr.llvm_repo.repo_name
xwin = rctx.attr.xwin_repo.repo_name
splat = "external/{}/splat".format(xwin)
rctx.file("bin/clang-cl", _CLANG_CL_WRAPPER.format(llvm = llvm, xwin = xwin), executable = True)
rctx.file("bin/lld-link", _LLD_LINK_WRAPPER.format(llvm = llvm, xwin = xwin), executable = True)
for tool in ("llvm-lib", "llvm-rc", "llvm-mt"):
rctx.file("bin/" + tool, _PASSTHROUGH_WRAPPER.format(llvm = llvm, tool = tool), executable = True)
rctx.file("bin/msvc-nop", _NOP_WRAPPER, executable = True)
# cc-rs resolves the x64 MASM assembler as `ml64.exe` from PATH on
# non-windows hosts (blake3); ship both spellings of the shim.
for name in ("ml64.exe", "ml64"):
rctx.file("bin/" + name, _ML64_WRAPPER.format(llvm = llvm), executable = True)
# The MSVC feature/action-config machinery, verbatim from the resolved
# rules_cc (same mechanism @local_config_cc uses on real Windows hosts).
rctx.template("windows_cc_toolchain_config.bzl", rctx.attr._config_bzl, executable = False)
# CMake toolchain file for the cmake crate (no placeholders — it
# self-locates via CMAKE_CURRENT_LIST_DIR, so no .format here).
rctx.file("toolchain.cmake", _TOOLCHAIN_CMAKE, executable = False)
# INCLUDE/LIB for raw cc_* compile/link actions (cwd = execroot, so the
# execroot-relative entries resolve). The rust graph routes everything
# through the wrappers, which pass /imsvc and /libpath themselves.
env_include = ";".join([
splat + "/crt/include",
splat + "/sdk/include/ucrt",
splat + "/sdk/include/um",
splat + "/sdk/include/shared",
splat + "/sdk/include/winrt",
splat + "/sdk/include/cppwinrt",
])
env_lib = ";".join([
splat + "/crt/lib/x86_64",
splat + "/sdk/lib/um/x86_64",
splat + "/sdk/lib/ucrt/x86_64",
])
rctx.file(
"BUILD.bazel",
_BUILD.format(env_include = env_include, env_lib = env_lib),
executable = False,
)
msvc_cc_repository = repository_rule(
implementation = _msvc_cc_impl,
doc = "clang-cl/lld-link wrapper scripts + MSVC-flavored cc_toolchain for x86_64-pc-windows-msvc.",
attrs = {
"llvm_repo": attr.label(
default = "@llvm_msvc_tools//:BUILD.bazel",
doc = "Anchor into the pruned LLVM tools repo (canonical name source; not fetched here).",
),
"xwin_repo": attr.label(
default = "@xwin_sysroot//:BUILD.bazel",
doc = "Anchor into the xwin CRT/SDK sysroot repo (canonical name source; not fetched here).",
),
"_config_bzl": attr.label(
default = "@rules_cc//cc/private/toolchain:windows_cc_toolchain_config.bzl",
doc = "rules_cc's Windows cc_toolchain_config implementation, copied into this repo.",
),
},
)
+126
View File
@@ -0,0 +1,126 @@
"""Repository rule fetching the LLVM binaries used by the msvc cross toolchain.
Downloads the official LLVM release archive for the host that fetches the repo
(linux-x64 CI pods, darwin dev hosts) and prunes it down to the clang-cl /
lld-link / llvm-lib / llvm-rc slice plus the clang builtin headers
(lib/clang/<major>/include — immintrin.h & co, required for the SSE units in
bundled opus). The pruned tree is ~300 MiB instead of ~10 GiB.
The archive download (~1.5-2 GiB) goes through repository_ctx.download_and_extract
with a pinned sha256, so it lands in Bazel's content-addressed repository cache:
re-fetches after `bazel clean --expunge` or a .bzl edit only pay extraction.
Checksums are the official llvm-project release assets, cross-checked against
bazel-contrib/toolchains_llvm's distribution table.
"""
_LLVM_VERSION = "20.1.7"
# host key -> (release asset suffix, sha256)
_LLVM_DISTS = {
"linux-arm64": ("Linux-ARM64", "832f2802a29457dc758f56e26e98558c6cd0e45fcd07186f540cb6e7f4e59385"),
"linux-x64": ("Linux-X64", "8494c98a774051a40bfe1187a2d6442f4bc107598998bbe1673d9bb1572cfd6f"),
"macos-arm64": ("macOS-ARM64", "6aa75de00575ad0663183b00f00f39992ded611b5136e57649ace1e6a53c0d16"),
"macos-x64": ("macOS-X64", "ccf82ffe7e136ee49659cb57157856a7963d0950fac3d05aabba0db75bfba26f"),
}
# bin/ entries to keep. Symlink chains (clang-cl -> clang -> clang-20,
# llvm-lib -> llvm-ar, lld-link -> lld) are closed over at fetch time by
# resolving realpaths, so version-suffixed real binaries need no hardcoding.
_KEEP_BINS = [
"clang",
"clang-cl",
"lld",
"lld-link",
"llvm-ar",
"llvm-lib",
"llvm-ml",
"llvm-mt",
"llvm-rc",
]
def _host_key(rctx):
os_name = rctx.os.name.lower()
arch = rctx.os.arch.lower()
if os_name.startswith("linux"):
host_os = "linux"
elif os_name.startswith("mac") or os_name.startswith("darwin"):
host_os = "macos"
else:
fail("bazel/toolchains/msvc: unsupported exec host OS for the msvc cross toolchain: " + rctx.os.name)
if arch in ("amd64", "x86_64", "x64"):
host_cpu = "x64"
elif arch in ("aarch64", "arm64"):
host_cpu = "arm64"
else:
fail("bazel/toolchains/msvc: unsupported exec host CPU for the msvc cross toolchain: " + rctx.os.arch)
return host_os + "-" + host_cpu
_BUILD = """\
# Generated by //bazel/toolchains/msvc:llvm.bzl — pruned LLVM {version} for the
# msvc cross toolchain ({host} exec host). Consumed by @msvc_cc wrappers.
package(default_visibility = ["//visibility:public"])
filegroup(
name = "bin",
srcs = glob(["bin/*"]),
)
filegroup(
name = "builtin_headers",
srcs = glob(["lib/clang/*/include/**"]),
)
filegroup(
name = "all",
srcs = [
":bin",
":builtin_headers",
],
)
"""
def _llvm_msvc_tools_impl(rctx):
key = _host_key(rctx)
if key not in _LLVM_DISTS:
fail("bazel/toolchains/msvc: no pinned LLVM release archive for host " + key)
suffix, sha256 = _LLVM_DISTS[key]
prefix = "LLVM-{}-{}".format(_LLVM_VERSION, suffix)
rctx.report_progress("Downloading LLVM {} ({}, ~2 GiB, repository-cache backed)".format(_LLVM_VERSION, suffix))
rctx.download_and_extract(
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-{}/{}.tar.xz".format(_LLVM_VERSION, prefix),
sha256 = sha256,
stripPrefix = prefix,
)
# Close the keep-set over symlink targets, then prune bin/.
keep = {name: None for name in _KEEP_BINS}
bin_dir = rctx.path("bin")
for name in _KEEP_BINS:
tool = bin_dir.get_child(name)
if tool.exists:
keep[tool.realpath.basename] = None
for entry in bin_dir.readdir():
if entry.basename not in keep:
rctx.delete(entry)
# Prune everything outside bin/ and lib/clang/<ver>/include.
for entry in rctx.path(".").readdir():
if entry.basename not in ("bin", "lib"):
rctx.delete(entry)
lib_dir = rctx.path("lib")
for entry in lib_dir.readdir():
if entry.basename != "clang":
rctx.delete(entry)
for verdir in lib_dir.get_child("clang").readdir():
for entry in verdir.readdir():
if entry.basename != "include":
rctx.delete(entry)
rctx.file("BUILD.bazel", _BUILD.format(version = _LLVM_VERSION, host = key), executable = False)
llvm_msvc_tools_repository = repository_rule(
implementation = _llvm_msvc_tools_impl,
doc = "Pruned LLVM release binaries (clang-cl/lld-link/llvm-lib/llvm-rc) for the exec host.",
)
+156
View File
@@ -0,0 +1,156 @@
"""Repository rule materializing the MSVC CRT + Windows SDK sysroot via xwin.
Downloads a pinned xwin release binary (github.com/Jake-Shadle/xwin) for the
host that fetches the repo and runs `xwin --accept-license splat`, producing:
splat/crt/include VC toolset headers
splat/crt/lib/x86_64 VC toolset libs (msvcrt.lib & co)
splat/sdk/include/{ucrt,um,shared,winrt,cppwinrt}
splat/sdk/lib/{ucrt,um}/x86_64
Cache implications: only the small xwin binary tarball goes through Bazel's
repository cache. The CRT/SDK payload (~1 GiB) is downloaded from the
Microsoft CDN by xwin itself inside this rule, so a cold fetch (clean
--expunge, sysroot.bzl edit, new output base) re-downloads it. The xwin
download cache is deleted after splatting to keep the repo at ~800 MiB.
Keep this file stable; wrapper/toolchain iteration lives in cc.bzl precisely
so it never invalidates this repo.
Reproducibility: --manifest-version pins the VS channel (17 = VS2022), but
Microsoft advances the channel's payload over time, so the splat is stable
day-to-day, not bit-reproducible forever — same property the cargo-xwin
pipeline had.
xwin release binaries stop shipping darwin builds after 0.6.5; 0.6.5 is the
newest version covering linux-musl + darwin hosts, which is why it is pinned.
"""
_XWIN_VERSION = "0.6.5"
_XWIN_MANIFEST_VERSION = "17"
# host key -> (release triple, sha256), from the published .sha256 assets.
_XWIN_DISTS = {
"linux-arm64": ("aarch64-unknown-linux-musl", "5e131007fad7c5f30d2f41090b49937fb8f16a787e5a95b4b3140e88d174dab2"),
"linux-x64": ("x86_64-unknown-linux-musl", "9fd53950b064d067f42428a69453b927656cae68dbd7f8d3f86dcb81c80dd22d"),
"macos-arm64": ("aarch64-apple-darwin", "21acd1e35d23b72efc8c47cbeda5028989f98089174b8c87074f892b65adbc01"),
"macos-x64": ("x86_64-apple-darwin", "ecb2b19b30fa3786749fae600ad60b034b0c1c6a604ecf9f35f682c23a40e54b"),
}
def _host_key(rctx):
os_name = rctx.os.name.lower()
arch = rctx.os.arch.lower()
if os_name.startswith("linux"):
host_os = "linux"
elif os_name.startswith("mac") or os_name.startswith("darwin"):
host_os = "macos"
else:
fail("bazel/toolchains/msvc: unsupported exec host OS for xwin: " + rctx.os.name)
if arch in ("amd64", "x86_64", "x64"):
host_cpu = "x64"
elif arch in ("aarch64", "arm64"):
host_cpu = "arm64"
else:
fail("bazel/toolchains/msvc: unsupported exec host CPU for xwin: " + rctx.os.arch)
return host_os + "-" + host_cpu
_BUILD = """\
# Generated by //bazel/toolchains/msvc:sysroot.bzl — MSVC CRT + Windows SDK
# splatted by xwin {version} (manifest-version {manifest}). Consumed by the
# @msvc_cc wrappers via /imsvc and /libpath.
package(default_visibility = ["//visibility:public"])
filegroup(
name = "crt_includes",
srcs = glob(["splat/crt/include/**"]),
)
filegroup(
name = "crt_libs",
srcs = glob(["splat/crt/lib/**"]),
)
filegroup(
name = "sdk_includes",
srcs = glob(["splat/sdk/include/**"]),
)
filegroup(
name = "sdk_libs",
srcs = glob(["splat/sdk/lib/**"]),
)
filegroup(
name = "sysroot",
srcs = [
":crt_includes",
":crt_libs",
":sdk_includes",
":sdk_libs",
],
)
"""
def _xwin_sysroot_impl(rctx):
key = _host_key(rctx)
if key not in _XWIN_DISTS:
fail("bazel/toolchains/msvc: no pinned xwin release binary for host " + key)
triple, sha256 = _XWIN_DISTS[key]
prefix = "xwin-{}-{}".format(_XWIN_VERSION, triple)
rctx.download_and_extract(
url = "https://github.com/Jake-Shadle/xwin/releases/download/{}/{}.tar.gz".format(_XWIN_VERSION, prefix),
sha256 = sha256,
stripPrefix = prefix,
)
rctx.report_progress("Splatting MSVC CRT + Windows SDK via xwin (first fetch ~1 GiB from the Microsoft CDN)")
result = rctx.execute(
[
rctx.path("xwin"),
"--accept-license",
"--arch",
"x86_64",
"--variant",
"desktop",
"--manifest-version",
_XWIN_MANIFEST_VERSION,
"--cache-dir",
".xwin-cache",
"splat",
"--copy",
"--output",
"splat",
],
timeout = 3600,
)
if result.return_code != 0:
fail("bazel/toolchains/msvc: xwin splat failed (exit {}):\n{}\n{}".format(
result.return_code,
result.stdout,
result.stderr,
))
# Drop the download cache (the splat is a --copy, not links into it).
rctx.delete(".xwin-cache")
# xwin drops `<sdk-version> -> .` alias symlinks (e.g. sdk/lib/10.0.26100)
# so version-qualified include/lib paths resolve. They are self-referential
# directory cycles, which Bazel's glob refuses to traverse — and nothing in
# this toolchain uses version-qualified paths, so drop them.
for dirname in ("splat/sdk/include", "splat/sdk/lib", "splat/crt/lib", "splat/crt/include"):
dirpath = rctx.path(dirname)
if not dirpath.exists:
continue
for entry in dirpath.readdir():
if entry.realpath == dirpath.realpath:
rctx.delete(entry)
rctx.file(
"BUILD.bazel",
_BUILD.format(version = _XWIN_VERSION, manifest = _XWIN_MANIFEST_VERSION),
executable = False,
)
xwin_sysroot_repository = repository_rule(
implementation = _xwin_sysroot_impl,
doc = "MSVC CRT + Windows SDK sysroot splatted by a pinned xwin release.",
)
+99
View File
@@ -0,0 +1,99 @@
# Rust target-triple config_settings for crate_universe's rendered selects
# (MODULE.bazel sets platforms_template = "@@//bazel/triples:{triple}").
#
# rules_rust's builtin @rules_rust//rust/platform settings can't express musl:
# gnu and musl triples share (os, cpu), so the libc axis rides on
# @zig_sdk//libc. The gnu settings match both the zig gnu.2.17 platforms and
# libc-unconstrained platforms (host builds, GH runners); musl requires the
# explicit constraint carried by //bazel/platforms:linux-musl-*.
load("@bazel_skylib//lib:selects.bzl", "selects")
package(default_visibility = ["//visibility:public"])
_LINUX_CPUS = {
"x86_64": "x86_64",
"aarch64": "aarch64",
}
[
config_setting(
name = "_linux-{}-libc-default".format(cpu),
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:" + cv,
"@zig_sdk//libc:unconstrained",
],
)
for cpu, cv in _LINUX_CPUS.items()
]
[
config_setting(
name = "_linux-{}-libc-gnu217".format(cpu),
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:" + cv,
"@zig_sdk//libc:gnu.2.17",
],
)
for cpu, cv in _LINUX_CPUS.items()
]
selects.config_setting_group(
name = "x86_64-unknown-linux-gnu",
match_any = [
":_linux-x86_64-libc-default",
":_linux-x86_64-libc-gnu217",
],
)
selects.config_setting_group(
name = "aarch64-unknown-linux-gnu",
match_any = [
":_linux-aarch64-libc-default",
":_linux-aarch64-libc-gnu217",
],
)
config_setting(
name = "x86_64-unknown-linux-musl",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
"@zig_sdk//libc:musl",
],
)
config_setting(
name = "aarch64-unknown-linux-musl",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:aarch64",
"@zig_sdk//libc:musl",
],
)
config_setting(
name = "x86_64-apple-darwin",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:x86_64",
],
)
config_setting(
name = "aarch64-apple-darwin",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:arm64",
],
)
config_setting(
name = "x86_64-pc-windows-msvc",
constraint_values = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
)
+26
View File
@@ -0,0 +1,26 @@
# x64 ISA variant axis for shipped addons: `baseline` (x86-64-v2) runs on any
# 2010+ CPU, `modern` (x86-64-v3) needs AVX2. Non-x64 targets use `default`.
# The constraint rides on //bazel/platforms:* and drives -Ctarget-cpu selects
# in //crates/pi-natives.
package(default_visibility = ["//visibility:public"])
constraint_setting(
name = "cpu_variant",
default_constraint_value = ":default",
)
constraint_value(
name = "default",
constraint_setting = ":cpu_variant",
)
constraint_value(
name = "baseline",
constraint_setting = ":cpu_variant",
)
constraint_value(
name = "modern",
constraint_setting = ":cpu_variant",
)
+26
View File
@@ -0,0 +1,26 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
# Owns every tree-sitter grammar dependency edge (56 grammar crates + core).
rust_library(
name = "pi-ast",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
crate_name = "pi_ast",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True),
)
rust_test(
name = "pi-ast_test",
crate = ":pi-ast",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+25
View File
@@ -0,0 +1,25 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "pi-iso",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
crate_name = "pi_iso",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True),
)
rust_test(
name = "pi-iso_test",
crate = ":pi-iso",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+66
View File
@@ -0,0 +1,66 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_shared_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
# The NAPI cdylib. build.rs is intentionally not wired in: its only effects are
# napi_build::setup() link args (hardcoded in linkopts below — see napi-build
# src/lib.rs) and a vestigial no-op filter-defs scan that belongs to pi-shell.
# TypeScript typedef regeneration stays a cargo-side dev flow
# (`bun --cwd packages/natives run build:bindings`); index.js/index.d.ts are
# committed, so artifact builds never need the napi CLI.
rust_shared_library(
name = "pi_natives",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
compile_data = glob([
"src/syntaxes/*.sublime-syntax",
"src/fonts/*",
]),
crate_features = [],
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
rustc_flags = select({
"//bazel/variants:baseline": ["-Ctarget-cpu=x86-64-v2"],
"//bazel/variants:modern": ["-Ctarget-cpu=x86-64-v3"],
"//conditions:default": [],
}) + select({
# napi_build::setup() equivalents (build.rs is not wired into Bazel):
# napi addons resolve Node symbols at load time on macOS; DF_1_NODELETE
# keeps the addon resident across Worker teardown on linux-gnu (napi
# emits it for gnu; harmless under musl's loader). windows-msvc needs
# nothing — napi-sys v3 imports node.exe via raw-dylib.
"@platforms//os:macos": ["-Clink-arg=-Wl,-undefined,dynamic_lookup"],
"@platforms//os:linux": ["-Clink-arg=-Wl,-z,nodelete"],
"//conditions:default": [],
}) + select({
# musl defaults to +crt-static, under which rustc silently emits no
# cdylib at all; napi musl addons have always linked the dynamic CRT.
"//bazel/triples:x86_64-unknown-linux-musl": ["-Ctarget-feature=-crt-static"],
"//bazel/triples:aarch64-unknown-linux-musl": ["-Ctarget-feature=-crt-static"],
"//conditions:default": [],
}),
version = "17.1.5",
deps = all_crate_deps(normal = True) + [
"//crates/pi-ast",
"//crates/pi-iso",
"//crates/pi-shell",
"//crates/pi-uutils-ctx",
"//crates/pi-walker",
],
)
rust_test(
name = "pi_natives_test",
crate = ":pi_natives",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True) + [
# dev-dependency on every platform (desktop_x11's pure keysym helpers
# compile under cfg(test) everywhere), but cargo-bazel folds it into
# the linux-only normal dep entry; restore it for the test build.
"@crates//:xkeysym",
],
)
+104
View File
@@ -0,0 +1,104 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//cargo:defs.bzl", "cargo_build_script")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
# build.rs concatenates src/minimizer/defs/*.toml into OUT_DIR/builtin_filters.toml,
# consumed via include_str!(concat!(env!("OUT_DIR"), ...)) in minimizer/engine.rs.
cargo_build_script(
name = "build_script",
srcs = ["build.rs"],
data = glob(["src/minimizer/defs/*.toml"]),
edition = "2024",
deps = all_crate_deps(build = True),
)
rust_library(
name = "pi-shell",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
compile_data = glob([
"src/minimizer/filters/fixtures/**",
]),
crate_name = "pi_shell",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True) + [
":build_script",
"//crates/pi-uu-diff",
"//crates/pi-uu-grep",
"//crates/pi-uutils-ctx",
"//crates/pi-walker",
"//crates/vendor/brush-builtins",
"//crates/vendor/brush-core",
"//crates/vendor/jaq",
] + ["//crates/vendor/" + c for c in [
"uu-b2sum",
"uu-base32",
"uu-base64",
"uu-basename",
"uu-cat",
"uu-checksum-common",
"uu-comm",
"uu-cut",
"uu-date",
"uu-dirname",
"uu-find",
"uu-head",
"uu-hostname",
"uu-ln",
"uu-ls",
"uu-md5sum",
"uu-mkdir",
"uu-mktemp",
"uu-mv",
"uu-nproc",
"uu-paste",
"uu-printenv",
"uu-readlink",
"uu-realpath",
"uu-rm",
"uu-sed",
"uu-seq",
"uu-sha1sum",
"uu-sha224sum",
"uu-sha256sum",
"uu-sha384sum",
"uu-sha512sum",
"uu-sort",
"uu-stat",
"uu-tac",
"uu-tail",
"uu-tee",
"uu-touch",
"uu-tr",
"uu-truncate",
"uu-uname",
"uu-uniq",
"uu-wc",
"uu-whoami",
"uu-xargs",
"uu-yes",
]],
)
rust_test(
name = "pi-shell_test",
crate = ":pi-shell",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
rust_test(
name = "minimizer_fixtures_test",
srcs = ["tests/minimizer_fixtures.rs"],
data = glob(["tests/fixtures/minimizer/**"]),
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True) + [":pi-shell"],
)
+9 -4
View File
@@ -169,11 +169,16 @@ fn diff_excerpt(expected: &str, actual: &str) -> String {
excerpt.trim_end().to_string() excerpt.trim_end().to_string()
} }
/// Absolute path to the fixtures tree, anchored at the crate manifest dir so /// Absolute path to the fixtures tree. Under cargo the compile-time manifest
/// the harness loads identically whether run as an integration test or under a /// dir exists at runtime; under Bazel the compile-time sandbox path is gone,
/// different working directory. /// so fall back to the runfiles-relative layout (test cwd is the workspace
/// runfiles root and the fixtures ride along as `data`).
fn fixtures_root() -> std::path::PathBuf { fn fixtures_root() -> std::path::PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/minimizer") let manifest = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/minimizer");
if manifest.is_dir() {
return manifest;
}
Path::new("crates/pi-shell/tests/fixtures/minimizer").to_path_buf()
} }
/// Walk `<root>/<family>/<case>.cmd` and assemble each fixture with its /// Walk `<root>/<family>/<case>.cmd` and assemble each fixture with its
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "pi-uu-diff",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "pi_uu_diff",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "pi-uu-diff_test",
crate = ":pi-uu-diff",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+29
View File
@@ -0,0 +1,29 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "pi-uu-grep",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "pi_uu_grep",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/pi-walker",
],
)
rust_test(
name = "pi-uu-grep_test",
crate = ":pi-uu-grep",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+26
View File
@@ -0,0 +1,26 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "pi-uutils-ctx",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "pi_uutils_ctx",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True),
)
rust_test(
name = "pi-uutils-ctx_test",
crate = ":pi-uutils-ctx",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+39
View File
@@ -0,0 +1,39 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "pi-walker",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
crate_name = "pi_walker",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "17.1.5",
deps = all_crate_deps(normal = True),
)
rust_test(
name = "pi-walker_test",
crate = ":pi-walker",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
[
rust_test(
name = name + "_test",
srcs = ["tests/" + name + ".rs"],
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True) + [":pi-walker"],
)
for name in [
"parallel",
"perf",
]
]
+85
View File
@@ -0,0 +1,85 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
# Vendored fork, promoted to a workspace member so Bazel treats it as
# first-party (crate_universe's path-dep rendering is machine-local and breaks
# lockfile portability). Feature list mirrors cargo's resolved default set.
rust_library(
name = "brush-builtins",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
crate_features = [
"builtin.alias",
"builtin.bg",
"builtin.bind",
"builtin.break",
"builtin.builtin",
"builtin.caller",
"builtin.cd",
"builtin.colon",
"builtin.command",
"builtin.compgen",
"builtin.complete",
"builtin.compopt",
"builtin.continue",
"builtin.declare",
"builtin.dirs",
"builtin.dot",
"builtin.echo",
"builtin.enable",
"builtin.eval",
"builtin.exec",
"builtin.exit",
"builtin.export",
"builtin.false",
"builtin.fc",
"builtin.fg",
"builtin.getopts",
"builtin.hash",
"builtin.help",
"builtin.history",
"builtin.jobs",
"builtin.kill",
"builtin.let",
"builtin.mapfile",
"builtin.popd",
"builtin.printf",
"builtin.pushd",
"builtin.pwd",
"builtin.read",
"builtin.return",
"builtin.set",
"builtin.shift",
"builtin.shopt",
"builtin.suspend",
"builtin.test",
"builtin.times",
"builtin.trap",
"builtin.true",
"builtin.type",
"builtin.ulimit",
"builtin.umask",
"builtin.unalias",
"builtin.unset",
"builtin.wait",
],
crate_name = "brush_builtins",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.2.0",
deps = all_crate_deps(normal = True) + [
"//crates/vendor/brush-core",
],
)
rust_test(
name = "brush-builtins_test",
crate = ":brush-builtins",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+29
View File
@@ -0,0 +1,29 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
# Vendored fork, promoted to a workspace member so Bazel treats it as
# first-party (crate_universe's path-dep rendering is machine-local and breaks
# lockfile portability). Feature list mirrors cargo's resolved default set.
rust_library(
name = "brush-core",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
crate_features = [],
crate_name = "brush_core",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.5.0",
deps = all_crate_deps(normal = True),
)
rust_test(
name = "brush-core_test",
crate = ":brush-core",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+29
View File
@@ -0,0 +1,29 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "jaq",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
compile_data = ["src/help.txt"],
crate_name = "jaq",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "2.3.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "jaq_test",
crate = ":jaq",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+22
View File
@@ -0,0 +1,22 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-b2sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/b2sum.rs",
aliases = aliases(),
crate_name = "uu_b2sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-checksum-common",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-base32",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/base32.rs",
aliases = aliases(),
crate_name = "uu_base32",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-base32_test",
crate = ":uu-base32",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+29
View File
@@ -0,0 +1,29 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-base64",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/base64.rs",
aliases = aliases(),
crate_name = "uu_base64",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-base32",
],
)
rust_test(
name = "uu-base64_test",
crate = ":uu-base64",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-basename",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/basename.rs",
aliases = aliases(),
crate_name = "uu_basename",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-cat",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/cat.rs",
aliases = aliases(),
crate_name = "uu_cat",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-cat_test",
crate = ":uu-cat",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-checksum-common",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "uu_checksum_common",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-comm",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/comm.rs",
aliases = aliases(),
crate_name = "uu_comm",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-cut",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/cut.rs",
aliases = aliases(),
crate_name = "uu_cut",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-cut_test",
crate = ":uu-cut",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-date",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/date.rs",
aliases = aliases(),
crate_name = "uu_date",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-date_test",
crate = ":uu-date",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-dirname",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/dirname.rs",
aliases = aliases(),
crate_name = "uu_dirname",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-dirname_test",
crate = ":uu-dirname",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+45
View File
@@ -0,0 +1,45 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-find",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "uu_find",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/pi-walker",
],
)
# Unit tests assume cargo's cwd (bare `test_data/...` paths) and create
# symlinks inside the source tree — incompatible with Bazel's runfiles
# execution. Run them via `cargo nextest` when touching this vendored fork;
# bsd_compat_test below covers the CLI contract hermetically.
rust_test(
name = "uu-find_test",
crate = ":uu-find",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
tags = ["manual"],
deps = all_crate_deps(normal_dev = True),
)
rust_test(
name = "bsd_compat_test",
srcs = ["tests/bsd_compat.rs"],
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True) + [
":uu-find",
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-head",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/head.rs",
aliases = aliases(),
crate_name = "uu_head",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-head_test",
crate = ":uu-head",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-hostname",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/hostname.rs",
aliases = aliases(),
crate_name = "uu_hostname",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-hostname_test",
crate = ":uu-hostname",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-ln",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/ln.rs",
aliases = aliases(),
crate_name = "uu_ln",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-ln_test",
crate = ":uu-ln",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-ls",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/ls.rs",
aliases = aliases(),
crate_name = "uu_ls",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-ls_test",
crate = ":uu-ls",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-md5sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/md5sum.rs",
aliases = aliases(),
crate_name = "uu_md5sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/vendor/uu-checksum-common",
],
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-mkdir",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/mkdir.rs",
aliases = aliases(),
crate_name = "uu_mkdir",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-mktemp",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/mktemp.rs",
aliases = aliases(),
crate_name = "uu_mktemp",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-mktemp_test",
crate = ":uu-mktemp",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-mv",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/mv.rs",
aliases = aliases(),
crate_name = "uu_mv",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-mv_test",
crate = ":uu-mv",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-nproc",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/nproc.rs",
aliases = aliases(),
crate_name = "uu_nproc",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-nproc_test",
crate = ":uu-nproc",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-paste",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/paste.rs",
aliases = aliases(),
crate_name = "uu_paste",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-printenv",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/printenv.rs",
aliases = aliases(),
crate_name = "uu_printenv",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-printenv_test",
crate = ":uu-printenv",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-readlink",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/readlink.rs",
aliases = aliases(),
crate_name = "uu_readlink",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-readlink_test",
crate = ":uu-readlink",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-realpath",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/realpath.rs",
aliases = aliases(),
crate_name = "uu_realpath",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-realpath_test",
crate = ":uu-realpath",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-rm",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/rm.rs",
aliases = aliases(),
crate_name = "uu_rm",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-rm_test",
crate = ":uu-rm",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sed",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "uu_sed",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.1.1",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-sed_test",
crate = ":uu-sed",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-seq",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/seq.rs",
aliases = aliases(),
crate_name = "uu_seq",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-seq_test",
crate = ":uu-seq",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+22
View File
@@ -0,0 +1,22 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sha1sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/sha1sum.rs",
aliases = aliases(),
crate_name = "uu_sha1sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-checksum-common",
],
)
+22
View File
@@ -0,0 +1,22 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sha224sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/sha224sum.rs",
aliases = aliases(),
crate_name = "uu_sha224sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-checksum-common",
],
)
+22
View File
@@ -0,0 +1,22 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sha256sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/sha256sum.rs",
aliases = aliases(),
crate_name = "uu_sha256sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-checksum-common",
],
)
+22
View File
@@ -0,0 +1,22 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sha384sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/sha384sum.rs",
aliases = aliases(),
crate_name = "uu_sha384sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-checksum-common",
],
)
+22
View File
@@ -0,0 +1,22 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sha512sum",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/sha512sum.rs",
aliases = aliases(),
crate_name = "uu_sha512sum",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-checksum-common",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-sort",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/sort.rs",
aliases = aliases(),
crate_name = "uu_sort",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-sort_test",
crate = ":uu-sort",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+8 -10
View File
@@ -109,9 +109,8 @@ pub fn ext_sort(
// exit 0 with truncated or empty output. // exit 0 with truncated or empty output.
match sorter_handle.join() { match sorter_handle.join() {
Ok(()) => result, Ok(()) => result,
Err(_) => { Err(_) => result
result.and(Err(USimpleError::new(2, "sort: sorter thread terminated unexpectedly".to_string()))) .and(Err(USimpleError::new(2, "sort: sorter thread terminated unexpectedly".to_string()))),
},
} }
} }
@@ -320,10 +319,10 @@ mod tests {
use super::*; use super::*;
/// External (multi-chunk) sort must run to completion and emit fully sorted /// External (multi-chunk) sort must run to completion and emit fully sorted
/// output. Regression guard for #6760: `ext_sort` now joins the sorter thread /// output. Regression guard for #6760: `ext_sort` now joins the sorter
/// after `read_write_loop`. A tiny explicit buffer forces spilling to /// thread after `read_write_loop`. A tiny explicit buffer forces spilling
/// temporary files, so the join runs on the `WroteChunksToFile` path — it /// to temporary files, so the join runs on the `WroteChunksToFile` path —
/// must surface sorted output rather than deadlock or truncate. /// it must surface sorted output rather than deadlock or truncate.
#[test] #[test]
fn ext_sort_spills_to_files_and_sorts() { fn ext_sort_spills_to_files_and_sorts() {
let input: String = (0..200u32).rev().map(|i| format!("{i:04}\n")).collect(); let input: String = (0..200u32).rev().map(|i| format!("{i:04}\n")).collect();
@@ -335,9 +334,8 @@ mod tests {
let out_dir = tempfile::tempdir().expect("temp dir"); let out_dir = tempfile::tempdir().expect("temp dir");
let out_path = out_dir.path().join("sorted.txt"); let out_path = out_dir.path().join("sorted.txt");
let mut files = std::iter::once(Ok( let mut files =
Box::new(Cursor::new(input.into_bytes())) as Box<dyn Read + Send>, std::iter::once(Ok(Box::new(Cursor::new(input.into_bytes())) as Box<dyn Read + Send>));
));
let output = Output::new(Some(out_path.as_os_str())).expect("open output"); let output = Output::new(Some(out_path.as_os_str())).expect("open output");
let mut tmp_dir = TmpDirWrapper::new(std::env::temp_dir()); let mut tmp_dir = TmpDirWrapper::new(std::env::temp_dir());
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-stat",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/stat.rs",
aliases = aliases(),
crate_name = "uu_stat",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-stat_test",
crate = ":uu-stat",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-tac",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/tac.rs",
aliases = aliases(),
crate_name = "uu_tac",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-tac_test",
crate = ":uu-tac",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+31
View File
@@ -0,0 +1,31 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-tail",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/tail.rs",
aliases = aliases(),
crate_name = "uu_tail",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
"//crates/vendor/uu-tac",
],
)
rust_test(
name = "uu-tail_test",
# rstest's macro verifies Cargo.toml exists in the manifest dir.
compile_data = ["Cargo.toml"],
crate = ":uu-tail",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-tee",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/tee.rs",
aliases = aliases(),
crate_name = "uu_tee",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-touch",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/touch.rs",
aliases = aliases(),
crate_name = "uu_touch",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-touch_test",
crate = ":uu-touch",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-tr",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/tr.rs",
aliases = aliases(),
crate_name = "uu_tr",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-truncate",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/truncate.rs",
aliases = aliases(),
crate_name = "uu_truncate",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-truncate_test",
crate = ":uu-truncate",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-uname",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/uname.rs",
aliases = aliases(),
crate_name = "uu_uname",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-uname_test",
crate = ":uu-uname",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-uniq",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/uniq.rs",
aliases = aliases(),
crate_name = "uu_uniq",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+21
View File
@@ -0,0 +1,21 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-wc",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/wc.rs",
aliases = aliases(),
crate_name = "uu_wc",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-whoami",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/whoami.rs",
aliases = aliases(),
crate_name = "uu_whoami",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-whoami_test",
crate = ":uu-whoami",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-xargs",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/lib.rs",
aliases = aliases(),
crate_name = "uu_xargs",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-xargs_test",
crate = ":uu-xargs",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+28
View File
@@ -0,0 +1,28 @@
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
package(default_visibility = ["//visibility:public"])
exports_files(["Cargo.toml"])
rust_library(
name = "uu-yes",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/yes.rs",
aliases = aliases(),
crate_name = "uu_yes",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro = True),
version = "0.8.0",
deps = all_crate_deps(normal = True) + [
"//crates/pi-uutils-ctx",
],
)
rust_test(
name = "uu-yes_test",
crate = ":uu-yes",
edition = "2024",
proc_macro_deps = all_crate_deps(proc_macro_dev = True),
deps = all_crate_deps(normal_dev = True),
)
+232 -94
View File
@@ -2,61 +2,229 @@
This runbook describes how `@oh-my-pi/pi-natives` produces `.node` addons, generated declarations, and compiled-binary embedded payloads, and how to debug loader/build failures. This runbook describes how `@oh-my-pi/pi-natives` produces `.node` addons, generated declarations, and compiled-binary embedded payloads, and how to debug loader/build failures.
Addon **artifacts are built by Bazel** (`rules_rust` + `crate_universe` + hermetic cc toolchains); the cargo workspace stays authoritative for local Rust iteration (rust-analyzer, `cargo nextest`) and for napi typedef regeneration. Runtime loading and embedding are unchanged.
It follows the architecture terms from `docs/natives-architecture.md`: It follows the architecture terms from `docs/natives-architecture.md`:
- **build-time artifact production** (`scripts/build-native.ts`) - **build-time artifact production** (Bazel `//:natives-<target>` via `scripts/bazel-natives.ts`)
- **embedded addon manifest generation** (`scripts/embed-native.ts`) - **embedded addon manifest generation** (`scripts/embed-native.ts`)
- **runtime addon loading** (`native/index.js`, `native/loader-state.js`) - **runtime addon loading** (`native/index.js`, `native/loader-state.js`)
## Implementation files ## Implementation files
- `packages/natives/scripts/build-native.ts` Build side:
- `packages/natives/scripts/embed-native.ts`
- `packages/natives/scripts/gen-enums.ts` - `BUILD.bazel` (root) — the eight `//:natives-<target>` addon targets + aggregate filegroups
- `bazel/defs.bzl` — the `native_addon` rule/transition
- `bazel/platforms/BUILD.bazel` — one `platform()` per shipped addon
- `bazel/variants/BUILD.bazel` — `baseline`/`modern` ISA constraint values
- `bazel/toolchains/` — musl rustc disambiguation + the msvc cross cc toolchain (`msvc/NOTES.md`)
- `bazel/clippy.bazelrc` — generated from `[workspace.lints]` in `Cargo.toml`
- `MODULE.bazel`, `.bazelrc`, `.bazelversion` (Bazel 9.2.0), `Cargo.Bazel.lock`
- `scripts/bazel-natives.ts` — the canonical driver (build + locate + install)
- `crates/pi-natives/BUILD.bazel`, `crates/pi-natives/Cargo.toml`
Package side (unchanged runtime/packaging):
- `packages/natives/scripts/build-bindings.ts` — dev-only typedef regeneration
- `packages/natives/scripts/embed-native.ts`, `gen-enums.ts`, `gen-npm-packages.ts`
- `packages/natives/package.json` - `packages/natives/package.json`
- `packages/natives/native/index.js` - `packages/natives/native/index.js`, `native/loader-state.js`
- `packages/natives/native/loader-state.js`
- `crates/pi-natives/Cargo.toml`
## Build pipeline overview ## Build architecture
### 1) Build entrypoints ### 1) `//:natives-<target>` addon targets
`packages/natives/package.json` scripts: Root `BUILD.bazel` instantiates one `native_addon` per shipped `(platform, arch, ISA-variant)`:
- `bun scripts/build-native.ts` (`build`) → N-API build, addon install, generated declarations install, explicit ESM export and enum runtime patch. | Target | Platform | Canonical output |
- `bun scripts/embed-native.ts` (`gen:native`) → generate `native/embedded-addon.js` plus `native/embedded-addons.<tag>.tar.gz` from built files. | --------------------------------- | --------------------------------------- | ------------------------------------ |
- `bun scripts/gen-npm-packages.ts` (`gen:npm`) → generate per-platform npm leaf packages (`@oh-my-pi/pi-natives-<platform>-<arch>`, installed as optional dependencies of the core package) under `npm/` from built addon files. | `//:natives-linux-x64-baseline` | `//bazel/platforms:linux-x64-baseline` | `pi_natives.linux-x64-baseline.node` |
| `//:natives-linux-x64-modern` | `//bazel/platforms:linux-x64-modern` | `pi_natives.linux-x64-modern.node` |
| `//:natives-linux-arm64` | `//bazel/platforms:linux-arm64` | `pi_natives.linux-arm64.node` |
| `//:natives-linux-musl-x64-baseline` | `//bazel/platforms:linux-musl-x64-baseline` | `pi_natives.linux-x64-baseline.node` |
| `//:natives-linux-musl-arm64` | `//bazel/platforms:linux-musl-arm64` | `pi_natives.linux-arm64.node` |
| `//:natives-darwin-x64-baseline` | `//bazel/platforms:darwin-x64-baseline` | `pi_natives.darwin-x64-baseline.node` |
| `//:natives-darwin-arm64` | `//bazel/platforms:darwin-arm64` | `pi_natives.darwin-arm64.node` |
| `//:natives-win32-x64-baseline` | `//bazel/platforms:win32-x64-baseline` | `pi_natives.win32-x64-baseline.node` |
Root scripts include `build:native` as `bun --cwd=packages/natives run build`. Notes:
### 2) N-API/Rust artifact build - musl addons **intentionally reuse** the plain `linux-<arch>` filenames — the loader never sees gnu and musl side by side; release jobs keep them in separate invocations/dest dirs (`scripts/bazel-natives.ts` hard-errors on a basename collision within one run).
- Aggregates: `//:natives-linux-all` (all linux targets + the msvc cross build, i.e. everything buildable from a linux-x64 host) and `//:natives-darwin-all` (mac hosts only).
`build-native.ts` invokes the `@napi-rs/cli` binary directly from `node_modules/.bin` with: ### 2) `native_addon` rule (`bazel/defs.bzl`)
- `napi build` `native_addon` wraps `//crates/pi-natives:pi_natives` (a `rust_shared_library`) in a configuration transition that pins, per target:
- `--manifest-path crates/pi-natives/Cargo.toml`
- `--package-json-path packages/natives/package.json`
- `--platform`
- `--no-js`
- `--dts index.d.ts`
- `--profile local` for non-CI local native builds, otherwise `--profile ci`
- `-o <isolated temp output dir>`
- optional `--target <CROSS_TARGET>` plus `--cross-compile` (napi picks the `cargo-zigbuild` or `cargo-xwin` backend from the target) for cross builds
`crates/pi-natives/Cargo.toml` declares `crate-type = ["cdylib"]`; napi-rs emits `.node` artifacts plus generated `index.d.ts` in an isolated temporary output directory under `packages/natives/native/.build/`. - `--platforms=<the addon's platform>`
- `--compilation_mode=opt`
- `@rules_rust//rust/settings:lto=thin`
- extra rustc flags `-Ccodegen-units=16 -Cstrip=symbols`
### 3) Artifact install This mirrors the old cargo `ci` profile. Because the profile lives **in the transition**, a bare `bazel build //:natives-<t>` is always release-grade regardless of `-c`, and every addon shares one cache entry per (platform, source) pair. The rule then symlinks the produced shared library to the loader's canonical `pi_natives.<platform>-<arch>[-<variant>].node` name, scoped under the rule name (`bazel-bin/natives-<t>/…`) so gnu/musl outputs with identical basenames cannot collide at the package level.
After napi-rs succeeds, `build-native.ts`: Per-target codegen that is not part of the transition lives in `crates/pi-natives/BUILD.bazel` `rustc_flags` selects: `-Ctarget-cpu=x86-64-v2` (baseline) / `x86-64-v3` (modern) via `//bazel/variants`, the napi link args (`-Wl,-undefined,dynamic_lookup` on macOS, `-Wl,-z,nodelete` on linux — `build.rs`/`napi_build::setup()` is deliberately not wired in), and `-Ctarget-feature=-crt-static` for musl.
1. resolves the built addon in the isolated output directory; ### 3) Platforms and toolchains
2. normalizes its name to `pi_natives.<platform>-<arch>(-variant).node` when needed;
3. installs the addon into `packages/natives/native/` with temp-file + rename semantics;
4. copies generated `index.d.ts` into `packages/natives/native/`;
5. runs `generateEnumExports()` to render explicit named ESM exports for classes/functions and runtime enum objects in the checked-in `native/index.js`.
Windows locked-DLL update failures are handled at runtime by staging install candidates into the versioned native cache; install/rename failures during local builds still include explicit file-operation diagnostics. | Target family | cc toolchain | Notes |
| --- | --- | --- |
| linux gnu (x64/arm64) | `@zig_sdk//libc_aware/toolchain:linux_*_gnu.2.17` (hermetic zig cc) | glibc **2.17** portability floor — same floor the previous cross builds used |
| linux musl (x64/arm64) | `@zig_sdk//libc_aware/toolchain:linux_*_musl` | dynamic CRT (`-Ctarget-feature=-crt-static` in the crate BUILD) |
| darwin (x64/arm64) | host Xcode toolchain | Apple frameworks aren't redistributable; darwin addons build on mac hosts only |
| win32-x64 msvc | `//bazel/toolchains/msvc` (`@msvc_cc`): clang-cl + lld-link + xwin CRT/SDK | hermetic cross-link from linux-x64 CI pods and darwin dev hosts; see `bazel/toolchains/msvc/NOTES.md` |
Rust toolchains are nightly (pinned in `MODULE.bazel`), with repo-local musl re-registrations in `//bazel/toolchains` carrying an explicit `@zig_sdk//libc:musl` constraint (rules_rust's generated gnu and musl toolchains otherwise share (os, cpu) constraints).
### 4) Third-party crates (`crate_universe`)
`@crates//...` is generated from the workspace `Cargo.toml`/`Cargo.lock` (lockfile: `Cargo.Bazel.lock`), restricted to exactly the seven shipped triples. Crate-specific build fixes live as `crate.annotation`s in `MODULE.bazel` (see the debugging playbook below).
**Repin flow:** after any `Cargo.toml`/`Cargo.lock` change (or annotation edit), run
```bash
bun run bazel:repin # = CARGO_BAZEL_REPIN=1 bazelisk fetch @crates//...
```
and commit the updated `Cargo.Bazel.lock`. A stale lockfile fails analysis with a "lockfile out of date" style error.
## Local development
### Building addons
```bash
# Addon for the current host (x64 hosts pick modern vs baseline via AVX2 detection),
# installed into packages/natives/native/:
bun --cwd=packages/natives run build # = bun ../../scripts/bazel-natives.ts host --dest native
# same, from the repo root:
bun run build:native
# The driver directly — targets are //:natives-* names plus pseudo-targets
# host / linux-all / darwin-all:
bun scripts/bazel-natives.ts <target>... [--dest <dir>] [-- <extra bazel args>]
bun scripts/bazel-natives.ts linux-x64-baseline linux-x64-modern --dest packages/natives/native
bun scripts/bazel-natives.ts darwin-all
# Or bazelisk directly (outputs stay in bazel-bin, nothing is installed):
bazelisk build //:natives-darwin-arm64
bazelisk build //:natives-linux-all
```
The driver runs one `bazel build` for all requested targets, locates outputs via `bazel cquery --output=files` (falling back to the `bazel-bin/natives-<t>/<canonical>.node` path convention), and copies them dereferenced into `--dest` (default `packages/natives/native`). Extra args after `--` go to bazel verbatim. It resolves `bazelisk` (or `bazel`) from `PATH` and honors an `OMP_BAZEL_RC` env var as a `--bazelrc=` startup option (that's how CI injects cache wiring).
Building `linux-all` into one dest would clobber gnu addons with musl ones (shared basenames) — the driver refuses; use separate invocations with separate `--dest` dirs.
### Typedef regeneration (napi CLI, dev-only)
`native/index.js`/`index.d.ts` are **committed**, so Bazel artifact builds never need the napi CLI. Only when the Rust API surface changes its exported typedefs:
```bash
bun --cwd=packages/natives run build:bindings # = bun scripts/build-bindings.ts
```
This runs the napi CLI (host-only, local cargo profile) against `crates/pi-natives`, installs the regenerated `index.d.ts`, normalizes the addon filename, and re-renders the explicit ESM exports + runtime enum objects via `gen-enums.ts`. Commit the resulting `index.js`/`index.d.ts` changes.
### Opt-in remote cache (`.bazelrc.user`)
`.bazelrc` ends with `try-import %workspace%/.bazelrc.user` (gitignored). The bazel-remote endpoint is cluster-internal only; if you can reach it (VPN/tailnet), wire it read-only:
```
# .bazelrc.user
build --config=cache-ro
build --remote_cache=grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092
build --tls_certificate=infra/bazel-remote/ca.crt
```
`cache-ro`/`cache-rw` in `.bazelrc` carry only policy (upload on/off, `--remote_local_fallback`, retries/timeout so a cache outage never fails the build); endpoint + credentials are always composed by the consumer. A plain `--disk_cache=<dir>` line also works fine here.
## CI
### `rust` job (validate + cache warm)
`.github/workflows/ci.yml` `rust` runs on `omp-kata` pods for pushes and `ubuntu-22.04` for PRs, composes cache wiring via the `bazel-cache` action, then:
```bash
bazelisk --bazelrc="$rc" test //crates/... # full Rust suite
# clippy scope mirrors `cargo clippy --workspace` (libraries only), split by
# lint policy via a query kind filter:
bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...)" \
| xargs bazelisk --bazelrc="$rc" build --config=clippy-strict --
bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (…strict set…) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \
| xargs bazelisk --bazelrc="$rc" build --config=clippy --
bazelisk --bazelrc="$rc" build --config=rustfmt //crates/...
```
- `--config=clippy` = rules_rust clippy aspect + `-Dwarnings`; `--config=clippy-strict` layers the generated `bazel/clippy.bazelrc` (rendered from `[workspace.lints]` in `Cargo.toml` — regenerate it when workspace lints change) for the crates with `[lints] workspace = true`.
- `--config=rustfmt` = rustfmt aspect against the workspace `rustfmt.toml`.
- On main pushes (read-write cache) the job additionally runs `bazelisk build //:natives-linux-all` to warm the shared cache for every downstream job.
No toolchain setup steps: bazelisk is on the GitHub images and baked into the kata runner image; Bazel fetches Rust/zig/LLVM/xwin hermetically.
### `bazel-cache` action (`.github/actions/bazel-cache`)
Single source of truth for cache wiring, emitted as a bazelrc fragment (its `rc` output) that consumers pass via `bazelisk --bazelrc=...` (or `OMP_BAZEL_RC` for the driver). Two modes, detected via `BAZEL_REMOTE_USER`/`BAZEL_REMOTE_PASSWORD` (injected from the `bazel-remote-ci` secret on kata pods only):
| Runner | Fragment contents |
| --- | --- |
| omp-kata pod | `--config=ci --config=cache-rw --remote_cache=grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092 --tls_certificate=infra/bazel-remote/ca.crt --remote_header='authorization=Basic <b64 ci creds>'` |
| GitHub-hosted | `--config=ci --disk_cache=~/.cache/omp-bazel-disk --repository_cache=~/.cache/omp-bazel-repo`, persisted by `actions/cache` keyed on `bazel-disk-<scope>-<os>-<arch>-<hash(Cargo.Bazel.lock, MODULE.bazel, rust-toolchain.toml)>` |
The remote endpoint resolves **only inside the cluster** (see `infra/bazel-remote/` and `infra/docs/04-arc-and-caching.md` §5); GitHub-hosted runners never talk to it. The `scope` input separates disk-cache keys per target set (`linux-x64-pair`, `release-<target_id>`, …) so jobs don't evict each other's entries.
### `bazel-natives` action (`.github/actions/bazel-natives`)
Thin composite: `bazel-cache` (with `cache-scope`) → `OMP_BAZEL_RC=<rc> bun scripts/bazel-natives.ts <targets> --dest <dest>`. Every TS test job uses it with `targets: linux-x64-baseline linux-x64-modern`, `cache-scope: linux-x64-pair`.
### `release_binary`
Release runners are GitHub-hosted and build addons **inline** (disk-cache mode — repeat releases with unchanged Rust are mostly local cache hits): the `bazel-natives` action runs with the matrix's `native_targets` (`linux-x64-baseline linux-x64-modern`, `linux-musl-x64-baseline`, `linux-arm64`, `linux-musl-arm64`, `darwin-all` on both mac runners, `win32-x64-baseline` cross-built from `ubuntu-22.04`) and `cache-scope: release-<target_id>`, then `bun run ci:release:build-binaries` embeds and compiles.
## Debugging playbook
### Where things land / how to inspect
```bash
# Outputs (workspace-relative): bazel-bin/natives-<target>/pi_natives.<...>.node
bazelisk cquery --output=files //:natives-linux-x64-baseline
# What actions/flags a target produces (add the same --config flags as the build):
bazelisk aquery 'outputs(".*\.node", deps(//:natives-linux-arm64))'
bazelisk aquery 'mnemonic("Rustc", deps(//crates/pi-natives:pi_natives))'
# Which toolchain resolved (e.g. confirm @msvc_cc, not host cc, for win32):
bazelisk cquery 'deps(//:natives-win32-x64-baseline)' | grep msvc_cc
# Keep the sandbox dir + print the full command line of a failing action:
bazelisk build --sandbox_debug --verbose_failures //:natives-<t>
# Analyze without building (cheap cross-target sanity check):
bazelisk build --nobuild //:natives-win32-x64-baseline
```
`scripts/bazel-natives.ts` streams bazel stderr live and repeats a 40-line tail on failure; when its cquery step fails it falls back to the `bazel-bin` path convention.
### Common failure classes (seen during bring-up — fixes already in tree, cite when they resurface)
| Symptom | Cause | Fix (in tree) |
| --- | --- | --- |
| musl build "succeeds" but emits no `.node` | musl defaults to `+crt-static`; rustc silently emits no cdylib | `-Ctarget-feature=-crt-static` select in `crates/pi-natives/BUILD.bazel` |
| opus/cmake `try_compile` fails linking UBSan runtime | zig cc enables UBSan by default; cmake's test exe links with the raw wrapper (no toolchain features) | `CFLAGS=-fno-sanitize=undefined` in the `audiopus_sys` annotation (`MODULE.bazel`) |
| `tree-sitter-just` scanner.c `#error` under opt | scanner hard-errors when `NDEBUG` is set (opt-mode cc default) | `CFLAGS=-UNDEBUG` annotation (cc-rs appends env CFLAGS last, so `-U` wins) |
| rstest macro: "Cargo.toml not found" in a vendored test | rstest verifies `Cargo.toml` exists in the manifest dir | `compile_data = ["Cargo.toml"]` on the `rust_test` (see `crates/vendor/uu-tail/BUILD.bazel`) |
| vendored tests fail on bare `test_data/...` paths / symlink into srcs | tests assume cargo's cwd, incompatible with runfiles execution | `tags = ["manual"]` (e.g. `//crates/vendor/uu-find:uu-find_test`); run via `cargo nextest` when touching the fork; hermetic sibling test covers the contract |
| blake3 msvc: `ml64.exe` not found | cc-rs resolves MASM from build-script PATH on non-windows hosts | `bin/ml64.exe → llvm-ml -m64` shim in `@msvc_cc`, prepended via the `blake3` annotation PATH |
| audiopus_sys msvc: cmake demands VS generator / rc+mt tools; `try_compile` wants `msvcrtd.lib` | cross cmake on linux/mac hosts; Debug config → `/MDd` which the lean xwin splat lacks | `CMAKE_GENERATOR_x86_64_pc_windows_msvc=Ninja` + `@msvc_cc`'s `toolchain.cmake` (`CMAKE_TOOLCHAIN_FILE_x86_64_pc_windows_msvc`) pinning wrappers + Release try-compile + `/MD` |
| win32 link oddities generally | — | read `bazel/toolchains/msvc/NOTES.md` first: wrapper self-location, `lld-link` flavor/driver-link behavior, `LIB`, `/MD` CRT choice, xwin splat caveats |
| `rust_test(crate = ...)` "can't find crate" at macro expansion | rmeta-only pipelined deps break macro_rules re-export harness compiles | rust pipelined_compilation stays OFF (`.bazelrc` note) |
| build script can't find cmake/ninja | `--incompatible_strict_action_env` — no host env leaks | explicit `PATH` in the crate annotation (`MODULE.bazel`), not host env |
### Cache behavior
- **omp-kata (push/main, release_binary is not here):** read-write gRPC to in-cluster bazel-remote (`grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092`, TLS via the committed `infra/bazel-remote/ca.crt`, htpasswd user `ci`). Expect `remote cache hit` counts in the build summary; the `rust` job's `//:natives-linux-all` warm build on main pushes is what seeds it. `--remote_local_fallback` + retries mean a cache outage degrades to a local build, never a failure.
- **GitHub-hosted (PRs, macOS, releases):** no remote cache at all — `--disk_cache`/`--repository_cache` persisted by `actions/cache`, keyed on `(scope, os, arch, hash(Cargo.Bazel.lock, MODULE.bazel, rust-toolchain.toml))` with a prefix restore key. A lockfile/module change starts from the nearest previous entry.
- **msvc repos:** the ~2 GiB LLVM download is sha256-pinned and repository-cache backed; the ~1 GiB xwin CRT/SDK splat is fetched from the Microsoft CDN inside the repo rule and is **not** repo-cache backed — a cold output base re-downloads it. Microsoft advances the VS channel payload over time, so remote-cache hit rates for win32 actions degrade gracefully after an MS bump (same property the previous cross toolchain had). Win32 link actions also don't share cache entries across host OSes (linux vs mac clang binaries).
- Server-side operations (deploy, TLS/auth, egress, poisoning boundary): `infra/docs/04-arc-and-caching.md` §5.
## Target/variant model and naming conventions ## Target/variant model and naming conventions
@@ -68,12 +236,12 @@ Both build and runtime use platform tag:
## Variant model (x64 only) ## Variant model (x64 only)
x64 supports CPU variants: x64 supports CPU variants, encoded as `//bazel/variants` constraint values on the platform (baseline → `-Ctarget-cpu=x86-64-v2`, modern → `x86-64-v3`):
- `modern` (AVX2-capable path) - `modern` (AVX2-capable path)
- `baseline` (fallback) - `baseline` (fallback)
Non-x64 uses a single default artifact with no variant suffix. Non-x64 uses a single default artifact with no variant suffix. There is no build-time variant *switch*: each variant is its own `//:natives-*` target, and the `host` pseudo-target picks modern vs baseline via AVX2 detection.
### Output filenames ### Output filenames
@@ -82,50 +250,14 @@ Non-x64 uses a single default artifact with no variant suffix.
Runtime x64 candidate order also includes the unsuffixed default filename after the selected variant candidates. Runtime x64 candidate order also includes the unsuffixed default filename after the selected variant candidates.
## Environment flags and build options
## Runtime flags ## Runtime flags
- `PI_NATIVE_VARIANT`: x64 runtime override; valid values are `modern` and `baseline`. - `PI_NATIVE_VARIANT`: x64 runtime override; valid values are `modern` and `baseline`.
- `PI_COMPILED`: legacy compiled-mode signal. A populated embedded-addon manifest is also a compiled-mode signal; compiled release builds additionally define `process.env.PI_COMPILED="true"` during `bun build --compile`. - `PI_COMPILED`: legacy compiled-mode signal. A populated embedded-addon manifest is also a compiled-mode signal; compiled release builds additionally define `process.env.PI_COMPILED="true"` during `bun build --compile`.
## Build-time flags/options ## Embed lifecycle (`embed-native.ts`)
- `CROSS_TARGET`: passed to napi-rs as `--target <CROSS_TARGET>`. 1. **Init**: compute the platform tag (host values, overridable by the release packaging script for cross-target archives).
- `TARGET_PLATFORM`: override output platform tag naming.
- `TARGET_ARCH`: override output arch naming.
- `TARGET_VARIANT` (x64 only): force `modern` or `baseline` for output filename and RUSTFLAGS policy.
- `CARGO_TARGET_DIR`: respected if set; otherwise the default `target/` dir is used so `Swatinem/rust-cache` can cache cleanly.
- `RUSTFLAGS`:
- if unset and not cross-compiling, script sets:
- modern: `-C target-cpu=x86-64-v3`
- baseline: `-C target-cpu=x86-64-v2`
- non-x64 / no variant: `-C target-cpu=native`
- if already set, script does not override.
## Build state/lifecycle transitions
### Build lifecycle (`build-native.ts`)
1. **Init**: parse env, resolve target tuple, cross/local mode, profile label.
2. **Variant resolve**:
- non-x64 → no variant;
- x64 + `TARGET_VARIANT` → explicit variant;
- x64 cross-build without `TARGET_VARIANT` → hard error;
- x64 local build without override → detect host AVX2.
3. **CPU policy**: set `RUSTFLAGS` for the resolved variant unless the caller already provided one.
4. **Compile**: run napi-rs against `crates/pi-natives` into an isolated output directory.
5. **Locate artifact**: accept the canonical filename or a single napi-rs-generated `pi_natives.<platform>-<arch>*.node` candidate.
6. **Install**: copy/rename addon into `packages/natives/native`.
7. **Install generated declarations**: copy `index.d.ts`.
8. **Patch exports/enums**: regenerate explicit ESM exports and enum runtime objects.
9. **Cleanup**: remove the temporary build output directory.
Failure exits have explicit error text for invalid variants, failed napi build, missing/multiple output artifacts, generated binding install failure, stripped CI ELF artifacts that still contain forbidden symbol/string-table sections, and install/rename failure.
### Embed lifecycle (`embed-native.ts`)
1. **Init**: compute platform tag from `TARGET_PLATFORM`/`TARGET_ARCH` or host values.
2. **Candidate set**: 2. **Candidate set**:
- x64 looks for `modern` and `baseline` files; - x64 looks for `modern` and `baseline` files;
- non-x64 looks for one default file. - non-x64 looks for one default file.
@@ -143,7 +275,7 @@ Typical local loop:
1. Build addon: `bun --cwd=packages/natives run build`. 1. Build addon: `bun --cwd=packages/natives run build`.
2. Loader resolves platform npm leaf-package candidates (`@oh-my-pi/pi-natives-<platform>-<arch>`, when resolvable), then package-local `native/` and executable-dir fallback candidates. 2. Loader resolves platform npm leaf-package candidates (`@oh-my-pi/pi-natives-<platform>-<arch>`, when resolvable), then package-local `native/` and executable-dir fallback candidates.
3. Generated declarations in `native/index.d.ts` describe the public TS API. 3. Generated declarations in `native/index.d.ts` describe the public TS API (regenerate with `build:bindings` only when the Rust API surface changes).
## Shipped/compiled binary workflow ## Shipped/compiled binary workflow
@@ -176,14 +308,12 @@ Generated declarations currently include exports from these Rust modules:
## Build-time failures ## Build-time failures
- Invalid variant configuration: - Bazel analysis/compile failure: `scripts/bazel-natives.ts` surfaces the exit code plus a stderr tail; re-run the printed `bazel build` line directly (add `--verbose_failures`, `--sandbox_debug`) to iterate.
- `TARGET_VARIANT` set on non-x64 → immediate error. - Unknown target name: the driver errors with the full known-target list (`//:natives-*` names + `host`/`linux-all`/`darwin-all`).
- unsupported `TARGET_VARIANT` value → immediate error. - No `.node` outputs located after a successful build: driver exits 1 (check `bazel cquery --output=files` manually).
- x64 cross-build without explicit `TARGET_VARIANT` → immediate error. - Basename collision (gnu + musl in one invocation): driver refuses to install and names both sources — split into separate `--dest` dirs.
- napi-rs build failure: script surfaces non-zero exit and stderr. - Stale `Cargo.Bazel.lock` after a `Cargo.{toml,lock}` change: run `bun run bazel:repin`.
- Artifact not found or ambiguous: script prints expected/candidate filenames and output directory contents. - `build:bindings` (napi) failure: script surfaces non-zero exit and stderr; artifact builds are unaffected (Bazel never runs the napi CLI).
- Install failure: explicit message; Windows includes locked-file hint.
- Generated binding install failure: explicit source/destination message.
## Runtime loader failures (`native/loader-state.js`) ## Runtime loader failures (`native/loader-state.js`)
@@ -196,22 +326,30 @@ Generated declarations currently include exports from these Rust modules:
| Symptom | Likely cause | Verify | Fix | | Symptom | Likely cause | Verify | Fix |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `Cannot find module` or dynamic library load error for every candidate | Missing release artifact, wrong platform tag, or stale compiled cache | Inspect loader error list and `packages/natives/native` filenames | Build correct target/variant; delete stale cache for the package version | | `Cannot find module` or dynamic library load error for every candidate | Missing release artifact, wrong platform tag, or stale compiled cache | Inspect loader error list and `packages/natives/native` filenames | Build correct target (`bun scripts/bazel-natives.ts <t> --dest packages/natives/native`); delete stale cache for the package version |
| Export is missing at runtime but present in TypeScript | Stale `.node` loaded, generated declarations newer than binary, or Rust export not compiled | Require the actual candidate and inspect `Object.keys(mod)` | Rebuild native package and remove stale candidate/cache paths | | Export is missing at runtime but present in TypeScript | Stale `.node` loaded, generated declarations newer than binary, or Rust export not compiled | Require the actual candidate and inspect `Object.keys(mod)` | Rebuild native package and remove stale candidate/cache paths |
| x64 machine loads baseline when modern expected | `PI_NATIVE_VARIANT=baseline`, no AVX2 detected, or modern file unavailable | Check env and filenames in `native/` | Build modern variant (`TARGET_VARIANT=modern ... build`) and ship it | | x64 machine loads baseline when modern expected | `PI_NATIVE_VARIANT=baseline`, no AVX2 detected, or modern file unavailable | Check env and filenames in `native/` | Build and ship the modern target (`bun scripts/bazel-natives.ts linux-x64-modern --dest packages/natives/native`) |
| Cross-build produces wrong-labeled binary | Mismatch between `CROSS_TARGET` and `TARGET_PLATFORM`/`TARGET_ARCH`, or missing x64 variant | Confirm env tuple and output filename | Re-run with consistent env values and explicit x64 `TARGET_VARIANT` | | gnu addon overwritten by musl (or vice versa) | Both built into one dest — they share canonical basenames by design | Compare `bazel-bin/natives-<t>/` sources vs installed file | Separate invocations with separate `--dest` dirs (release matrix already does this) |
| Compiled binary fails after upgrade | Stale extracted cache, embedded archive mismatch, or embedded manifest version mismatch | Inspect `<getNativesDir()>/<version>` and loader error list | Delete versioned cache for the package version; regenerate embedded archive/manifest during packaging | | Compiled binary fails after upgrade | Stale extracted cache, embedded archive mismatch, or embedded manifest version mismatch | Inspect `<getNativesDir()>/<version>` and loader error list | Delete versioned cache for the package version; regenerate embedded archive/manifest during packaging |
| `gen:native` fails with `No native addons found` | Required platform artifact was not built before embedding | Check expected list in error text | Build at least one expected artifact for the target, then rerun `gen:native` | | `gen:native` fails with `No native addons found` | Required platform artifact was not built before embedding | Check expected list in error text | Build at least one expected artifact for the target, then rerun `gen:native` |
## Operational commands ## Operational commands
```bash ```bash
# Release artifact for current host # Addon for the current host, installed into packages/natives/native/
bun --cwd=packages/natives run build bun --cwd=packages/natives run build
# Build explicit x64 variants # Explicit targets (x64 variants are separate targets, not env switches)
TARGET_VARIANT=modern bun --cwd=packages/natives run build bun scripts/bazel-natives.ts linux-x64-modern linux-x64-baseline --dest packages/natives/native
TARGET_VARIANT=baseline bun --cwd=packages/natives run build
# Raw bazel (output: bazel-bin/natives-<t>/pi_natives.<...>.node)
bazelisk build //:natives-darwin-arm64
# Refresh Cargo.Bazel.lock after Cargo.{toml,lock} or annotation changes
bun run bazel:repin
# Regenerate TS typedefs + enum exports (napi CLI, only on Rust API changes)
bun --cwd=packages/natives run build:bindings
# Generate embedded addon manifest from built native files # Generate embedded addon manifest from built native files
bun run gen:native bun run gen:native
@@ -245,11 +383,11 @@ The key is `sha256` over `(path \t git-tree-hash \n)` pairs for the following in
2. `Cargo.lock` 2. `Cargo.lock`
3. `Cargo.toml` 3. `Cargo.toml`
4. `rust-toolchain.toml` 4. `rust-toolchain.toml`
5. `packages/natives` (whole subtree — build script, `scripts/*`, package.json with napi config) 5. `packages/natives` (whole subtree — build script, `scripts/*`, package.json)
Tree hashes come from one `git cat-file --batch-check` invocation against `HEAD`; paths missing from `HEAD` fold in as a fixed null hash so the key stays deterministic across repos that don't ship every input. The target-triple suffix matches the napi addon basename convention (`<platform>-<arch>` for non-x64, `<platform>-<arch>-<variant>` for x64). When `TARGET_VARIANT` is unset on an x64 host the variant component is `host` rather than autodetected — the key is stable on a given machine but a `modern`/`baseline` build with an explicit `TARGET_VARIANT` gets a different key. Tree hashes come from one `git cat-file --batch-check` invocation against `HEAD`; paths missing from `HEAD` fold in as a fixed null hash so the key stays deterministic across repos that don't ship every input. The target-triple suffix matches the addon basename convention (`<platform>-<arch>` for non-x64, `<platform>-<arch>-<variant>` for x64).
Anything outside this input set (Rust toolchain auto-installed delta, host glibc, env vars other than `TARGET_VARIANT`) is **not** in the key. If you need to invalidate after such a change, delete the cache directory by hand or bump one of the input files. Anything outside this input set (Bazel definition files like `MODULE.bazel`/`BUILD.bazel`/`Cargo.Bazel.lock`, host glibc, env vars) is **not** in the key. If you need to invalidate after such a change, delete the cache directory by hand or bump one of the input files.
### Layout and ownership ### Layout and ownership
@@ -261,7 +399,7 @@ Anything outside this input set (Rust toolchain auto-installed delta, host glibc
### Populate and capture semantics ### Populate and capture semantics
- **Populate** (workspace ← cache) runs inside `ensure_workspace`. On a key hit the `.node` is **hardlinked** into the workspace (zero-copy, shared inode); the companion `index.d.ts` / `index.js` / `embedded-addon.js` are **copied** (independent inodes) because the napi build's `installGeneratedBindings` and `gen-enums.ts` rewrite those files via `open(..., 'w')` — an in-place truncate that would otherwise propagate through a hardlink and corrupt the cache. Cross-device hardlink failures (`EXDEV`) fall back to copy. - **Populate** (workspace ← cache) runs inside `ensure_workspace`. On a key hit the `.node` is **hardlinked** into the workspace (zero-copy, shared inode); the companion `index.d.ts` / `index.js` / `embedded-addon.js` are **copied** (independent inodes) because the bindings regeneration flow (`build-bindings.ts`'s `installGeneratedBindings` and `gen-enums.ts`) rewrites those files via `open(..., 'w')` — an in-place truncate that would otherwise propagate through a hardlink and corrupt the cache. Cross-device hardlink failures (`EXDEV`) fall back to copy.
- **Capture** (cache ← workspace) runs from the post-task success path when the build produced a complete artifact set. Capture uses **copy**, not hardlink: hardlinking a slot-owned workspace file would preserve slot UID ownership on the cached inode and defeat the shared-group model. Copying creates a fresh root-owned, `gid=omp` inode via the setgid cache root. Capture is idempotent under the per-repo flock: a concurrent capture for the same key returns the existing entry. - **Capture** (cache ← workspace) runs from the post-task success path when the build produced a complete artifact set. Capture uses **copy**, not hardlink: hardlinking a slot-owned workspace file would preserve slot UID ownership on the cached inode and defeat the shared-group model. Copying creates a fresh root-owned, `gid=omp` inode via the setgid cache root. Capture is idempotent under the per-repo flock: a concurrent capture for the same key returns the existing entry.
### Garbage collection ### Garbage collection
+109
View File
@@ -0,0 +1,109 @@
# bazel-remote cache for the self-hosted Bazel pipeline.
#
# One replica, node-local storage (RWO local-path PVC), TLS + htpasswd auth from
# secrets created by setup.sh (run that script on the CI host; it generates the
# CA/server cert and credentials, then applies this file).
#
# Exposure: ClusterIP `bazel-remote` only — gRPC :9092 + HTTP :8080 for
# in-cluster runner pods (kata microVMs). Nothing is published outside the
# cluster: GitHub-hosted runners never talk to this infrastructure (they use
# an actions/cache-backed bazel disk cache instead).
#
# Clients verify the self-signed server cert against the CA committed at
# infra/bazel-remote/ca.crt (`--tls_certificate=infra/bazel-remote/ca.crt`).
apiVersion: v1
kind: Namespace
metadata:
name: bazel-cache
labels:
kubernetes.io/metadata.name: bazel-cache
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazel-remote-data
namespace: bazel-cache
spec:
accessModes: [ReadWriteOnce]
storageClassName: local-path
resources:
requests:
storage: 100Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bazel-remote
namespace: bazel-cache
labels: { app: bazel-remote }
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels: { app: bazel-remote }
template:
metadata:
labels: { app: bazel-remote }
spec:
# kubelet's legacy service-link envs (BAZEL_REMOTE_PORT=tcp://...) collide
# with bazel-remote's own BAZEL_REMOTE_* config env prefix.
enableServiceLinks: false
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
containers:
- name: bazel-remote
image: buchgr/bazel-remote-cache:v2.6.2
imagePullPolicy: IfNotPresent
args:
- --max_size=90
- --dir=/data
- --grpc_address=:9092
- --http_address=:8080
- --tls_cert_file=/tls/tls.crt
- --tls_key_file=/tls/tls.key
- --htpasswd_file=/auth/htpasswd
- --allow_unauthenticated_reads
ports:
- { name: grpc, containerPort: 9092 }
- { name: http, containerPort: 8080 }
volumeMounts:
- { name: data, mountPath: /data }
- { name: tls, mountPath: /tls, readOnly: true }
- { name: auth, mountPath: /auth, readOnly: true }
# TLS is enabled, so /status is served over HTTPS on the http port.
# Kubelet probes skip certificate verification.
readinessProbe:
httpGet: { path: /status, port: http, scheme: HTTPS }
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
httpGet: { path: /status, port: http, scheme: HTTPS }
initialDelaySeconds: 15
periodSeconds: 20
resources:
requests: { cpu: "500m", memory: "2Gi" }
# Concurrent uploads of ~150MB addon artifacts spike RSS well past
# 4Gi (memcg OOM-killed the server mid-build); 10Gi gives headroom
# for a full 8-target push wave.
limits: { cpu: "4", memory: "10Gi" }
volumes:
- name: data
persistentVolumeClaim: { claimName: bazel-remote-data }
- name: tls
secret: { secretName: bazel-remote-tls }
- name: auth
secret: { secretName: bazel-remote-auth }
---
apiVersion: v1
kind: Service
metadata:
name: bazel-remote
namespace: bazel-cache
spec:
selector: { app: bazel-remote }
ports:
- { name: grpc, port: 9092, targetPort: grpc, protocol: TCP }
- { name: http, port: 8080, targetPort: http, protocol: TCP }
+30
View File
@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFJTCCAw2gAwIBAgIUPoZBmg9lfv5jlya7JGstFUYiri8wDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAwwPYmF6ZWwtcmVtb3RlLWNhMB4XDTI2MDcyNzA3NDMzM1oX
DTM2MDcyNDA3NDMzM1owGjEYMBYGA1UEAwwPYmF6ZWwtcmVtb3RlLWNhMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAn1iBTWdr/SOKFzRSNsFJCnf6JaDQ
tSQfO92oMrNSoHEjC0tFsB7D98GnCJySut+rlHCJy1OGzl1x3WdWxWkqNLdlfHLc
VrM3ATXpmtfSXvTOHP4o57awOR5W8gcwvKvs1xcMjKYyR0XcH9HN3Aq42n1e53uq
vGParr2EbMvTqjhMLlUpuxERHVYBUhUOspBS/r+MGJQOnJUzde3bhpYCMLseM0gq
V/Boav/4M/wf8ECYpHyr5qZGl4o8zlySOZpSb35+TKQcGIysyKQ/xVQWzjy0ay9w
TSHcI6p1y/Sfsw3ejd6g5e8F9YyLJd8Nr00vBJZ+/b/RCRwHvwGWw8BeZiq9iIZ2
+awNNE7NxchiCZQJCWSacPHMLsEJHCwUpbOtrojQqGoHZvpB0p4WVhxiBU2MYDwG
XPdpbRByrfuNIOrvE5FrdlYbIUYLBXQLuqygCMez+LRUn+ksxgWr70Vfe+Tm55Bv
94Zn9Dm81+zS5YJKHkBD0g3e2hAqG++hGc7RMrMZMDyOexdSJUjKzr7UwPsXhH6T
DfyCj4m9Mub33EeBRLxHrAXU+HzhS3ugx5p54xGijduGMCSpTWAIDWXZA3ktmFlt
DmkSkDWkmR0c8mUMSBQVkwihC3IJ1vji4mVsWXZSqWlmhIvTlKdQPOs+A8d6Q9Q0
Okr2G1IjkCP6DPsCAwEAAaNjMGEwHQYDVR0OBBYEFM1VckaC0O8tTYxHIcUWa1Vd
9QMSMB8GA1UdIwQYMBaAFM1VckaC0O8tTYxHIcUWa1Vd9QMSMA8GA1UdEwEB/wQF
MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQCKFcunEEYG
mMRFRxgvQmxFMwG7NcQmozR6gH1HUxPpgENTB2o0Vxtz4QcZBqPh00iwKiNGrfJB
Kf/YXCMP10nmlDg0N0B8td8+IiFyjeRCXT3OUMIQ0PTBs+OG5BzlIWRB/WHPpAMV
3xCCg1FhL8IYC5/qOjneO+D3rzNMlthy5CKIh1E6sOUifxuA1bdi4r3I/iR3i8c2
5wkKVfeXH0D/c7oOQcecvM70Y37Pi6uW1Enr2QrMHs9bJH1yRgwhwOfuLETi75Xm
kU5cKK3VRPHn+DxNauzdTRCXR0QMbLwJ1SdHSbhk32JvQb1dZ/CvINV9EUTroMEH
W3W8VI2c4JYnjEwFAaZxlAI/UIz0uoybuRwx1e+Q+cfmDzGAzb/SsZF1wWvcBkX0
DcAej3cY9p6JsSxzjhmk0DiJ+F0UZEvEaiozg2wwTxLufKbExptxT4qhpxKaywY+
WnW+M+jTQx18ljnbvBx1hENaeYEbk8VRS3M/nb6AbucnjK8zzw5XGDaA+yC9v7qq
jy1UGL/FbwU1JglMmw8lA4JBCRD2Xrz3N4GmuoX3KemLg4nEi8GERdvpGGypTH/V
UaumBZRrGwy0NeqWJlrcRjTGqL+VePYzNI4yKOgH5fgdvt1ENYah5ODTmqo0fmwu
bg5jTuxPpqe0OKG2ysdPSxAmrRLKM1Upcw==
-----END CERTIFICATE-----
@@ -0,0 +1,24 @@
# JSON-patch (kubectl --type=json --patch-file) appending the bazel-remote
# egress rule to the arc-runners `runner-egress-lockdown` NetworkPolicy.
# Mirrors the existing sccache/RustFS rule (service CIDR + namespaceSelector).
#
# NOT idempotent on its own - `add` on `/spec/egress/-` appends every time.
# setup.sh guards it with a jq presence check; apply by hand the same way:
#
# kubectl -n arc-runners get networkpolicy runner-egress-lockdown -o json \
# | jq -e '.spec.egress[].to[]? | select(.namespaceSelector.matchLabels["kubernetes.io/metadata.name"] == "bazel-cache")' >/dev/null \
# || kubectl -n arc-runners patch networkpolicy runner-egress-lockdown \
# --type=json --patch-file=infra/bazel-remote/runner-egress-patch.yaml
- op: add
path: /spec/egress/-
value:
# bazel-remote shared cache (gRPC) over the cluster network.
to:
- ipBlock:
cidr: 10.43.0.0/16
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: bazel-cache
ports:
- port: 9092
protocol: TCP
+157
View File
@@ -0,0 +1,157 @@
#!/usr/bin/env bash
# Idempotent bazel-remote cache bootstrap. Run ON the CI host (root), with the
# two YAML files from this directory next to it:
#
# ./setup.sh
#
# What it does (safe to re-run; every step is guarded or apply-based):
# 1. Generates a self-signed CA + server cert (SANs: in-cluster service DNS
# plus the host's private admin name) under $STATE_DIR.
# 2. Creates/updates secrets:
# bazel-cache/bazel-remote-tls - server cert + key (kubernetes.io/tls)
# bazel-cache/bazel-remote-auth - htpasswd (bcrypt, user `ci`)
# arc-runners/bazel-remote-ci - BAZEL_REMOTE_USER / BAZEL_REMOTE_PASSWORD
# 3. Applies bazel-remote.yaml (namespace, PVC, Deployment, ClusterIP service).
# 4. Appends the bazel-cache:9092 egress rule to the arc-runners
# runner-egress-lockdown NetworkPolicy (guarded, via runner-egress-patch.yaml).
# 5. Removes the retired public exposure if present (NodePort service +
# firewalld 30992/tcp): the cache is strictly cluster-internal; nothing
# about this infrastructure is reachable from — or committed to — the
# public repo beyond the CA certificate.
# 6. Prints the CA cert (commit it as infra/bazel-remote/ca.crt).
#
# Env knobs:
# KUBECONFIG kubeconfig path [/etc/rancher/k3s/k3s.yaml]
# STATE_DIR where CA/certs/password persist [/root/bazel-remote-cache]
# ADMIN_SAN optional extra DNS SAN for host-side debugging [can.internal]
# CERT_DAYS CA + server cert lifetime [3650]
set -euo pipefail
export KUBECONFIG="${KUBECONFIG:-/etc/rancher/k3s/k3s.yaml}"
STATE_DIR="${STATE_DIR:-/root/bazel-remote-cache}"
ADMIN_SAN="${ADMIN_SAN:-can.internal}"
CERT_DAYS="${CERT_DAYS:-3650}"
NS=bazel-cache
ARC_NS=arc-runners
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for f in bazel-remote.yaml runner-egress-patch.yaml; do
[ -f "$here/$f" ] || { echo "missing $here/$f (run from a checkout of infra/bazel-remote/)" >&2; exit 1; }
done
for bin in kubectl openssl jq; do
command -v "$bin" >/dev/null || { echo "missing required tool: $bin" >&2; exit 1; }
done
if ! command -v htpasswd >/dev/null; then
echo "==> htpasswd missing; installing httpd-tools/apache2-utils"
if command -v dnf >/dev/null; then dnf install -y httpd-tools
elif command -v apt-get >/dev/null; then apt-get update && apt-get install -y apache2-utils
else echo "cannot install htpasswd (no dnf/apt-get); install it manually" >&2; exit 1
fi
fi
mkdir -p "$STATE_DIR"
chmod 700 "$STATE_DIR"
cd "$STATE_DIR"
# --- 1. CA + server certificate -------------------------------------------
if [ ! -s ca.crt ] || [ ! -s ca.key ]; then
echo "==> [1/6] generating CA"
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days "$CERT_DAYS" \
-keyout ca.key -out ca.crt \
-subj "/CN=bazel-remote-ca" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
chmod 600 ca.key
else
echo "==> [1/6] reusing existing CA ($STATE_DIR/ca.crt)"
fi
if [ ! -s server.crt ] || [ ! -s server.key ]; then
echo "==> [1/6] generating server certificate"
openssl req -newkey rsa:4096 -sha256 -nodes \
-keyout server.key -out server.csr \
-subj "/CN=bazel-remote.${NS}.svc.cluster.local"
cat > server.ext <<EOF
basicConstraints=CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:bazel-remote.${NS}.svc.cluster.local,DNS:bazel-remote.${NS}.svc,DNS:${ADMIN_SAN}
EOF
openssl x509 -req -sha256 -days "$CERT_DAYS" \
-in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-extfile server.ext -out server.crt
rm -f server.csr server.ext
chmod 600 server.key
else
echo "==> [1/6] reusing existing server certificate"
fi
# --- 2. Credentials + secrets ----------------------------------------------
if [ ! -s ci-password ]; then
echo "==> [2/6] generating ci password"
openssl rand -base64 24 | tr -d '/+=' > ci-password
chmod 600 ci-password
else
echo "==> [2/6] reusing existing ci password"
fi
CI_PASSWORD="$(cat ci-password)"
htpasswd -Bbc htpasswd ci "$CI_PASSWORD" >/dev/null 2>&1
chmod 600 htpasswd
echo "==> [2/6] applying secrets"
kubectl create namespace "$NS" --dry-run=client -o yaml | kubectl apply -f -
kubectl -n "$NS" create secret tls bazel-remote-tls \
--cert=server.crt --key=server.key \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n "$NS" create secret generic bazel-remote-auth \
--from-file=htpasswd=htpasswd \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n "$ARC_NS" create secret generic bazel-remote-ci \
--from-literal=BAZEL_REMOTE_USER=ci \
--from-literal=BAZEL_REMOTE_PASSWORD="$CI_PASSWORD" \
--dry-run=client -o yaml | kubectl apply -f -
# --- 3. bazel-remote itself -------------------------------------------------
echo "==> [3/6] applying bazel-remote.yaml"
kubectl apply -f "$here/bazel-remote.yaml"
# --- 4. Runner egress: allow bazel-cache:9092 -------------------------------
echo "==> [4/6] patching runner-egress-lockdown (bazel-cache:9092)"
if kubectl -n "$ARC_NS" get networkpolicy runner-egress-lockdown -o json \
| jq -e '.spec.egress[].to[]? | select(.namespaceSelector.matchLabels["kubernetes.io/metadata.name"] == "bazel-cache")' >/dev/null; then
echo " egress rule already present; skipping"
else
kubectl -n "$ARC_NS" patch networkpolicy runner-egress-lockdown \
--type=json --patch-file="$here/runner-egress-patch.yaml"
fi
# --- 5. Retire any previous public exposure -----------------------------------
echo "==> [5/6] ensuring the cache is cluster-internal only"
if kubectl -n "$NS" get service bazel-remote-public >/dev/null 2>&1; then
kubectl -n "$NS" delete service bazel-remote-public
echo " removed retired NodePort service bazel-remote-public"
fi
if firewall-cmd --permanent --query-port=30992/tcp >/dev/null 2>&1; then
firewall-cmd --permanent --remove-port=30992/tcp
firewall-cmd --reload
echo " closed retired firewalld port 30992/tcp"
fi
# --- 6. Operator hand-off -----------------------------------------------------
echo "==> [6/6] done. Manual follow-ups:"
echo
echo "1. Commit the CA cert into the repo as infra/bazel-remote/ca.crt"
echo " (this script cannot commit; the cert is public, only ca.key is secret):"
echo " --- $STATE_DIR/ca.crt ---"
cat ca.crt
echo " --- end ca.crt ---"
echo
echo "2. Runner pods need 'envFrom: [{secretRef: {name: bazel-remote-ci}}]'."
echo " infra/reload-runner.sh now inserts this into the ARC values file on the"
echo " next reload; to wire it without an image reload, add under"
echo " template.spec.containers[0].envFrom in /root/arc-omp-values.yaml:"
echo " - secretRef:"
echo " name: bazel-remote-ci"
echo " then re-run the helm upgrade from infra/docs/04-arc-and-caching.md §3."
echo
echo "Endpoint: grpcs://bazel-remote.${NS}.svc.cluster.local:9092 (in-cluster only)"

Some files were not shown because too many files have changed in this diff Show More