From 21f25610cfc8c980b61cdcb9b42263e41657033c Mon Sep 17 00:00:00 2001 From: wavezhang Date: Mon, 8 Jun 2026 22:59:27 +0800 Subject: [PATCH 1/2] feat: build static linux x64 binaries with musl Build codewhale-cli and codewhale-tui with x86_64-unknown-linux-musl target in the CNB tag_push workflow to produce fully static Linux x64 binaries. Install musl-tools instead of libdbus-1-dev; keep toolchain install and build in a single stage since CNB stages run in isolated containers without persistent state. Co-Authored-By: Claude Opus 4.7 --- .cnb.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.cnb.yml b/.cnb.yml index 1a9abfdf4..af204c8a8 100644 --- a/.cnb.yml +++ b/.cnb.yml @@ -113,20 +113,24 @@ $: - docker: image: rust:1.88-bookworm stages: - - name: build linux x64 release assets + - name: build linux x64 release assets (static) 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 ./scripts/release/check-versions.sh ./scripts/release/check-ohos-deps.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 mkdir -p target/cnb-release - cp target/release/codewhale target/cnb-release/codewhale-linux-x64 - cp target/release/codewhale-tui target/cnb-release/codewhale-tui-linux-x64 + BIN_DIR="target/x86_64-unknown-linux-musl/release" + cp "$BIN_DIR/codewhale" target/cnb-release/codewhale-linux-x64 + cp "$BIN_DIR/codewhale-tui" target/cnb-release/codewhale-tui-linux-x64 strip \ target/cnb-release/codewhale-linux-x64 \ target/cnb-release/codewhale-tui-linux-x64 \ From 3cc28ba64d36a91b19e4d43f7cf2ef6f1ae56079 Mon Sep 17 00:00:00 2001 From: wavezhang Date: Thu, 11 Jun 2026 14:11:27 +0800 Subject: [PATCH 2/2] fix: gate keyring behind not(target_env = "musl") for static builds When targeting x86_64-unknown-linux-musl, the keyring crate's linux-native-sync-persistent feature pulls in libdbus-sys which cannot link against musl. Gate the OS keyring dependency behind not(target_env = "musl") so musl builds fall back to the file-backed secret store instead. Co-Authored-By: Claude Opus 4.7 --- crates/secrets/Cargo.toml | 2 +- crates/secrets/src/lib.rs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/secrets/Cargo.toml b/crates/secrets/Cargo.toml index 7db781eb2..58c804fb7 100644 --- a/crates/secrets/Cargo.toml +++ b/crates/secrets/Cargo.toml @@ -19,7 +19,7 @@ keyring = { version = "3", features = ["apple-native"] } [target.'cfg(target_os = "windows")'.dependencies] keyring = { version = "3", features = ["windows-native"] } -[target.'cfg(all(target_os = "linux", not(target_env = "ohos")))'.dependencies] +[target.'cfg(all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")))'.dependencies] keyring = { version = "3", features = ["linux-native-sync-persistent", "crypto-rust"] } [dev-dependencies] diff --git a/crates/secrets/src/lib.rs b/crates/secrets/src/lib.rs index 53e4012ad..81c7047e1 100644 --- a/crates/secrets/src/lib.rs +++ b/crates/secrets/src/lib.rs @@ -127,7 +127,7 @@ impl DefaultKeyringStore { #[cfg(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) ))] { // `Entry::new` is enough to validate the native macOS/Windows @@ -156,7 +156,7 @@ impl DefaultKeyringStore { #[cfg(not(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) )))] { let _ = &self.service; @@ -170,7 +170,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) ))] { let entry = keyring::Entry::new(&self.service, key) @@ -184,7 +184,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(not(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) )))] { let _ = key; @@ -196,7 +196,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) ))] { let entry = keyring::Entry::new(&self.service, key) @@ -208,7 +208,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(not(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) )))] { let _ = (key, value); @@ -220,7 +220,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) ))] { let entry = keyring::Entry::new(&self.service, key) @@ -233,7 +233,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(not(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) )))] { let _ = key; @@ -249,7 +249,7 @@ impl KeyringStore for DefaultKeyringStore { #[cfg(not(any( target_os = "macos", target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) + all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl")) )))] fn unsupported_keyring_message() -> String { "system keyring backend is unsupported on this platform".to_string()