From 088cab5ee4e6972f188f059d58e287df8f63678d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 21 Jun 2026 15:39:17 +0200 Subject: [PATCH] fix(macos): prefer repo pnpm for packaging --- scripts/package-mac-app.sh | 8 +-- scripts/package-mac-dist.sh | 8 +-- test/scripts/package-mac-app.test.ts | 62 +++++++++++++++++++++++ test/scripts/package-mac-dist.test.ts | 73 +++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 8 deletions(-) diff --git a/scripts/package-mac-app.sh b/scripts/package-mac-app.sh index 7ae5d49d9759..92e0cbe3d566 100755 --- a/scripts/package-mac-app.sh +++ b/scripts/package-mac-app.sh @@ -68,13 +68,13 @@ sparkle_framework_for_arch() { PNPM_CMD=() resolve_pnpm_cmd() { - if command -v pnpm >/dev/null 2>&1; then - PNPM_CMD=(pnpm) + if command -v corepack >/dev/null 2>&1 && (cd "$ROOT_DIR" && corepack pnpm --version >/dev/null 2>&1); then + PNPM_CMD=(corepack pnpm) return 0 fi - if command -v corepack >/dev/null 2>&1 && (cd "$ROOT_DIR" && corepack pnpm --version >/dev/null 2>&1); then - PNPM_CMD=(corepack pnpm) + if command -v pnpm >/dev/null 2>&1; then + PNPM_CMD=(pnpm) return 0 fi diff --git a/scripts/package-mac-dist.sh b/scripts/package-mac-dist.sh index d290719a72f9..82721eebc166 100755 --- a/scripts/package-mac-dist.sh +++ b/scripts/package-mac-dist.sh @@ -33,13 +33,13 @@ DIST_PNPM_CMD=() SPARKLE_BUILD_DEPS_RETRIED=0 resolve_dist_pnpm_cmd() { - if command -v pnpm >/dev/null 2>&1; then - DIST_PNPM_CMD=(pnpm) + if command -v corepack >/dev/null 2>&1 && (cd "$ROOT_DIR" && corepack pnpm --version >/dev/null 2>&1); then + DIST_PNPM_CMD=(corepack pnpm) return 0 fi - if command -v corepack >/dev/null 2>&1 && (cd "$ROOT_DIR" && corepack pnpm --version >/dev/null 2>&1); then - DIST_PNPM_CMD=(corepack pnpm) + if command -v pnpm >/dev/null 2>&1; then + DIST_PNPM_CMD=(pnpm) return 0 fi diff --git a/test/scripts/package-mac-app.test.ts b/test/scripts/package-mac-app.test.ts index a11291ecb880..dd5c93deec4e 100644 --- a/test/scripts/package-mac-app.test.ts +++ b/test/scripts/package-mac-app.test.ts @@ -205,6 +205,68 @@ describe("package-mac-app plist stamping", () => { ]); }); + it("prefers repo Corepack pnpm over a global pnpm shim", () => { + const helperBlock = getPackageManagerHelperBlock(); + const tempRoot = mkdtempSync(path.join(tmpdir(), "openclaw-package-pnpm-root-")); + const outerRoot = mkdtempSync(path.join(tmpdir(), "openclaw-package-pnpm-outer-")); + const toolsDir = mkdtempSync(path.join(tmpdir(), "openclaw-package-pnpm-tools-")); + const logPath = path.join(tempRoot, "pnpm.log"); + tempDirs.push(tempRoot, outerRoot, toolsDir); + + writeFileSync( + path.join(tempRoot, "package.json"), + '{\n "packageManager": "pnpm@11.2.2+sha512.test"\n}\n', + ); + writeFileSync( + path.join(outerRoot, "package.json"), + '{\n "packageManager": "pnpm@11.8.0+sha512.test"\n}\n', + ); + writeFileSync( + path.join(toolsDir, "pnpm"), + [ + "#!/usr/bin/env bash", + "set -euo pipefail", + 'printf "global|%s|%s\\n" "$PWD" "$*" >> "$OPENCLAW_TEST_LOG"', + 'if [[ "${1:-}" == "--version" ]]; then echo "11.8.0"; fi', + "", + ].join("\n"), + "utf8", + ); + writeFileSync( + path.join(toolsDir, "corepack"), + [ + "#!/usr/bin/env bash", + "set -euo pipefail", + 'printf "corepack|%s|%s\\n" "$PWD" "$*" >> "$OPENCLAW_TEST_LOG"', + 'if [[ "${1:-}" == "pnpm" && "${2:-}" == "--version" ]]; then', + ' if grep -q "pnpm@11.2.2" package.json 2>/dev/null; then echo "11.2.2"; else echo "11.8.0"; fi', + "fi", + "", + ].join("\n"), + "utf8", + ); + chmodSync(path.join(toolsDir, "pnpm"), 0o755); + chmodSync(path.join(toolsDir, "corepack"), 0o755); + + const result = runHelper(` + set -euo pipefail + ROOT_DIR=${JSON.stringify(tempRoot)} + OPENCLAW_TEST_LOG=${JSON.stringify(logPath)} + export OPENCLAW_TEST_LOG + PATH=${JSON.stringify(`${toolsDir}:/usr/bin:/bin`)} + cd ${JSON.stringify(outerRoot)} + ${helperBlock} + run_pnpm --version + `); + + expect(result.status).toBe(0); + expect(result.stdout).toBe("11.2.2\n"); + expect(readFileSync(logPath, "utf8").trim().split("\n")).toEqual([ + `corepack|${tempRoot}|pnpm --version`, + `corepack|${tempRoot}|pnpm --version`, + ]); + }); + it("fails with an actionable error when neither pnpm nor corepack pnpm is available", () => { const helperBlock = getPackageManagerHelperBlock(); const tempRoot = mkdtempSync(path.join(tmpdir(), "openclaw-package-pnpm-root-")); diff --git a/test/scripts/package-mac-dist.test.ts b/test/scripts/package-mac-dist.test.ts index 746d5cba2ddb..c152b03e6964 100644 --- a/test/scripts/package-mac-dist.test.ts +++ b/test/scripts/package-mac-dist.test.ts @@ -37,6 +37,17 @@ function runHelper(script: string) { }); } +function getPackageManagerHelperBlock(): string { + const script = readFileSync(scriptPath, "utf8"); + const start = script.indexOf("DIST_PNPM_CMD=()"); + const end = script.indexOf("ensure_sparkle_build_deps()"); + + expect(start).toBeGreaterThanOrEqual(0); + expect(end).toBeGreaterThan(start); + + return script.slice(start, end); +} + afterEach(() => { for (const dir of tempDirs.splice(0)) { rmSync(dir, { recursive: true, force: true }); @@ -102,6 +113,68 @@ describe("package-mac-dist plist validation", () => { expect(script).not.toContain('canonical_sparkle_build "$VERSION" 2>/dev/null || true'); }); + it("prefers repo Corepack pnpm over a global pnpm shim", () => { + const helperBlock = getPackageManagerHelperBlock(); + const tempRoot = mkdtempSync(path.join(tmpdir(), "openclaw-dist-pnpm-root-")); + const outerRoot = mkdtempSync(path.join(tmpdir(), "openclaw-dist-pnpm-outer-")); + const toolsDir = mkdtempSync(path.join(tmpdir(), "openclaw-dist-pnpm-tools-")); + const logPath = path.join(tempRoot, "pnpm.log"); + tempDirs.push(tempRoot, outerRoot, toolsDir); + + writeFileSync( + path.join(tempRoot, "package.json"), + '{\n "packageManager": "pnpm@11.2.2+sha512.test"\n}\n', + ); + writeFileSync( + path.join(outerRoot, "package.json"), + '{\n "packageManager": "pnpm@11.8.0+sha512.test"\n}\n', + ); + writeFileSync( + path.join(toolsDir, "pnpm"), + [ + "#!/usr/bin/env bash", + "set -euo pipefail", + 'printf "global|%s|%s\\n" "$PWD" "$*" >> "$OPENCLAW_TEST_LOG"', + 'if [[ "${1:-}" == "--version" ]]; then echo "11.8.0"; fi', + "", + ].join("\n"), + "utf8", + ); + writeFileSync( + path.join(toolsDir, "corepack"), + [ + "#!/usr/bin/env bash", + "set -euo pipefail", + 'printf "corepack|%s|%s\\n" "$PWD" "$*" >> "$OPENCLAW_TEST_LOG"', + 'if [[ "${1:-}" == "pnpm" && "${2:-}" == "--version" ]]; then', + ' if grep -q "pnpm@11.2.2" package.json 2>/dev/null; then echo "11.2.2"; else echo "11.8.0"; fi', + "fi", + "", + ].join("\n"), + "utf8", + ); + chmodSync(path.join(toolsDir, "pnpm"), 0o755); + chmodSync(path.join(toolsDir, "corepack"), 0o755); + + const result = runHelper(` + set -euo pipefail + ROOT_DIR=${JSON.stringify(tempRoot)} + OPENCLAW_TEST_LOG=${JSON.stringify(logPath)} + export OPENCLAW_TEST_LOG + PATH=${JSON.stringify(`${toolsDir}:/usr/bin:/bin`)} + cd ${JSON.stringify(outerRoot)} + ${helperBlock} + run_dist_pnpm --version + `); + + expect(result.status).toBe(0); + expect(result.stdout).toBe("11.2.2\n"); + expect(readFileSync(logPath, "utf8").trim().split("\n")).toEqual([ + `corepack|${tempRoot}|pnpm --version`, + `corepack|${tempRoot}|pnpm --version`, + ]); + }); + it("keeps dependency bootstrap output out of captured Sparkle build values", () => { const script = readFileSync(scriptPath, "utf8"); const helpers = script.slice(