diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0e9159f..b4fa99f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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 diff --git a/bin/agent-browser.js b/bin/agent-browser.js index 4933947..1aba489 100755 --- a/bin/agent-browser.js +++ b/bin/agent-browser.js @@ -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'; diff --git a/scripts/build-all-platforms.sh b/scripts/build-all-platforms.sh index 45a2a67..277843e 100755 --- a/scripts/build-all-platforms.sh +++ b/scripts/build-all-platforms.sh @@ -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 "" diff --git a/scripts/postinstall.js b/scripts/postinstall.js index d37e7d0..949acb3 100644 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -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);