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 f838b93..6145de9 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 29e4b32..d85e64d 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 5a33b15..f705e00 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 2acabf2..3403a4d 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/bin/sandbox-agent b/sdks/cli/bin/sandbox-agent index 705af5d..9374244 100755 --- a/sdks/cli/bin/sandbox-agent +++ b/sdks/cli/bin/sandbox-agent @@ -1,21 +1,6 @@ #!/usr/bin/env node const { execFileSync } = require("child_process"); const path = require("path"); -const fs = require("fs"); - -// Handle --version / -V at the launcher level to report npm package version -// This ensures version matches what's installed via npm, not what's compiled into the binary -const args = process.argv.slice(2); -if (args.length === 1 && (args[0] === "--version" || args[0] === "-V")) { - const pkgJsonPath = path.join(__dirname, "..", "package.json"); - try { - const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8")); - console.log(`sandbox-agent ${pkgJson.version}`); - process.exit(0); - } catch (e) { - // Fall through to binary if we can't read package.json - } -} const PLATFORMS = { "darwin-arm64": "@sandbox-agent/cli-darwin-arm64", @@ -34,7 +19,7 @@ if (!pkg) { try { const pkgPath = require.resolve(`${pkg}/package.json`); const bin = process.platform === "win32" ? "sandbox-agent.exe" : "sandbox-agent"; - execFileSync(path.join(path.dirname(pkgPath), "bin", bin), args, { stdio: "inherit" }); + execFileSync(path.join(path.dirname(pkgPath), "bin", bin), process.argv.slice(2), { stdio: "inherit" }); } catch (e) { if (e.status !== undefined) process.exit(e.status); throw e; 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 c0a57ff..38db97e 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)]