fix(release): static musl Linux binaries, so the installer runs on Debian 12 (D158) #33

Merged
whitlocktech merged 1 commits from ci/static-musl-installer into main 2026-09-26 14:53:22 +00:00
Member

Found by the Rust phase 18 walk (§34.3 step 7). The org lead chose static musl (D158). edge was deleted at the #32 cutover, so this goes straight into main.

The defect

The released Linux installer is linked against the release runner's glibc and needs glibc 2.39:

./runicgateway-installer-linux-x86_64: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found

It fails on the first line on Debian 12 (2.36) and Ubuntu 22.04 (2.35), which are the hosts an operator is most likely to have. v0.2.0 was the same, so this predates phase 18. Step 7 had to be walked on Debian 13. The sidecar it installs has been static since D149.

The change (release.yml only)

  • LINUX_TARGET and ARM64_TARGET are now x86_64-unknown-linux-musl and aarch64-unknown-linux-musl.
  • Both are built with cargo zigbuild. ring (under ureq's rustls) compiles C, so each target needs a musl-targeting C compiler. Ubuntu packages one for x86_64 only; zig covers both, installed from PyPI (ziglang, cargo-zigbuild). The gcc-aarch64-linux-gnu and libc6-dev-arm64-cross packages are no longer needed.
  • The package step refuses a Linux binary that file doesn't call statically linked, so a regression fails the release instead of an operator's first run.
  • Windows is unchanged (MinGW).

Proof

In rust:1-slim-bookworm, with the same commands: both targets build, file reports "ELF 64-bit … x86-64 … statically linked" and "… ARM aarch64 … statically linked", and the x86_64 binary runs. PR checks don't run the release build, so the release run on merge is the first CI proof. If it fails, it fails before tagging.

Merging releases v0.3.1. I'll then re-walk step 7 on the Debian 12 rig with the downloaded binary.

  • AI-assisted: Claude Code (Claude Opus 5.5)

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

Found by the Rust phase 18 walk (§34.3 step 7). The org lead chose static musl (**D158**). `edge` was deleted at the #32 cutover, so this goes straight into `main`. ## The defect The released Linux installer is linked against the release runner's glibc and needs **glibc 2.39**: ``` ./runicgateway-installer-linux-x86_64: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found ``` It fails on the first line on **Debian 12** (2.36) and **Ubuntu 22.04** (2.35), which are the hosts an operator is most likely to have. v0.2.0 was the same, so this predates phase 18. Step 7 had to be walked on Debian 13. The sidecar it installs has been static since D149. ## The change (release.yml only) - `LINUX_TARGET` and `ARM64_TARGET` are now `x86_64-unknown-linux-musl` and `aarch64-unknown-linux-musl`. - Both are built with **`cargo zigbuild`**. `ring` (under ureq's rustls) compiles C, so each target needs a musl-targeting C compiler. Ubuntu packages one for x86_64 only; zig covers both, installed from PyPI (`ziglang`, `cargo-zigbuild`). The `gcc-aarch64-linux-gnu` and `libc6-dev-arm64-cross` packages are no longer needed. - The package step **refuses a Linux binary that `file` doesn't call statically linked**, so a regression fails the release instead of an operator's first run. - Windows is unchanged (MinGW). ## Proof In `rust:1-slim-bookworm`, with the same commands: both targets build, `file` reports *"ELF 64-bit … x86-64 … statically linked"* and *"… ARM aarch64 … statically linked"*, and the x86_64 binary runs. PR checks don't run the release build, so the release run on merge is the first CI proof. If it fails, it fails before tagging. Merging releases **v0.3.1**. I'll then re-walk step 7 on the Debian 12 rig with the downloaded binary. - [x] AI-assisted: Claude Code (Claude Opus 5.5) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-26 09:47:26 +00:00
fix(release): static musl Linux binaries, so the installer runs on Debian 12 (D158)
All checks were successful
PR Checks / rust-gates (pull_request) Successful in 1m1s
9f43260ee7
The Linux installers were linked against the release runner's glibc and
needed glibc 2.39: v0.3.0 (and v0.2.0) failed on the first line on
Debian 12 (2.36) and Ubuntu 22.04 (2.35) with "GLIBC_2.39 not found" --
found by the Rust phase 18 walk, step 7. Both Linux targets are now
x86_64/aarch64-unknown-linux-musl, built with cargo-zigbuild (zig is the
one C compiler `ring` needs for both musl targets; Ubuntu packages a
musl gcc for x86_64 only), and the package step refuses a Linux binary
that `file` does not call statically linked. Windows is unchanged.

Tried in rust:1-slim-bookworm: both targets build, both are "statically
linked", and the x86_64 binary runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech approved these changes 2026-09-26 14:53:07 +00:00
whitlocktech merged commit dc3d360cf2 into main 2026-09-26 14:53:22 +00:00
whitlocktech deleted branch ci/static-musl-installer 2026-09-26 14:53:23 +00:00
Sign in to join this conversation.
No description provided.