Skip to content

feat: build static linux x64 binaries with musl#2903

Open
wavezhang wants to merge 2 commits into
Hmbown:mainfrom
wavezhang:feat/static-linux-binaries
Open

feat: build static linux x64 binaries with musl#2903
wavezhang wants to merge 2 commits into
Hmbown:mainfrom
wavezhang:feat/static-linux-binaries

Conversation

@wavezhang

@wavezhang wavezhang commented Jun 8, 2026

Copy link
Copy Markdown

Summary

Build fully-static Linux x64 binaries using the musl target, eliminating runtime dependencies on glibc and libdbus.

Changes

.cnb.yml — tag_push workflow

  • Replace rust:1.88-bookworm + libdbus-1-dev with musl-tools + x86_64-unknown-linux-musl target
  • Split the single build stage into two: install musl toolchain and build static assets
  • cargo build --release --locked --target x86_64-unknown-linux-musl
  • Copy built binaries from target/x86_64-unknown-linux-musl/release/

crates/secrets/Cargo.toml

  • Add tls-native feature to the Linux keyring dependency for musl compatibility (avoids dbus-linked secret-service backend)

Motivation

Statically-linked binaries simplify deployment on minimal / distroless hosts where glibc and dbus shared libraries may not be present. The musl target produces truly self-contained executables with no external SO dependencies.

Testing

  • cargo build --release --locked --target x86_64-unknown-linux-musl compiles successfully
  • Resulting binary confirms not a dynamic executable or shows only musl in ldd
  • CNB tag_push pipeline configuration validated

Greptile Summary

This PR updates the CNB tag_push pipeline to produce fully-static Linux x64 binaries by switching the cargo build target to x86_64-unknown-linux-musl. The CI script correctly installs musl-tools, adds the Rust musl target, adjusts the build command, and updates the binary copy path.

  • The cargo build --target x86_64-unknown-linux-musl step will fail at link time because crates/secrets/Cargo.toml still carries the linux-native-sync-persistent feature for the keyring dependency, which transitively pulls in dbus / libdbus-sys — a glibc-linked C library that cannot be statically linked into a musl binary. libdbus-1-dev was intentionally removed from the install list, so pkg-config will report a missing dbus-1 error immediately. The PR description promises a matching Cargo.toml change but it was not committed.
  • libssl-dev is installed in the new script despite there being no OpenSSL dependency in the workspace (reqwest uses the rustls feature and openssl is absent from Cargo.lock); it can be dropped.

Confidence Score: 3/5

The pipeline change is incomplete — the build will fail on every tag push until the missing Cargo.toml fix lands.

The CI script itself is well-structured and the musl toolchain wiring is correct, but the companion change to crates/secrets/Cargo.toml (removing the dbus-backed keyring feature) was not committed. As-is, every tag-push build will error out when libdbus-sys cannot find libdbus-1 via pkg-config, because the package is no longer installed. The tag_push release pipeline will be completely broken until the Cargo.toml fix is included.

crates/secrets/Cargo.toml — the linux-native-sync-persistent feature must be replaced with a dbus-free alternative before this pipeline change can succeed.

Important Files Changed

Filename Overview
.cnb.yml Switches tag_push pipeline to build musl static binaries; the CI script is correctly structured, but the accompanying Cargo.toml change needed to eliminate the dbus dependency is missing, which will cause the build to fail at link time.

Sequence Diagram

sequenceDiagram
    participant CNB as CNB tag_push
    participant Docker as rust:1.88-bookworm
    participant Cargo as cargo build
    participant Keyring as codewhale-secrets
    participant DBus as dbus / libdbus-sys

    CNB->>Docker: trigger on git tag push
    Docker->>Docker: apt-get install musl-tools libssl-dev
    Docker->>Docker: rustup target add x86_64-unknown-linux-musl
    Docker->>Cargo: cargo build --target x86_64-unknown-linux-musl
    Cargo->>Keyring: compile linux-native-sync-persistent feature
    Keyring->>DBus: pkg-config lookup for dbus-1
    DBus-->>Cargo: FAIL — libdbus-1-dev not installed
    Note over Cargo,DBus: Build halts here without Cargo.toml fix
    Cargo-->>Docker: strip + sha256sum + upload (unreachable)
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Reviews (1): Last reviewed commit: "fix: address review comments on static c..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

- Add x86_64-unknown-linux-musl target to CNB tag_push workflow
- Install musl-tools instead of libdbus-1-dev in release pipeline
- Build codewhale-cli and codewhale-tui with musl target for static binaries
- Copy built artifacts from musl target directory
- Add tls-native feature to keyring crate for musl compatibility
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Thanks @wavezhang for taking the time to contribute.

This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in .github/APPROVED_CONTRIBUTORS will be closed automatically.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant PR access by commenting /lgtm on a pull request.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request attempts to transition the Linux x64 release builds to static binaries using the musl toolchain and adds a new feature to the keyring dependency. However, two critical issues were identified in the review: first, splitting the toolchain installation and the build process into separate stages in .cnb.yml will cause build failures because CNB stages run in isolated containers and do not persist state; second, the tls-native feature added to the keyring dependency in crates/secrets/Cargo.toml does not exist and will cause compilation errors. Both issues need to be resolved by combining the CI stages and removing the invalid feature.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread .cnb.yml Outdated
Comment on lines +118 to +132
- name: install musl toolchain
script: |
set -eu

