Skip to content

fix(release): ship static musl Linux binaries - #86

Merged
wahyuakbarwibowo merged 1 commit into
mainfrom
fix/linux-musl-release
Sep 18, 2026
Merged

wahyuakbarwibowo merged 1 commit into
mainfrom
fix/linux-musl-release

Conversation

@badrus123

@badrus123 badrus123 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Problem

Linux release binaries are built on ubuntu-24.04 against
x86_64-unknown-linux-gnu (.github/workflows/release.yml:24,75), so they
link against GLIBC_2.39 and refuse to start on anything older:

/usr/local/bin/forgeguard: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found (required by /usr/local/bin/forgeguard)

That breaks Ubuntu 22.04 (glibc 2.35), Debian 12 (2.36), and most CI base
images. Release v0.17.0 ships only gnu builds — there is no musl asset to
fall back to.

Found while running the DeepSWE A/B harness against v0.17.0: every
treatment trial failed during Docker image build, at the last step, because
install.sh downloaded fine and forgeguard --version then aborted.

Change

Both Linux matrix entries now target *-unknown-linux-musl and install
musl-tools for the bundled C dependencies (rusqlite with bundled,
zstd). The binary links statically, so one artifact runs on every distro,
glibc or musl.

Asset names are unchanged, so install.sh, npm/scripts/install.js, and the
Homebrew formula template need no edit.

Verification

Built the workspace for musl in rust:alpine with musl-dev installed, then
ran the result on the distro the current release fails on.

Build, with rusqlite bundled and zstd linking cleanly:

Compiling forgeguard v0.17.0 (/w/crates/forgeguard-cli)
Finished `release` profile [optimized] target(s) in 5m 04s

The artifact is static:

forgeguard: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV),
statically linked, BuildID[sha1]=dee34262..., stripped

Running it on Ubuntu 22.04:

ldd (Ubuntu GLIBC 2.35-0ubuntu3.14) 2.35
--- run:
forgeguard 0.17.0

Checked on aarch64-unknown-linux-musl, since that builds natively on the
machine at hand. x86_64-unknown-linux-musl uses the same toolchain path and
the same two C dependencies, but has not been built here — the x86_64 build
job on a tag is its first real exercise.

Why musl does not regress glibc users

A static musl binary carries its own libc and never looks for libc.so.6, so
glibc distros keep working — the Ubuntu 22.04 run above is that case. The two
usual static-linking pitfalls do not apply here: a grep over Cargo.toml and
every crates/*/Cargo.toml for reqwest|ureq|hyper|libloading|dlopen|getaddrinfo
returns nothing, so there is no DNS/NSS path and no dynamic library loading.

Remaining trade-off: musl's allocator is slower than glibc's under heavy
multithreaded allocation. No rayon or custom allocator appears in any
manifest, so the exposure is small. If indexing later measures slow, adding
mimalloc as the global allocator addresses it without changing targets.

Note for reviewers

release.yml only runs on a tag or workflow_dispatch, so the checks on this
PR exercise ci.yml and do not build either musl target. The evidence above is
from a local container build; the x86_64 target is first proven when a tag is
cut.

The Linux release binaries were built on `ubuntu-24.04` against
`x86_64-unknown-linux-gnu`, so they link against GLIBC_2.39 and refuse to
start anywhere older:

    /usr/local/bin/forgeguard: /lib/x86_64-linux-gnu/libc.so.6:
    version `GLIBC_2.39' not found (required by /usr/local/bin/forgeguard)

That covers Ubuntu 22.04, Debian 12, and most CI base images. It was found
while running the DeepSWE A/B harness: every treatment trial died during
image build, because `install.sh` succeeded and `forgeguard --version`
then failed.

Both Linux targets now build `*-unknown-linux-musl` and link statically, so
one binary runs on every distro, glibc or not. Asset names are unchanged, so
`install.sh`, `npm/scripts/install.js`, and the Homebrew formula template
need no change.

`reqwest`, `ureq`, `hyper`, `libloading`, and `dlopen` are absent from every
manifest, so neither static NSS resolution nor `dlopen` applies here.
@badrus123
badrus123 requested a review from a team September 17, 2026 20:37
@suiflex-bot suiflex-bot Bot added commit: fix maintainer area: ci GitHub Actions workflows and templates labels Sep 17, 2026

@wahyuakbarwibowo wahyuakbarwibowo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

install for linux yeah

@wahyuakbarwibowo
wahyuakbarwibowo merged commit d7a17e7 into main Sep 18, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci GitHub Actions workflows and templates commit: fix maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants