import assert from "node:assert/strict"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { execFileSync, spawnSync } from "node:child_process"; import { afterEach, describe, it } from "vitest"; const scriptPath = path.resolve("scripts/ci/persist-node-toolchain.sh"); const temporaryDirectories = []; afterEach(() => { for (const directory of temporaryDirectories.splice(0)) { fs.rmSync(directory, { recursive: true, force: true }); } }); function createFixture({ reportedVersion = "v24.18.0", includeCorepack = true } = {}) { const root = fs.mkdtempSync(path.join(os.tmpdir(), "hivegrid-node-toolchain-")); temporaryDirectories.push(root); const toolCache = path.join(root, "toolcache"); const toolBin = path.join(root, "persistent-bin"); const downloadedBin = path.join(toolCache, "node", "24.18.0", "x64", "bin"); fs.mkdirSync(downloadedBin, { recursive: true }); fs.mkdirSync(toolBin, { recursive: true }); fs.writeFileSync(path.join(root, ".nvmrc"), "v24.18.0\n"); fs.writeFileSync(path.join(downloadedBin, "node"), `#!/bin/sh\nprintf '%s\\n' '${reportedVersion}'\n`, { mode: 0o755 }); if (includeCorepack) { fs.writeFileSync(path.join(downloadedBin, "corepack"), "#!/bin/sh\nexit 0\n", { mode: 0o755 }); } return { root, toolCache, toolBin, downloadedBin }; } function environment(fixture) { return { ...process.env, RUNNER_TOOL_CACHE: fixture.toolCache, HIVEGRID_CI_TOOL_BIN: fixture.toolBin, }; } describe("persist-node-toolchain", () => { it("links setup-node's pinned runtime into a stable tool directory", () => { const fixture = createFixture(); execFileSync("bash", [scriptPath], { cwd: fixture.root, env: environment(fixture) }); assert.equal(fs.realpathSync(path.join(fixture.toolBin, "node")), fs.realpathSync(path.join(fixture.downloadedBin, "node"))); assert.equal(fs.realpathSync(path.join(fixture.toolBin, "corepack")), fs.realpathSync(path.join(fixture.downloadedBin, "corepack"))); }); it("fails closed when Corepack is absent from the downloaded runtime", () => { const fixture = createFixture({ includeCorepack: false }); const result = spawnSync("bash", [scriptPath], { cwd: fixture.root, env: environment(fixture), encoding: "utf8" }); assert.equal(result.status, 1); assert.match(result.stderr, /Corepack is missing/); }); it("fails closed when the persisted runtime does not match .nvmrc", () => { const fixture = createFixture({ reportedVersion: "v24.17.0" }); const result = spawnSync("bash", [scriptPath], { cwd: fixture.root, env: environment(fixture), encoding: "utf8" }); assert.equal(result.status, 1); assert.match(result.stderr, /runtime mismatch/); }); });