From 992ddf6310b3eee9197e21adea297258b8db422f Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 21 Jun 2026 06:25:54 +0200 Subject: [PATCH] test(scripts): cover workflow docker routes --- scripts/test-projects.test-support.mjs | 4 ++ test/scripts/test-install-sh-docker.test.ts | 53 +++++++++++++++++++++ test/scripts/test-projects.test.ts | 4 ++ 3 files changed, 61 insertions(+) diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index 715d15719815..7fb12f84ffb1 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -477,6 +477,10 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([ ["test/scripts/ci-workflow-guards.test.ts", "test/scripts/package-acceptance-workflow.test.ts"], ], [".github/workflows/live-media-runner-image.yml", LIVE_MEDIA_RUNNER_IMAGE_TEST_TARGETS], + [ + ".github/workflows/openclaw-live-and-e2e-checks-reusable.yml", + ["test/scripts/package-acceptance-workflow.test.ts"], + ], [ ".github/workflows/openclaw-release-checks.yml", ["test/scripts/package-acceptance-workflow.test.ts"], diff --git a/test/scripts/test-install-sh-docker.test.ts b/test/scripts/test-install-sh-docker.test.ts index a6887161794c..8726a17bfffc 100644 --- a/test/scripts/test-install-sh-docker.test.ts +++ b/test/scripts/test-install-sh-docker.test.ts @@ -9,13 +9,16 @@ import { createTempDirTracker } from "../helpers/temp-dir.js"; const SCRIPT_PATH = "scripts/test-install-sh-docker.sh"; const INSTALL_E2E_DOCKER_PATH = "scripts/test-install-sh-e2e-docker.sh"; +const INSTALL_E2E_DOCKERFILE_PATH = "scripts/docker/install-sh-e2e/Dockerfile"; const INSTALL_E2E_RUNNER_PATH = "scripts/docker/install-sh-e2e/run.sh"; const DOCKER_SETUP_PATH = "scripts/docker/setup.sh"; const HOST_TIMEOUT_PATH = "scripts/lib/host-timeout.sh"; const PODMAN_SETUP_PATH = "scripts/podman/setup.sh"; const PODMAN_QUADLET_TEMPLATE_PATH = "scripts/podman/openclaw.container.in"; const PODMAN_RUN_PATH = "scripts/run-openclaw-podman.sh"; +const SMOKE_DOCKERFILE_PATH = "scripts/docker/install-sh-smoke/Dockerfile"; const SMOKE_RUNNER_PATH = "scripts/docker/install-sh-smoke/run.sh"; +const NONROOT_DOCKERFILE_PATH = "scripts/docker/install-sh-nonroot/Dockerfile"; const NONROOT_RUNNER_PATH = "scripts/docker/install-sh-nonroot/run.sh"; const BUN_GLOBAL_SMOKE_PATH = "scripts/e2e/bun-global-install-smoke.sh"; const BUN_GLOBAL_ASSERTIONS_PATH = "scripts/e2e/lib/bun-global-install/assertions.mjs"; @@ -135,6 +138,27 @@ function normalizeInstallE2eAgentOutput(output: string) { } } +function expectInstallDockerfileContract( + dockerfilePath: string, + runnerPath: string, + entrypoint: string, +): string { + const dockerfile = readFileSync(dockerfilePath, "utf8"); + + expect(dockerfile).toContain("# syntax=docker/dockerfile:1.7"); + expect(dockerfile).toMatch(/^FROM \S+@sha256:[a-f0-9]{64}$/m); + expect(dockerfile).toContain("apt-get"); + expect(dockerfile).toContain("bash"); + expect(dockerfile).toContain("ca-certificates"); + expect(dockerfile).toContain("curl"); + expect(dockerfile).toContain( + "COPY install-sh-common/version-parse.sh /usr/local/install-sh-common/version-parse.sh", + ); + expect(dockerfile).toContain(`COPY --chmod=755 ${runnerPath} ${entrypoint}`); + expect(dockerfile).toContain(`ENTRYPOINT ["${entrypoint}"]`); + return dockerfile; +} + async function waitForCondition( predicate: () => boolean, label: string, @@ -269,6 +293,35 @@ describe("test-install-sh-docker", () => { ); }); + it("keeps install-sh Dockerfiles wired to their runner contracts", () => { + const e2eDockerfile = expectInstallDockerfileContract( + INSTALL_E2E_DOCKERFILE_PATH, + "install-sh-e2e/run.sh", + "/usr/local/bin/openclaw-install-e2e", + ); + const smokeDockerfile = expectInstallDockerfileContract( + SMOKE_DOCKERFILE_PATH, + "install-sh-smoke/run.sh", + "/usr/local/bin/openclaw-install-smoke", + ); + const nonrootDockerfile = expectInstallDockerfileContract( + NONROOT_DOCKERFILE_PATH, + "install-sh-nonroot/run.sh", + "/usr/local/bin/openclaw-install-nonroot", + ); + + expect(e2eDockerfile).toContain("USER appuser"); + expect(smokeDockerfile).toContain( + "COPY install-sh-common/cli-verify.sh /usr/local/install-sh-common/cli-verify.sh", + ); + expect(nonrootDockerfile).toContain( + "COPY install-sh-common/cli-verify.sh /usr/local/install-sh-common/cli-verify.sh", + ); + expect(nonrootDockerfile).toContain("USER app"); + expect(nonrootDockerfile).toContain("WORKDIR /home/app"); + expect(nonrootDockerfile).toContain("NPM_CONFIG_UPDATE_NOTIFIER=false"); + }); + it("can reuse dist from the already-built root Docker smoke image", () => { const script = readFileSync(SCRIPT_PATH, "utf8"); const dockerfile = readFileSync("Dockerfile", "utf8"); diff --git a/test/scripts/test-projects.test.ts b/test/scripts/test-projects.test.ts index ff0ff7deef39..c02cf2308335 100644 --- a/test/scripts/test-projects.test.ts +++ b/test/scripts/test-projects.test.ts @@ -1598,6 +1598,10 @@ describe("scripts/test-projects changed-target routing", () => { ".github/workflows/live-media-runner-image.yml", ["test/scripts/package-acceptance-workflow.test.ts"], ], + [ + ".github/workflows/openclaw-live-and-e2e-checks-reusable.yml", + ["test/scripts/package-acceptance-workflow.test.ts"], + ], [ "Dockerfile", [