From 716b351619bdf959e2d2acd9fdca8b2aff2c480c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 4 Jul 2026 06:40:45 -0400 Subject: [PATCH] feat: allow custom sandbox image tags (#99915) * feat: allow custom sandbox image tags * test: align Crabbox default acceptance --- scripts/sandbox-setup.sh | 2 +- test/scripts/docker-build-helper.test.ts | 8 ++++++++ .../package-acceptance-workflow.test.ts | 18 +++++++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/scripts/sandbox-setup.sh b/scripts/sandbox-setup.sh index 46de6862a6d..f8881845a00 100755 --- a/scripts/sandbox-setup.sh +++ b/scripts/sandbox-setup.sh @@ -4,7 +4,7 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "$ROOT_DIR/scripts/lib/docker-build.sh" -IMAGE_NAME="openclaw-sandbox:bookworm-slim" +IMAGE_NAME="${OPENCLAW_SANDBOX_IMAGE:-openclaw-sandbox:bookworm-slim}" docker_build_exec -t "${IMAGE_NAME}" -f "$ROOT_DIR/scripts/docker/sandbox/Dockerfile" "$ROOT_DIR" echo "Built ${IMAGE_NAME}" diff --git a/test/scripts/docker-build-helper.test.ts b/test/scripts/docker-build-helper.test.ts index 5c0aa60e951..3e0df3d4bc4 100644 --- a/test/scripts/docker-build-helper.test.ts +++ b/test/scripts/docker-build-helper.test.ts @@ -172,6 +172,14 @@ function runCleanupDefaultPlatform(env: Record, hostArch: string } describe("docker build helper", () => { + it("allows deployments to build an immutable sandbox image tag", () => { + const script = readFileSync("scripts/sandbox-setup.sh", "utf8"); + + expect(script).toContain( + 'IMAGE_NAME="${OPENCLAW_SANDBOX_IMAGE:-openclaw-sandbox:bookworm-slim}"', + ); + }); + it("forces BuildKit for centralized Docker builds", () => { const helper = readFileSync(HELPER_PATH, "utf8"); diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index 95b38145685..ebf78151487 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -378,7 +378,7 @@ describe("package acceptance workflow", () => { ); }); - it("keeps default Crabbox capacity on the Azure credit-backed lane", () => { + it("defaults Crabbox proof to Blacksmith while keeping direct jobs on Azure", () => { const crabboxConfig = parse(readFileSync(CRABBOX_CONFIG, "utf8")) as { aws?: { region?: string }; capacity?: { @@ -388,22 +388,30 @@ describe("package acceptance workflow", () => { regions?: string[]; }; jobs?: { - changed?: { command?: string; market?: string; shell?: boolean; type?: string }; - prewarm?: { market?: string; type?: string }; + changed?: { + command?: string; + market?: string; + provider?: string; + shell?: boolean; + type?: string; + }; + prewarm?: { market?: string; provider?: string; type?: string }; }; provider?: string; ssh?: { port?: string; user?: string }; }; - expect(crabboxConfig.provider).toBe("azure"); + expect(crabboxConfig.provider).toBe("blacksmith-testbox"); expect(crabboxConfig.capacity?.market).toBe("on-demand"); expect(crabboxConfig.capacity?.fallback).toBeUndefined(); expect(crabboxConfig.capacity?.regions).toBeUndefined(); expect(crabboxConfig.capacity?.availabilityZones).toBeUndefined(); expect(crabboxConfig.aws?.region).toBe("eu-west-1"); expect(crabboxConfig.jobs?.prewarm?.market).toBe("on-demand"); + expect(crabboxConfig.jobs?.prewarm?.provider).toBe("azure"); expect(crabboxConfig.jobs?.prewarm?.type).toBe("Standard_D4ads_v6"); expect(crabboxConfig.jobs?.changed?.market).toBe("on-demand"); + expect(crabboxConfig.jobs?.changed?.provider).toBe("azure"); expect(crabboxConfig.jobs?.changed?.type).toBe("Standard_D4ads_v6"); expect(crabboxConfig.jobs?.changed?.shell).toBe(true); expect(crabboxConfig.jobs?.changed?.command).toContain("set -euo pipefail"); @@ -2140,7 +2148,7 @@ describe("package artifact reuse", () => { "uses: openclaw/clawhub/.github/workflows/package-publish.yml@d8096dfc039e86ab942ddf9ef117d04849fd84c1", ); expect(clawHubWorkflow).toContain( - "family: ${{ contains(fromJson('[\"@openclaw/acpx\",\"@openclaw/diffs\",\"@openclaw/feishu\",\"@openclaw/qqbot\"]'), matrix.plugin.packageName) && 'bundle-plugin' || '' }}", + 'family: ${{ contains(fromJson(\'["@openclaw/acpx","@openclaw/diffs","@openclaw/feishu","@openclaw/qqbot"]\'), matrix.plugin.packageName) && \'bundle-plugin\' || \'\' }}', ); expect(clawHubWorkflow).toContain("dry_run:"); expect(clawHubWorkflow).toContain("default: false");