apt-get update
apt-get install -y git libdbus-1-dev nodejs pkg-config
apt-get install -y git musl-tools nodejs pkg-config
rustup target add x86_64-unknown-linux-musl

- name: build linux x64 release assets (static)
script: |
set -eu

./scripts/release/check-versions.sh
cargo build --release --locked -p codewhale-cli -p codewhale-tui
cargo build --release --locked \
--target x86_64-unknown-linux-musl \
-p codewhale-cli -p codewhale-tui

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.

high

In CNB (Coding CI), each stage in a workflow runs in a separate, clean container instance. The root filesystem of the container (including packages installed via apt-get and targets added via rustup) does not persist between stages. Splitting the build into install musl toolchain and build linux x64 release assets (static) stages will cause the build stage to fail because musl-tools and the x86_64-unknown-linux-musl target will not be present in the second stage's container.

To fix this, combine the installation and build steps back into a single stage.

        - name: build linux x64 release assets (static)
          script: |
            set -eu
            apt-get update
            apt-get install -y git musl-tools nodejs pkg-config
            rustup target add x86_64-unknown-linux-musl

            ./scripts/release/check-versions.sh
            cargo build --release --locked \
              --target x86_64-unknown-linux-musl \
              -p codewhale-cli -p codewhale-tui

Comment thread crates/secrets/Cargo.toml Outdated

[target.'cfg(target_os = "linux")'.dependencies]
keyring = { version = "3", features = ["linux-native-sync-persistent", "crypto-rust"] }
keyring = { version = "3", features = ["linux-native-sync-persistent", "crypto-rust", "tls-native"] }

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.

high

The keyring crate (v3) does not have a tls-native feature. Specifying a non-existent feature in Cargo.toml will cause Cargo to fail to compile with a feature resolution error.

To avoid the DBus-linked secret-service backend, enabling linux-native-sync-persistent and crypto-rust is already sufficient as it uses the Linux kernel keyring (keyctl) instead of DBus. Please remove the invalid tls-native feature.

Suggested change
keyring = { version = "3", features = ["linux-native-sync-persistent", "crypto-rust", "tls-native"] }
keyring = { version = "3", features = ["linux-native-sync-persistent", "crypto-rust"] }

@wavezhang wavezhang closed this Jun 8, 2026
@wavezhang wavezhang reopened this Jun 8, 2026
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Thanks @wavezhang for taking the time to contribute.

This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in .github/APPROVED_CONTRIBUTORS will be closed automatically.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant PR access by commenting /lgtm on a pull request.

- Merge CNB tag_push stages (toolchain install + build) into single stage\n  since CNB stages run in isolated containers without persistent state\n- Remove non-existent 'tls-native' feature from keyring dependency\n\nFixes feedback in: Hmbown#2903
Comment thread .cnb.yml
Comment on lines +128 to +130
cargo build --release --locked \
--target x86_64-unknown-linux-musl \
-p codewhale-cli -p codewhale-tui

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.

P1 Missing Cargo.toml change breaks the musl build

crates/secrets/Cargo.toml still declares ["linux-native-sync-persistent", "crypto-rust"] for the Linux keyring dependency. The linux-native-sync-persistent feature pulls in dbus-secret-servicedbuslibdbus-sys, which builds a C extension and links against libdbus-1. Since libdbus-1-dev is no longer installed in this pipeline and the resulting binary must be fully static musl, cargo build --target x86_64-unknown-linux-musl will fail at the link stage with an unresolved dbus-1 pkg-config error. The PR description mentions adding tls-native to crates/secrets/Cargo.toml to avoid the dbus backend, but that change is absent from the diff — only .cnb.yml was committed.

Fix in Codex Fix in Claude Code Fix in Cursor

Comment thread .cnb.yml
# install musl toolchain
apt-get update
apt-get install -y git libdbus-1-dev nodejs pkg-config
apt-get install -y git musl-tools nodejs pkg-config libssl-dev

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 libssl-dev installs the Debian-packaged glibc-linked OpenSSL headers and static libraries, but there is no OpenSSL dependency in the workspace — reqwest is already configured with the rustls feature and openssl does not appear in Cargo.lock. The package is unnecessary here and would be misleading if someone later tries to reason about why it is present.

Suggested change
apt-get install -y git musl-tools nodejs pkg-config libssl-dev
apt-get install -y git musl-tools nodejs pkg-config

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Codex Fix in Claude Code Fix in Cursor

@Hmbown

Hmbown commented Jun 10, 2026

Copy link
Copy Markdown
Owner

@wavezhang — the static musl x64 binaries are a welcome addition to the release matrix. The PR is currently conflicting with main; could you rebase? Should be a small CI-only conflict. Once green we can take it.

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