mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:40:44 +00:00
fix(release): isolate packaged compile cache
This commit is contained in:
@@ -1083,6 +1083,15 @@ gateway_log_ready() {
|
||||
gateway_smoke_ready() {
|
||||
gateway_listener_ready && gateway_log_ready
|
||||
}
|
||||
stop_openclaw_gateway_processes() {
|
||||
OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 /opt/homebrew/bin/openclaw gateway stop >/dev/null 2>&1 || true
|
||||
/usr/bin/pkill -9 -f openclaw-gateway || true
|
||||
/usr/bin/pkill -9 -f 'openclaw gateway run' || true
|
||||
/usr/bin/pkill -9 -f 'openclaw.mjs gateway' || true
|
||||
for pid in \$(/usr/sbin/lsof -tiTCP:18789 -sTCP:LISTEN 2>/dev/null || true); do
|
||||
/bin/kill -9 "\$pid" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
if [ -n "\$busy" ]; then
|
||||
printf 'update still has active npm/pnpm/openclaw processes\n%s\n' "\$busy" >&2
|
||||
exit 1
|
||||
@@ -1118,6 +1127,18 @@ if [ "\$gateway_ready" != "1" ]; then
|
||||
done
|
||||
fi
|
||||
if [ "\$gateway_ready" != "1" ]; then
|
||||
stop_openclaw_gateway_processes
|
||||
/opt/homebrew/bin/openclaw gateway run --bind loopback --port 18789 --force >/tmp/openclaw-parallels-npm-update-macos-recover-gateway.log 2>&1 </dev/null &
|
||||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||||
if gateway_smoke_ready; then
|
||||
gateway_ready=1
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
fi
|
||||
if [ "\$gateway_ready" != "1" ]; then
|
||||
tail -n 120 /tmp/openclaw-parallels-npm-update-macos-recover-gateway.log 2>/dev/null || true
|
||||
echo "gateway did not become ready after transport recovery" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -5,6 +5,7 @@ import { cleanupTempDirs, makeTempDir } from "../test/helpers/temp-dir.js";
|
||||
import {
|
||||
buildOpenClawCompileCacheRespawnPlan,
|
||||
isSourceCheckoutInstallRoot,
|
||||
resolveOpenClawCompileCacheDirectory,
|
||||
resolveEntryInstallRoot,
|
||||
shouldEnableOpenClawCompileCache,
|
||||
} from "./entry.compile-cache.js";
|
||||
@@ -54,6 +55,21 @@ describe("entry compile cache", () => {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("scopes packaged compile cache by package install metadata", async () => {
|
||||
const root = makeTempDir(tempDirs, "openclaw-compile-cache-package-key-");
|
||||
const packageJsonPath = path.join(root, "package.json");
|
||||
await fs.writeFile(packageJsonPath, '{"version":"2026.4.27-beta.1"}\n', "utf8");
|
||||
|
||||
const directory = resolveOpenClawCompileCacheDirectory({
|
||||
env: { NODE_COMPILE_CACHE: path.join(root, ".node-cache") },
|
||||
installRoot: root,
|
||||
});
|
||||
|
||||
expect(directory).toContain(path.join(".node-cache", "openclaw"));
|
||||
expect(directory).toContain("2026.4.27-beta.1");
|
||||
expect(path.basename(directory)).toMatch(/^\d+-\d+$/);
|
||||
});
|
||||
|
||||
it("builds a one-shot no-cache respawn plan when source checkout inherits NODE_COMPILE_CACHE", async () => {
|
||||
const root = makeTempDir(tempDirs, "openclaw-compile-cache-respawn-");
|
||||
await fs.mkdir(path.join(root, "src"), { recursive: true });
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { existsSync, readFileSync, statSync } from "node:fs";
|
||||
import { enableCompileCache, getCompileCacheDir } from "node:module";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
export function resolveEntryInstallRoot(entryFile: string): string {
|
||||
@@ -34,6 +35,55 @@ export function shouldEnableOpenClawCompileCache(params: {
|
||||
return !isSourceCheckoutInstallRoot(params.installRoot);
|
||||
}
|
||||
|
||||
function sanitizeCompileCachePathSegment(value: string): string {
|
||||
const normalized = value.replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
|
||||
return normalized.length > 0 ? normalized : "unknown";
|
||||
}
|
||||
|
||||
function readPackageVersion(packageJsonPath: string): string {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8")) as unknown;
|
||||
if (
|
||||
parsed &&
|
||||
typeof parsed === "object" &&
|
||||
"version" in parsed &&
|
||||
typeof parsed.version === "string" &&
|
||||
parsed.version.trim().length > 0
|
||||
) {
|
||||
return parsed.version;
|
||||
}
|
||||
} catch {
|
||||
// Fall through to an install-metadata-only cache key.
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
export function resolveOpenClawCompileCacheDirectory(params: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
installRoot: string;
|
||||
}): string {
|
||||
const env = params.env ?? process.env;
|
||||
const packageJsonPath = path.join(params.installRoot, "package.json");
|
||||
const version = sanitizeCompileCachePathSegment(readPackageVersion(packageJsonPath));
|
||||
let installMarker = "no-package-json";
|
||||
try {
|
||||
const stat = statSync(packageJsonPath);
|
||||
installMarker = `${Math.trunc(stat.mtimeMs)}-${stat.size}`;
|
||||
} catch {
|
||||
// Package archives should always have package.json, but keep startup best-effort.
|
||||
}
|
||||
const baseDirectory =
|
||||
env.NODE_COMPILE_CACHE && !isNodeCompileCacheDisabled(env)
|
||||
? env.NODE_COMPILE_CACHE
|
||||
: path.join(os.tmpdir(), "node-compile-cache");
|
||||
return path.join(
|
||||
baseDirectory,
|
||||
"openclaw",
|
||||
version,
|
||||
sanitizeCompileCachePathSegment(installMarker),
|
||||
);
|
||||
}
|
||||
|
||||
export type OpenClawCompileCacheRespawnPlan = {
|
||||
command: string;
|
||||
args: string[];
|
||||
@@ -107,7 +157,7 @@ export function enableOpenClawCompileCache(params: {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
enableCompileCache();
|
||||
enableCompileCache(resolveOpenClawCompileCacheDirectory(params));
|
||||
} catch {
|
||||
// Best-effort only; never block startup.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user