Skip to content

ci: build multi-platform Rust binaries in the deploy job - #462

Merged
tinder-maxwellelliott merged 6 commits into
masterfrom
maxwelle/deploy-rust-binaries-ci
Aug 15, 2026
Merged

ci: build multi-platform Rust binaries in the deploy job#462
tinder-maxwellelliott merged 6 commits into
masterfrom
maxwelle/deploy-rust-binaries-ci

Conversation

@tinder-maxwellelliott

Copy link
Copy Markdown
Collaborator

Summary

  • Extend the CI deploy job into a Linux/macOS/Windows matrix that builds and uploads the same host-native Rust CLI assets used by GitHub Releases
  • Keep JAR + release.tar.gz artifacts on Ubuntu only

Test plan

  • Confirm the deploy matrix runs on ubuntu/macOS/windows
  • Verify workflow artifacts include:
    • bazel-diff_deploy.jar
    • release.tar.gz
    • bazel-diff-rust-linux-amd64
    • bazel-diff-rust-macos-arm64
    • bazel-diff-rust-windows-amd64.exe
  • Spot-check downloaded binaries run --help on their platforms

Made with Cursor

Upload linux/macOS/Windows host-native CLI artifacts alongside the existing JAR and source archive.

Co-authored-by: Cursor <cursoragent@cursor.com>
@csmoe

csmoe commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

The release build of rust should add config like:

[profile.release]
codegen-units = 1
lto = fat

Should improve the perf more(maybe not, but they're common release parameters in rust commmunity)

tinder-maxwellelliott and others added 5 commits August 15, 2026 08:47
The deploy and release jobs built //:bazel-diff-rust and then reproduced
Bazel's own knowledge in shell: which path rules_rust writes the binary to
(bazel-bin/src/bazel-diff vs .exe), what to rename it to per runner, and which
C++ flags a release build needs. The rename in particular was unchecked -- a
macOS runner would happily publish a binary named "linux-amd64".

Move all of that into Bazel. //release:bazel-diff-rust selects on
@platforms//os and @platforms//cpu to name its output for the platform it is
built for, so the workflows now run one `bazelisk build ... --config=release`
and upload what lands in bazel-bin/release/ -- no cp, no path branching, and
`if-no-files-found: error` turns a name mismatch into a failed job. The build
flags move to a `release` config in .bazelrc, which also drops the
`--cxxopt=-std=c++17` the Windows leg was passing to MSVC (the platform
configs in .bazelrc already send /std:c++17 there).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rules_rust does not read Cargo profiles, so `-c opt` alone gave the published
binaries opt-level=3/debuginfo=0/strip=debuginfo -- no LTO and a full symbol
table -- while Cargo.toml has declared `[profile.release] lto = "thin",
strip = true` all along. Anyone building with cargo got a better binary than
the one we ship.

Add both to --config=release. On macOS arm64 the artifact drops from 6,344,496
to 5,304,656 bytes (-16.4%); //:rust_tests passes under the config.

-Cstrip=symbols goes through extra_rustc_flags rather than the toolchain's
strip_level so it applies to release builds only, and rules_rust appends it
after the toolchain's own -Cstrip, where last-wins.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Windows deploy leg failed with "invalid package name '/release'": Git
bash's MSYS runtime treats an argument starting with //release as a UNC-ish
Windows path and rewrites it to /release before Bazel ever sees it. The label
this replaced, //:bazel-diff-rust, has no path-like segment after the slashes,
so it was never converted -- the mangling only showed up once the target moved
into a package.

MSYS2_ARG_CONV_EXCL='//' excludes exactly the label arguments from conversion
and leaves the rest of the command line alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Windows leg has never built the Rust binary -- it failed the same way on
this PR's first commit, before the //release target existed, so the label fix
only got far enough to expose it. link.exe is MAX_PATH-bound at 260, and under
Bazel's default Windows output root the Rust stdlib rlib

  C:\users\runneradmin\_bazel_runneradmin\<hash>\execroot\_main\bazel-out\
  x64_windows-opt-exec-<hash>\bin\external\rules_rust++rust+rw-<n>_tools\
  rust_toolchain\lib\rustlib\x86_64-pc-windows-msvc\lib\
  librustc_std_workspace_alloc-e9a7af2889795557.rlib

comes to 263 characters, so the link dies with LNK1181. Every rlib opened
before it has a shorter file name and fits; that one is the first over.

--output_user_root=C:/b shortens the prefix by 35 characters. It has to be a
startup flag, so it rides in a matrix entry rather than --config=release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tinder-maxwellelliott
tinder-maxwellelliott merged commit 30d605d into master Aug 15, 2026
25 of 26 checks passed
@tinder-maxwellelliott
tinder-maxwellelliott deleted the maxwelle/deploy-rust-binaries-ci branch August 15, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants