From f16a66fa439f24edcc7fbdc92e5ddf1074f2ff4c Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Fri, 10 Apr 2026 17:03:52 -0500 Subject: [PATCH] fix: release local heavy-check locks on success --- scripts/lib/local-heavy-check-runtime.mjs | 17 +++++++++++ scripts/lib/run-extension-oxlint.mjs | 14 ++++++--- scripts/run-oxlint.mjs | 2 +- scripts/run-tsgo.mjs | 2 +- .../scripts/local-heavy-check-runtime.test.ts | 30 +++++++++++++++++++ 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/scripts/lib/local-heavy-check-runtime.mjs b/scripts/lib/local-heavy-check-runtime.mjs index 43eeff679f1..020eee0e1b2 100644 --- a/scripts/lib/local-heavy-check-runtime.mjs +++ b/scripts/lib/local-heavy-check-runtime.mjs @@ -133,6 +133,9 @@ export function acquireLocalHeavyCheckLockSync(params) { let lastProgressAt = 0; fs.mkdirSync(locksDir, { recursive: true }); + if (!params.lockName) { + cleanupLegacyLockDirs(locksDir, staleLockMs); + } for (;;) { try { @@ -210,6 +213,20 @@ export function resolveGitCommonDir(cwd) { return path.join(cwd, ".git"); } +function cleanupLegacyLockDirs(locksDir, staleLockMs) { + for (const legacyLockName of ["test"]) { + const legacyLockDir = path.join(locksDir, `${legacyLockName}.lock`); + if (!fs.existsSync(legacyLockDir)) { + continue; + } + + const owner = readOwnerFile(path.join(legacyLockDir, "owner.json")); + if (shouldReclaimLock({ owner, lockDir: legacyLockDir, staleLockMs })) { + fs.rmSync(legacyLockDir, { recursive: true, force: true }); + } + } +} + function insertBeforeSeparator(args, ...items) { if (items.length > 0 && hasFlag(args, items[0])) { return; diff --git a/scripts/lib/run-extension-oxlint.mjs b/scripts/lib/run-extension-oxlint.mjs index fedcaeb65b4..25b0484daa2 100644 --- a/scripts/lib/run-extension-oxlint.mjs +++ b/scripts/lib/run-extension-oxlint.mjs @@ -18,6 +18,7 @@ export function runExtensionOxlint(params) { }); const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), params.tempDirPrefix)); const tempConfigPath = path.join(tempDir, "oxlint.json"); + let exitCode = 0; try { prepareExtensionPackageBoundaryArtifacts(repoRoot); @@ -45,11 +46,13 @@ export function runExtensionOxlint(params) { throw result.error; } - process.exit(result.status ?? 1); + exitCode = result.status ?? 1; } finally { fs.rmSync(tempDir, { recursive: true, force: true }); releaseLock(); } + + process.exitCode = exitCode; } function prepareExtensionPackageBoundaryArtifacts(repoRoot) { @@ -59,6 +62,7 @@ function prepareExtensionPackageBoundaryArtifacts(repoRoot) { toolName: "extension-package-boundary-artifacts", lockName: "extension-package-boundary-artifacts", }); + let exitCode = 0; try { const result = spawnSync( @@ -75,12 +79,14 @@ function prepareExtensionPackageBoundaryArtifacts(repoRoot) { throw result.error; } - if ((result.status ?? 1) !== 0) { - process.exit(result.status ?? 1); - } + exitCode = result.status ?? 1; } finally { releaseLock(); } + + if (exitCode !== 0) { + process.exitCode = exitCode; + } } function writeTempOxlintConfig(repoRoot, configPath) { diff --git a/scripts/run-oxlint.mjs b/scripts/run-oxlint.mjs index 8630c9daae4..5a8b3b8e14c 100644 --- a/scripts/run-oxlint.mjs +++ b/scripts/run-oxlint.mjs @@ -25,7 +25,7 @@ try { throw result.error; } - process.exit(result.status ?? 1); + process.exitCode = result.status ?? 1; } finally { releaseLock(); } diff --git a/scripts/run-tsgo.mjs b/scripts/run-tsgo.mjs index 2e5787b3707..f7906a74477 100644 --- a/scripts/run-tsgo.mjs +++ b/scripts/run-tsgo.mjs @@ -30,7 +30,7 @@ try { throw result.error; } - process.exit(result.status ?? 1); + process.exitCode = result.status ?? 1; } finally { releaseLock(); } diff --git a/test/scripts/local-heavy-check-runtime.test.ts b/test/scripts/local-heavy-check-runtime.test.ts index 0413af769ce..def0c4353b1 100644 --- a/test/scripts/local-heavy-check-runtime.test.ts +++ b/test/scripts/local-heavy-check-runtime.test.ts @@ -197,4 +197,34 @@ describe("local-heavy-check-runtime", () => { release(); expect(fs.existsSync(lockDir)).toBe(false); }); + + it("cleans up stale legacy test locks when acquiring the shared heavy-check lock", () => { + const cwd = createTempDir("openclaw-local-heavy-check-legacy-"); + const commonDir = path.join(cwd, ".git"); + const locksDir = path.join(commonDir, "openclaw-local-checks"); + const legacyLockDir = path.join(locksDir, "test.lock"); + const heavyCheckLockDir = path.join(locksDir, "heavy-check.lock"); + fs.mkdirSync(legacyLockDir, { recursive: true }); + fs.writeFileSync( + path.join(legacyLockDir, "owner.json"), + `${JSON.stringify({ + pid: 999_999_999, + tool: "test", + cwd, + })}\n`, + "utf8", + ); + + const release = acquireLocalHeavyCheckLockSync({ + cwd, + env: makeEnv(), + toolName: "oxlint", + }); + + expect(fs.existsSync(legacyLockDir)).toBe(false); + expect(fs.existsSync(heavyCheckLockDir)).toBe(true); + + release(); + expect(fs.existsSync(heavyCheckLockDir)).toBe(false); + }); });