feat: add linux-musl (Alpine) builds for x64 and arm64 (#784)

* feat: add linux-musl (Alpine) builds for x64 and arm64

Add x86_64-unknown-linux-musl and aarch64-unknown-linux-musl targets to
the release workflow using cargo-zigbuild. Update the JS wrapper and
postinstall script to detect musl libc and select the correct binary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: simplify isMusl() and add musl targets to build script

Address PR #784 review feedback:
- Remove redundant first try block in isMusl() (ldd --version always
  throws on musl, so only the `|| true` variant works)
- Add x86_64-unknown-linux-musl and aarch64-unknown-linux-musl targets
  to build-all-platforms.sh to stay in sync with the release workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Manolis Tzanidakis
2026-03-14 12:51:35 -05:00
committed by GitHub
co-authored by Claude Opus 4.6
parent c4a40033e0
commit 388f19e1bb
4 changed files with 47 additions and 6 deletions
+15 -3
View File
@@ -31,6 +31,16 @@ jobs:
target: aarch64-unknown-linux-gnu
binary: agent-browser-linux-arm64
use_zigbuild: true
- name: Linux musl x64
os: ubuntu-latest
target: x86_64-unknown-linux-musl
binary: agent-browser-linux-musl-x64
use_zigbuild: true
- name: Linux musl ARM64
os: ubuntu-latest
target: aarch64-unknown-linux-musl
binary: agent-browser-linux-musl-arm64
use_zigbuild: true
- name: Windows x64
os: ubuntu-latest
target: x86_64-pc-windows-gnu
@@ -175,6 +185,8 @@ jobs:
EXPECTED_BINARIES=(
"agent-browser-linux-x64"
"agent-browser-linux-arm64"
"agent-browser-linux-musl-x64"
"agent-browser-linux-musl-arm64"
"agent-browser-win32-x64.exe"
"agent-browser-darwin-x64"
"agent-browser-darwin-arm64"
@@ -199,7 +211,7 @@ jobs:
echo "Error: $ERRORS binary issues found"
exit 1
fi
echo "All 5 platform binaries present and valid"
echo "All 7 platform binaries present and valid"
- name: Create Release Pull Request or Publish to npm
id: changesets
@@ -241,8 +253,8 @@ jobs:
- name: Verify binaries exist
run: |
BINARY_COUNT=$(ls bin/agent-browser-* 2>/dev/null | wc -l)
if [ "$BINARY_COUNT" -lt 5 ]; then
echo "Error: Expected 5 binaries, found $BINARY_COUNT"
if [ "$BINARY_COUNT" -lt 7 ]; then
echo "Error: Expected 7 binaries, found $BINARY_COUNT"
ls -la bin/
exit 1
fi
+13 -2
View File
@@ -8,7 +8,7 @@
* binary directly (zero overhead).
*/
import { spawn } from 'child_process';
import { spawn, execSync } from 'child_process';
import { existsSync, accessSync, chmodSync, constants } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
@@ -16,6 +16,17 @@ import { platform, arch } from 'os';
const __dirname = dirname(fileURLToPath(import.meta.url));
// Detect if the system uses musl libc (e.g. Alpine Linux)
function isMusl() {
if (platform() !== 'linux') return false;
try {
const result = execSync('ldd --version 2>&1 || true', { encoding: 'utf8' });
return result.toLowerCase().includes('musl');
} catch {
return existsSync('/lib/ld-musl-x86_64.so.1') || existsSync('/lib/ld-musl-aarch64.so.1');
}
}
// Map Node.js platform/arch to binary naming convention
function getBinaryName() {
const os = platform();
@@ -27,7 +38,7 @@ function getBinaryName() {
osKey = 'darwin';
break;
case 'linux':
osKey = 'linux';
osKey = isMusl() ? 'linux-musl' : 'linux';
break;
case 'win32':
osKey = 'win32';
+6
View File
@@ -61,6 +61,12 @@ build_target "x86_64-apple-darwin" "agent-browser-darwin-x64"
# macOS ARM64 (via zig for cross-compilation)
build_target "aarch64-apple-darwin" "agent-browser-darwin-arm64"
# Linux musl x64 (Alpine)
build_target "x86_64-unknown-linux-musl" "agent-browser-linux-musl-x64"
# Linux musl ARM64 (Alpine)
build_target "aarch64-unknown-linux-musl" "agent-browser-linux-musl-arm64"
echo ""
echo -e "${GREEN}Build complete!${NC}"
echo ""
+13 -1
View File
@@ -20,8 +20,20 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
const projectRoot = join(__dirname, '..');
const binDir = join(projectRoot, 'bin');
// Detect if the system uses musl libc (e.g. Alpine Linux)
function isMusl() {
if (platform() !== 'linux') return false;
try {
const result = execSync('ldd --version 2>&1 || true', { encoding: 'utf8' });
return result.toLowerCase().includes('musl');
} catch {
return existsSync('/lib/ld-musl-x86_64.so.1') || existsSync('/lib/ld-musl-aarch64.so.1');
}
}
// Platform detection
const platformKey = `${platform()}-${arch()}`;
const osKey = platform() === 'linux' && isMusl() ? 'linux-musl' : platform();
const platformKey = `${osKey}-${arch()}`;
const ext = platform() === 'win32' ? '.exe' : '';
const binaryName = `agent-browser-${platformKey}${ext}`;
const binaryPath = join(binDir, binaryName);