Skip to content

fix: statically link prebuilt Linux binaries against musl#321

Open
mvanhorn wants to merge 1 commit into
modem-dev:mainfrom
mvanhorn:fix/300-statically-link-prebuilt-linux-binaries-against-mu
Open

fix: statically link prebuilt Linux binaries against musl#321
mvanhorn wants to merge 1 commit into
modem-dev:mainfrom
mvanhorn:fix/300-statically-link-prebuilt-linux-binaries-against-mu

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

Summary

Prebuilt Linux binaries from CI link against glibc, so users on Alpine/musl systems can't run them. Switch to a musl static-link target.

Why this matters

This is the packaging fix issue #300 explicitly asks for. The blocker is purely the CI release workflow's link target; the source code is fully portable.

Changes

  • .github/workflows/release.yml - add a musl static-link target alongside the existing glibc target for Linux releases.
  • README install snippet updated to mention musl compatibility.

Fixes #300

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 16, 2026

Greptile Summary

This PR fixes Alpine/musl compatibility for prebuilt Linux binaries by switching the Bun compile target to bun-linux-x64-musl and bun-linux-arm64-musl for the two Linux CI matrix entries. The build script is refactored to conditionally pass --target based on the HUNK_TARGET_TRIPLE env var, leaving macOS and local builds untouched.

  • release-prebuilt-npm.yml: adds target_triple to Linux matrix entries and injects the value as HUNK_TARGET_TRIPLE into the build step; macOS entries receive an empty string which the script correctly ignores.
  • build-bin.sh: replaces the hard-coded bun build --compile invocation with a dynamic args array that appends --target only when HUNK_TARGET_TRIPLE is non-empty.

Confidence Score: 4/5

Safe to merge; the change is narrow, the bash guard correctly skips the target flag for macOS and local builds, and musl-static binaries run on glibc Linux so the existing smoke test on ubuntu-latest remains valid.

The logic is correct end-to-end: Linux entries get a musl target, macOS entries fall through with no target, and the build script's non-empty guard handles the empty-string case that GitHub Actions injects for undefined matrix properties. The one thing worth a follow-up is that HUNK_TARGET_TRIPLE is unconditionally set on every matrix entry including macOS, which works today but is a latent footgun if future steps consume that var without the same guard.

No files require special attention; both changed files are straightforward and low risk.

Important Files Changed

Filename Overview
.github/workflows/release-prebuilt-npm.yml Adds target_triple matrix variables for both Linux entries and injects them as HUNK_TARGET_TRIPLE into the build step; macOS entries leave the property undefined, which GitHub Actions resolves to an empty string — handled correctly by the build script's -n guard.
scripts/build-bin.sh Refactors the hard-coded bun build invocation into a dynamic args array; correctly appends --target only when HUNK_TARGET_TRIPLE is non-empty, leaving macOS/local builds unaffected.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Matrix Entry] -->|has target_triple?| B{target_triple defined?}
    B -->|Yes: Linux x64 / ARM64| C[Set HUNK_TARGET_TRIPLE=bun-linux-*-musl]
    B -->|No: macOS x64 / ARM64| D[Set HUNK_TARGET_TRIPLE=empty string]
    C --> E[build-bin.sh]
    D --> E
    E --> F{HUNK_TARGET_TRIPLE non-empty?}
    F -->|Yes| G[bun build --compile --target bun-linux-*-musl src/main.tsx]
    F -->|No| H[bun build --compile src/main.tsx]
    G --> I[Musl-static binary\nworks on Alpine + glibc Linux]
    H --> J[Native binary\nmacOS / local dev]
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
.github/workflows/release-prebuilt-npm.yml:57-62
**`HUNK_TARGET_TRIPLE` always injected for every matrix entry**

The `env: HUNK_TARGET_TRIPLE: ${{ matrix.target_triple }}` block is attached unconditionally, so macOS runners receive `HUNK_TARGET_TRIPLE=""` (GitHub Actions resolves undefined matrix properties to empty string). The build script's `[[ -n "${HUNK_TARGET_TRIPLE:-}" ]]` guard makes this safe today, but any future consumer of that env var that doesn't apply the same guard will silently inherit an empty target. Consider making the env injection conditional with an `if: matrix.target_triple != ''` step-level condition, or move the env var into the matrix entries that need it.

Reviews (1): Last reviewed commit: "fix: statically link prebuilt Linux bina..." | Re-trigger Greptile

Comment on lines 57 to 62
- name: Build host artifact
env:
HUNK_TARGET_TRIPLE: ${{ matrix.target_triple }}
run: |
bun run build:bin
bun run ./scripts/build-prebuilt-artifact.ts --expect-package "${{ matrix.package_name }}"
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.

P2 HUNK_TARGET_TRIPLE always injected for every matrix entry

The env: HUNK_TARGET_TRIPLE: ${{ matrix.target_triple }} block is attached unconditionally, so macOS runners receive HUNK_TARGET_TRIPLE="" (GitHub Actions resolves undefined matrix properties to empty string). The build script's [[ -n "${HUNK_TARGET_TRIPLE:-}" ]] guard makes this safe today, but any future consumer of that env var that doesn't apply the same guard will silently inherit an empty target. Consider making the env injection conditional with an if: matrix.target_triple != '' step-level condition, or move the env var into the matrix entries that need it.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/release-prebuilt-npm.yml
Line: 57-62

Comment:
**`HUNK_TARGET_TRIPLE` always injected for every matrix entry**

The `env: HUNK_TARGET_TRIPLE: ${{ matrix.target_triple }}` block is attached unconditionally, so macOS runners receive `HUNK_TARGET_TRIPLE=""` (GitHub Actions resolves undefined matrix properties to empty string). The build script's `[[ -n "${HUNK_TARGET_TRIPLE:-}" ]]` guard makes this safe today, but any future consumer of that env var that doesn't apply the same guard will silently inherit an empty target. Consider making the env injection conditional with an `if: matrix.target_triple != ''` step-level condition, or move the env var into the matrix entries that need it.

How can I resolve this? If you propose a fix, please make it concise.

@mvanhorn mvanhorn force-pushed the fix/300-statically-link-prebuilt-linux-binaries-against-mu branch from 76c7ce0 to 5b3d6bf Compare May 16, 2026 21:09
@mvanhorn
Copy link
Copy Markdown
Contributor Author

Rebased onto main (5b3d6bf). The conflict came from the build-bin.sh -> build-bin.ts rewrite in #285 and the new Windows matrix entry from the same PR. The musl-target conditional now lives in scripts/build-bin.ts (gated on process.env.HUNK_TARGET_TRIPLE) and the target_triple matrix entries are restricted to the two Linux runners.

On the Greptile P2 ("HUNK_TARGET_TRIPLE always injected for every matrix entry"): the if (targetTriple) guard in build-bin.ts already skips --target when the matrix entry doesn't set one, so macOS and Windows entries receive an empty string and produce a native build, which is the intended behavior. The two suggested mitigations would either skip the entire Build host artifact step on non-Linux (breaking those builds) or require splitting it into two near-duplicate steps to avoid passing through an empty env var that's already guarded one level down. Happy to revisit if a future consumer of HUNK_TARGET_TRIPLE lands without the same guard.

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.

Pre-built Linux binaries should statically link against musl

1 participant