From cc97eca9b1145f8a8233ad04551fa7135afa6fd5 Mon Sep 17 00:00:00 2001 From: kiranmagic7 Date: Mon, 1 Jun 2026 07:02:00 +0530 Subject: [PATCH] test(installer): keep Node floor tied to package engine Adds a focused installer regression test tying install.sh's accepted Node 22 floor to the package engine floor. Thanks @kiranmagic7. --- test/scripts/install-sh.test.ts | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/test/scripts/install-sh.test.ts b/test/scripts/install-sh.test.ts index e19133b8957..2cac0e5237a 100644 --- a/test/scripts/install-sh.test.ts +++ b/test/scripts/install-sh.test.ts @@ -959,6 +959,59 @@ describe("install.sh", () => { expect(output).toContain("version=v22.22.0"); }); + it("uses the package engine floor when accepting existing Node runtimes", () => { + const pkg = JSON.parse(readFileSync("package.json", "utf8")) as { + engines?: { node?: string }; + }; + const engineMatch = /^>=22\.(\d+)\.0$/.exec(pkg.engines?.node ?? ""); + expect(engineMatch).not.toBeNull(); + + const minMinor = Number(engineMatch?.[1]); + expect(script).toContain(`NODE_MIN_MINOR=${minMinor}`); + + const tmp = mkdtempSync(join(tmpdir(), "openclaw-install-node-floor-")); + const bin = join(tmp, "bin"); + mkdirSync(bin, { recursive: true }); + + const nodePath = join(bin, "node"); + writeFileSync( + nodePath, + ["#!/bin/sh", 'printf "%s\\n" "${FAKE_NODE_VERSION:-v0.0.0}"', ""].join("\n"), + ); + chmodSync(nodePath, 0o755); + + let result: ReturnType | undefined; + try { + result = runInstallShell( + [ + `cd ${JSON.stringify(process.cwd())}`, + `source ${JSON.stringify(SCRIPT_PATH)}`, + "set +e", + `FAKE_NODE_VERSION="v22.${minMinor - 1}.0"`, + "export FAKE_NODE_VERSION", + "node_is_at_least_required", + "node_below_floor=$?", + `FAKE_NODE_VERSION="v22.${minMinor}.0"`, + "export FAKE_NODE_VERSION", + "node_is_at_least_required", + "node_at_floor=$?", + 'printf "node_below_floor=%s\\nnode_at_floor=%s\\n" "$node_below_floor" "$node_at_floor"', + "exit 0", + ].join("\n"), + { + PATH: `${bin}:/usr/bin:/bin`, + TERM: "dumb", + }, + ); + } finally { + rmSync(tmp, { force: true, recursive: true }); + } + + expect(result?.status).toBe(0); + expect(result?.stdout).toContain("node_below_floor=1"); + expect(result?.stdout).toContain("node_at_floor=0"); + }); + it("persists a supported Linux Node path before noninteractive shell guards", () => { const tmp = mkdtempSync(join(tmpdir(), "openclaw-install-linux-node-path-")); const home = join(tmp, "home");