mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:20:43 +00:00
fix(release): scope launcher compile cache
This commit is contained in:
77
openclaw.mjs
77
openclaw.mjs
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { existsSync, readFileSync, statSync } from "node:fs";
|
||||
import { access } from "node:fs/promises";
|
||||
import module from "node:module";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const MIN_NODE_MAJOR = 22;
|
||||
@@ -46,6 +48,41 @@ const isSourceCheckoutLauncher = () =>
|
||||
const isNodeCompileCacheDisabled = () => process.env.NODE_DISABLE_COMPILE_CACHE !== undefined;
|
||||
const isNodeCompileCacheRequested = () =>
|
||||
process.env.NODE_COMPILE_CACHE !== undefined && !isNodeCompileCacheDisabled();
|
||||
const sanitizeCompileCachePathSegment = (value) => {
|
||||
const normalized = value.replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
|
||||
return normalized.length > 0 ? normalized : "unknown";
|
||||
};
|
||||
const readPackageVersion = () => {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
|
||||
if (typeof parsed?.version === "string" && parsed.version.trim().length > 0) {
|
||||
return parsed.version;
|
||||
}
|
||||
} catch {
|
||||
// Fall through to an install-metadata-only cache key.
|
||||
}
|
||||
return "unknown";
|
||||
};
|
||||
const resolvePackagedCompileCacheDirectory = () => {
|
||||
const packageJsonUrl = new URL("./package.json", import.meta.url);
|
||||
const version = sanitizeCompileCachePathSegment(readPackageVersion());
|
||||
let installMarker = "no-package-json";
|
||||
try {
|
||||
const stat = statSync(packageJsonUrl);
|
||||
installMarker = `${Math.trunc(stat.mtimeMs)}-${stat.size}`;
|
||||
} catch {
|
||||
// Package archives should always have package.json, but keep startup best-effort.
|
||||
}
|
||||
const baseDirectory = isNodeCompileCacheRequested()
|
||||
? process.env.NODE_COMPILE_CACHE
|
||||
: path.join(os.tmpdir(), "node-compile-cache");
|
||||
return path.join(
|
||||
baseDirectory,
|
||||
"openclaw",
|
||||
version,
|
||||
sanitizeCompileCachePathSegment(installMarker),
|
||||
);
|
||||
};
|
||||
|
||||
const respawnWithoutCompileCacheIfNeeded = () => {
|
||||
if (!isSourceCheckoutLauncher()) {
|
||||
@@ -79,10 +116,46 @@ const respawnWithoutCompileCacheIfNeeded = () => {
|
||||
|
||||
respawnWithoutCompileCacheIfNeeded();
|
||||
|
||||
const respawnWithPackagedCompileCacheIfNeeded = () => {
|
||||
if (isSourceCheckoutLauncher() || isNodeCompileCacheDisabled()) {
|
||||
return false;
|
||||
}
|
||||
if (process.env.OPENCLAW_PACKAGED_COMPILE_CACHE_RESPAWNED === "1") {
|
||||
return false;
|
||||
}
|
||||
const currentDirectory = module.getCompileCacheDir?.();
|
||||
if (!currentDirectory) {
|
||||
return false;
|
||||
}
|
||||
const desiredDirectory = resolvePackagedCompileCacheDirectory();
|
||||
if (path.resolve(currentDirectory) === path.resolve(desiredDirectory)) {
|
||||
return false;
|
||||
}
|
||||
const env = {
|
||||
...process.env,
|
||||
NODE_COMPILE_CACHE: desiredDirectory,
|
||||
OPENCLAW_PACKAGED_COMPILE_CACHE_RESPAWNED: "1",
|
||||
};
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
[...process.execArgv, fileURLToPath(import.meta.url), ...process.argv.slice(2)],
|
||||
{
|
||||
stdio: "inherit",
|
||||
env,
|
||||
},
|
||||
);
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
process.exit(result.status ?? 1);
|
||||
};
|
||||
|
||||
respawnWithPackagedCompileCacheIfNeeded();
|
||||
|
||||
// https://nodejs.org/api/module.html#module-compile-cache
|
||||
if (module.enableCompileCache && !isNodeCompileCacheDisabled() && !isSourceCheckoutLauncher()) {
|
||||
try {
|
||||
module.enableCompileCache();
|
||||
module.enableCompileCache(resolvePackagedCompileCacheDirectory());
|
||||
} catch {
|
||||
// Ignore errors
|
||||
}
|
||||
|
||||
@@ -1078,7 +1078,7 @@ gateway_listener_ready() {
|
||||
gateway_log_ready() {
|
||||
latest="\$(/bin/ls -t /tmp/openclaw/openclaw-*.log 2>/dev/null | /usr/bin/head -n 1 || true)"
|
||||
[ -n "\$latest" ] || return 1
|
||||
/usr/bin/tail -n 160 "\$latest" | /usr/bin/grep -q 'ready ('
|
||||
/usr/bin/tail -n 160 "\$latest" | /usr/bin/grep -Eq 'ready( \(|[[:space:]]*\$)'
|
||||
}
|
||||
gateway_smoke_ready() {
|
||||
gateway_listener_ready && gateway_log_ready
|
||||
@@ -1682,7 +1682,7 @@ gateway_listener_ready() {
|
||||
gateway_log_ready() {
|
||||
latest="\$(/bin/ls -t /tmp/openclaw/openclaw-*.log 2>/dev/null | /usr/bin/head -n 1 || true)"
|
||||
[ -n "\$latest" ] || return 1
|
||||
/usr/bin/tail -n 160 "\$latest" | /usr/bin/grep -q 'ready ('
|
||||
/usr/bin/tail -n 160 "\$latest" | /usr/bin/grep -Eq 'ready( \(|[[:space:]]*\$)'
|
||||
}
|
||||
gateway_smoke_ready() {
|
||||
gateway_listener_ready && gateway_log_ready
|
||||
|
||||
@@ -177,6 +177,32 @@ describe("openclaw launcher", () => {
|
||||
expect(result.stdout).toBe("cache:enabled;respawn:0");
|
||||
});
|
||||
|
||||
it("scopes packaged launcher compile cache inside configured cache roots", async () => {
|
||||
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
|
||||
await fs.writeFile(path.join(fixtureRoot, "package.json"), '{"version":"2026.4.27-beta.1"}\n');
|
||||
await fs.writeFile(
|
||||
path.join(fixtureRoot, "dist", "entry.js"),
|
||||
[
|
||||
'import module from "node:module";',
|
||||
'process.stdout.write(module.getCompileCacheDir?.() ?? "cache:disabled");',
|
||||
].join("\n"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const result = spawnSync(process.execPath, [path.join(fixtureRoot, "openclaw.mjs")], {
|
||||
cwd: fixtureRoot,
|
||||
env: launcherEnv({
|
||||
NODE_COMPILE_CACHE: path.join(fixtureRoot, ".node-compile-cache"),
|
||||
}),
|
||||
encoding: "utf8",
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain(
|
||||
path.join(".node-compile-cache", "openclaw", "2026.4.27-beta.1"),
|
||||
);
|
||||
});
|
||||
|
||||
it("enables compile cache for packaged launchers", async () => {
|
||||
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
|
||||
await addCompileCacheProbe(fixtureRoot);
|
||||
|
||||
Reference in New Issue
Block a user