

























@@ -0,0 +1,131 @@
1+import { spawnSync } from "node:child_process";
2+import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3+import { tmpdir } from "node:os";
4+import { join, resolve } from "node:path";
5+import { describe, expect, it } from "vitest";
6+7+const ensureNodeScript = resolve(".github/actions/setup-pnpm-store-cache/ensure-node.sh");
8+9+function writeFakeNode(binDir: string, version: string) {
10+mkdirSync(binDir, { recursive: true });
11+const nodePath = join(binDir, "node");
12+writeFileSync(
13+nodePath,
14+`#!/usr/bin/env bash
15+if [[ "$1" == "-p" ]]; then
16+ echo "${version}"
17+ exit 0
18+fi
19+if [[ "$1" == "-v" ]]; then
20+ echo "v${version}"
21+ exit 0
22+fi
23+exit 0
24+`,
25+);
26+chmodSync(nodePath, 0o755);
27+return nodePath;
28+}
29+30+function runEnsureNode(root: string, requested: string, extraEnv: NodeJS.ProcessEnv = {}) {
31+const githubPath = join(root, "github-path");
32+const result = spawnSync(
33+"bash",
34+[
35+"-c",
36+[
37+"set -e",
38+`source "${ensureNodeScript}"`,
39+`openclaw_ensure_node "${requested}"`,
40+"command -v node",
41+"node -p 'process.versions.node'",
42+].join("; "),
43+],
44+{
45+encoding: "utf8",
46+env: {
47+ ...process.env,
48+GITHUB_PATH: githubPath,
49+ ...extraEnv,
50+},
51+},
52+);
53+return result;
54+}
55+56+describe("setup-pnpm-store-cache ensure-node", () => {
57+it("uses a matching active node", () => {
58+const root = mkdtempSync(join(tmpdir(), "openclaw-ensure-node-"));
59+try {
60+const activeBin = join(root, "active", "bin");
61+const activeNode = writeFakeNode(activeBin, "24.15.0");
62+const result = runEnsureNode(root, "24.15.0", {
63+PATH: `${activeBin}:${process.env.PATH ?? ""}`,
64+RUNNER_TOOL_CACHE: join(root, "missing-toolcache"),
65+});
66+67+expect(result.status).toBe(0);
68+expect(result.stdout).toContain(`Using active Node 24.15.0 at ${activeNode}`);
69+expect(result.stdout.trim().endsWith("24.15.0")).toBe(true);
70+} finally {
71+rmSync(root, { recursive: true, force: true });
72+}
73+});
74+75+it("repairs PATH from the toolcache when setup-node leaves an old node active", () => {
76+const root = mkdtempSync(join(tmpdir(), "openclaw-ensure-node-"));
77+try {
78+const activeBin = join(root, "active", "bin");
79+writeFakeNode(activeBin, "20.20.0");
80+const toolcacheBin = join(root, "toolcache", "node", "24.15.0", "x64", "bin");
81+const toolcacheNode = writeFakeNode(toolcacheBin, "24.15.0");
82+const result = runEnsureNode(root, "24.15.0", {
83+PATH: `${activeBin}:${process.env.PATH ?? ""}`,
84+RUNNER_TOOL_CACHE: join(root, "toolcache"),
85+});
86+87+expect(result.status).toBe(0);
88+expect(result.stdout).toContain(`Using Node 24.15.0 from ${toolcacheNode}`);
89+expect(result.stdout).toContain(`${toolcacheNode}\n24.15.0`);
90+} finally {
91+rmSync(root, { recursive: true, force: true });
92+}
93+});
94+95+it("accepts major wildcard requests when selecting a toolcache node", () => {
96+const root = mkdtempSync(join(tmpdir(), "openclaw-ensure-node-"));
97+try {
98+const activeBin = join(root, "active", "bin");
99+writeFakeNode(activeBin, "20.20.0");
100+const toolcacheBin = join(root, "toolcache", "node", "24.15.0", "x64", "bin");
101+writeFakeNode(toolcacheBin, "24.15.0");
102+const result = runEnsureNode(root, "24.x", {
103+PATH: `${activeBin}:${process.env.PATH ?? ""}`,
104+RUNNER_TOOL_CACHE: join(root, "toolcache"),
105+});
106+107+expect(result.status).toBe(0);
108+expect(result.stdout.trim().endsWith("24.15.0")).toBe(true);
109+} finally {
110+rmSync(root, { recursive: true, force: true });
111+}
112+});
113+114+it("fails clearly when no matching node is available", () => {
115+const root = mkdtempSync(join(tmpdir(), "openclaw-ensure-node-"));
116+try {
117+const activeBin = join(root, "active", "bin");
118+writeFakeNode(activeBin, "20.20.0");
119+const result = runEnsureNode(root, "99.99.99", {
120+PATH: `${activeBin}:${process.env.PATH ?? ""}`,
121+RUNNER_TOOL_CACHE: join(root, "toolcache"),
122+});
123+124+expect(result.status).toBe(1);
125+expect(result.stdout).toContain("::error::Expected Node '99.99.99'");
126+expect(result.stdout).toContain("active node is '20.20.0'");
127+} finally {
128+rmSync(root, { recursive: true, force: true });
129+}
130+});
131+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。