From 553f2498367f3cf955e03aec51de70a4e7d6b996 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Mon, 2 Feb 2026 00:45:31 -0800 Subject: [PATCH] fix: add postinstall chmod for npm binary permissions (#43) * fix: add postinstall chmod for npm binary permissions * fix: report npm package version instead of compiled binary version The --version flag now reports the version from package.json instead of the version compiled into the Rust binary. This ensures the version matches what was installed via npm, even when binaries are reused from previous releases. * fix: bake version into binary at build time Instead of hacking around the version in the Node.js wrapper script, properly pass the version at build time via SANDBOX_AGENT_VERSION env var. Changes: - build.rs: Generate version.rs with VERSION constant from env var - main.rs: Use generated version constant for clap --version - Dockerfiles: Accept SANDBOX_AGENT_VERSION as build arg - build.sh: Pass version as second argument to Docker builds - release.yaml: Pass version to build script during CI - Remove version hack from sdks/cli/bin/sandbox-agent wrapper The version is now baked into the binary during the release build, ensuring --version reports the correct npm package version. --- .github/workflows/release.yaml | 4 ++-- docker/release/build.sh | 12 +++++++++-- docker/release/linux-x86_64.Dockerfile | 4 ++++ docker/release/macos-aarch64.Dockerfile | 4 ++++ docker/release/macos-x86_64.Dockerfile | 4 ++++ docker/release/windows.Dockerfile | 4 ++++ sdks/cli/platforms/darwin-arm64/package.json | 3 +++ sdks/cli/platforms/darwin-x64/package.json | 3 +++ sdks/cli/platforms/linux-x64/package.json | 3 +++ server/packages/sandbox-agent/build.rs | 22 +++++++++++++++++++- server/packages/sandbox-agent/src/main.rs | 7 ++++++- 11 files changed, 64 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0ab3ac5..76c5b31 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -125,8 +125,8 @@ jobs: # Use Docker BuildKit export DOCKER_BUILDKIT=1 - # Build the binary using our Dockerfile - docker/release/build.sh ${{ matrix.target }} + # Build the binary using our Dockerfile with version + docker/release/build.sh ${{ matrix.target }} ${{ github.event.inputs.version }} # Make sure dist directory exists and binary is there ls -la dist/ diff --git a/docker/release/build.sh b/docker/release/build.sh index 2095591..a9e42e4 100755 --- a/docker/release/build.sh +++ b/docker/release/build.sh @@ -2,6 +2,14 @@ set -euo pipefail TARGET=${1:-x86_64-unknown-linux-musl} +VERSION=${2:-} + +# Build arguments for Docker +BUILD_ARGS="" +if [ -n "$VERSION" ]; then + BUILD_ARGS="--build-arg SANDBOX_AGENT_VERSION=$VERSION" + echo "Building with version: $VERSION" +fi case $TARGET in x86_64-unknown-linux-musl) @@ -36,9 +44,9 @@ case $TARGET in DOCKER_BUILDKIT=1 if [ -n "$TARGET_STAGE" ]; then - docker build --target "$TARGET_STAGE" -f "docker/release/$DOCKERFILE" -t "sandbox-agent-builder-$TARGET" . + docker build --target "$TARGET_STAGE" $BUILD_ARGS -f "docker/release/$DOCKERFILE" -t "sandbox-agent-builder-$TARGET" . else - docker build -f "docker/release/$DOCKERFILE" -t "sandbox-agent-builder-$TARGET" . + docker build $BUILD_ARGS -f "docker/release/$DOCKERFILE" -t "sandbox-agent-builder-$TARGET" . fi CONTAINER_ID=$(docker create "sandbox-agent-builder-$TARGET") diff --git a/docker/release/linux-x86_64.Dockerfile b/docker/release/linux-x86_64.Dockerfile index 3831cb0..d707d20 100644 --- a/docker/release/linux-x86_64.Dockerfile +++ b/docker/release/linux-x86_64.Dockerfile @@ -66,6 +66,10 @@ WORKDIR /build # Build for x86_64 FROM base AS x86_64-builder +# Accept version as build arg +ARG SANDBOX_AGENT_VERSION +ENV SANDBOX_AGENT_VERSION=${SANDBOX_AGENT_VERSION} + # Set up OpenSSL for x86_64 musl target ENV SSL_VER=1.1.1w RUN wget https://www.openssl.org/source/openssl-$SSL_VER.tar.gz \ diff --git a/docker/release/macos-aarch64.Dockerfile b/docker/release/macos-aarch64.Dockerfile index ed5e79c..dcc9466 100644 --- a/docker/release/macos-aarch64.Dockerfile +++ b/docker/release/macos-aarch64.Dockerfile @@ -70,6 +70,10 @@ WORKDIR /build # Build for ARM64 macOS FROM base AS aarch64-builder +# Accept version as build arg +ARG SANDBOX_AGENT_VERSION +ENV SANDBOX_AGENT_VERSION=${SANDBOX_AGENT_VERSION} + # Install macOS ARM64 target RUN rustup target add aarch64-apple-darwin diff --git a/docker/release/macos-x86_64.Dockerfile b/docker/release/macos-x86_64.Dockerfile index 34fce08..62d7c90 100644 --- a/docker/release/macos-x86_64.Dockerfile +++ b/docker/release/macos-x86_64.Dockerfile @@ -70,6 +70,10 @@ WORKDIR /build # Build for x86_64 macOS FROM base AS x86_64-builder +# Accept version as build arg +ARG SANDBOX_AGENT_VERSION +ENV SANDBOX_AGENT_VERSION=${SANDBOX_AGENT_VERSION} + # Install macOS x86_64 target RUN rustup target add x86_64-apple-darwin diff --git a/docker/release/windows.Dockerfile b/docker/release/windows.Dockerfile index 914c955..38fb3c5 100644 --- a/docker/release/windows.Dockerfile +++ b/docker/release/windows.Dockerfile @@ -26,6 +26,10 @@ RUN cd frontend/packages/inspector && pnpm exec vite build FROM rust:1.88.0 +# Accept version as build arg +ARG SANDBOX_AGENT_VERSION +ENV SANDBOX_AGENT_VERSION=${SANDBOX_AGENT_VERSION} + # Install dependencies RUN apt-get update && apt-get install -y \ llvm-14-dev \ diff --git a/sdks/cli/platforms/darwin-arm64/package.json b/sdks/cli/platforms/darwin-arm64/package.json index 07d5628..242e689 100644 --- a/sdks/cli/platforms/darwin-arm64/package.json +++ b/sdks/cli/platforms/darwin-arm64/package.json @@ -13,6 +13,9 @@ "cpu": [ "arm64" ], + "scripts": { + "postinstall": "chmod +x bin/sandbox-agent || true" + }, "files": [ "bin" ] diff --git a/sdks/cli/platforms/darwin-x64/package.json b/sdks/cli/platforms/darwin-x64/package.json index 414cf04..c585259 100644 --- a/sdks/cli/platforms/darwin-x64/package.json +++ b/sdks/cli/platforms/darwin-x64/package.json @@ -13,6 +13,9 @@ "cpu": [ "x64" ], + "scripts": { + "postinstall": "chmod +x bin/sandbox-agent || true" + }, "files": [ "bin" ] diff --git a/sdks/cli/platforms/linux-x64/package.json b/sdks/cli/platforms/linux-x64/package.json index ef8ac77..c6f15b3 100644 --- a/sdks/cli/platforms/linux-x64/package.json +++ b/sdks/cli/platforms/linux-x64/package.json @@ -13,6 +13,9 @@ "cpu": [ "x64" ], + "scripts": { + "postinstall": "chmod +x bin/sandbox-agent || true" + }, "files": [ "bin" ] diff --git a/server/packages/sandbox-agent/build.rs b/server/packages/sandbox-agent/build.rs index 56e4ba0..170c05a 100644 --- a/server/packages/sandbox-agent/build.rs +++ b/server/packages/sandbox-agent/build.rs @@ -16,10 +16,14 @@ fn main() { .join("dist"); println!("cargo:rerun-if-env-changed=SANDBOX_AGENT_SKIP_INSPECTOR"); + println!("cargo:rerun-if-env-changed=SANDBOX_AGENT_VERSION"); println!("cargo:rerun-if-changed={}", dist_dir.display()); - let skip = env::var("SANDBOX_AGENT_SKIP_INSPECTOR").is_ok(); + // Generate version constant from environment variable or fallback to Cargo.toml version let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR")); + generate_version(&out_dir); + + let skip = env::var("SANDBOX_AGENT_SKIP_INSPECTOR").is_ok(); let out_file = out_dir.join("inspector_assets.rs"); if skip { @@ -61,3 +65,19 @@ fn quote_path(path: &Path) -> String { .replace('\\', "\\\\") .replace('"', "\\\"") } + +fn generate_version(out_dir: &Path) { + // Use SANDBOX_AGENT_VERSION env var if set, otherwise fall back to CARGO_PKG_VERSION + let version = env::var("SANDBOX_AGENT_VERSION") + .unwrap_or_else(|_| env::var("CARGO_PKG_VERSION").expect("CARGO_PKG_VERSION")); + + let out_file = out_dir.join("version.rs"); + let contents = format!( + "/// Version string for this build.\n\ + /// Set via SANDBOX_AGENT_VERSION env var at build time, or falls back to Cargo.toml version.\n\ + pub const VERSION: &str = \"{}\";\n", + version + ); + + fs::write(&out_file, contents).expect("write version.rs"); +} diff --git a/server/packages/sandbox-agent/src/main.rs b/server/packages/sandbox-agent/src/main.rs index 8904ddd..92587c2 100644 --- a/server/packages/sandbox-agent/src/main.rs +++ b/server/packages/sandbox-agent/src/main.rs @@ -4,6 +4,11 @@ use std::path::PathBuf; use std::sync::Arc; use clap::{Args, Parser, Subcommand}; + +// Include the generated version constant +mod build_version { + include!(concat!(env!("OUT_DIR"), "/version.rs")); +} use reqwest::blocking::Client as HttpClient; use reqwest::Method; use sandbox_agent::router::{build_router_with_state, shutdown_servers}; @@ -34,7 +39,7 @@ const DEFAULT_PORT: u16 = 2468; #[derive(Parser, Debug)] #[command(name = "sandbox-agent", bin_name = "sandbox-agent")] -#[command(about = "https://sandboxagent.dev", version)] +#[command(about = "https://sandboxagent.dev", version = build_version::VERSION)] #[command(arg_required_else_help = true)] struct Cli { #[command(subcommand)]