From 0c9dacf9023b8301a8d0db009e42ee3e2daecf0e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 25 Apr 2026 03:31:44 -0700 Subject: [PATCH] fix(test): ignore local check opt-out in dev wrappers --- scripts/check-changed.mjs | 25 +++++++++------ scripts/lib/local-heavy-check-runtime.mjs | 15 +++++++++ scripts/run-oxlint.mjs | 6 +++- scripts/run-tsgo.mjs | 6 +++- test/scripts/changed-lanes.test.ts | 13 ++++++++ .../scripts/local-heavy-check-runtime.test.ts | 32 ++++++++++++++++++- 6 files changed, 84 insertions(+), 13 deletions(-) diff --git a/scripts/check-changed.mjs b/scripts/check-changed.mjs index 69c302c6d9f..45b0ebf668f 100644 --- a/scripts/check-changed.mjs +++ b/scripts/check-changed.mjs @@ -7,6 +7,7 @@ import { } from "./changed-lanes.mjs"; import { booleanFlag, parseFlagArgs, stringFlag } from "./lib/arg-utils.mjs"; import { printTimingSummary } from "./lib/check-timing-summary.mjs"; +import { resolveLocalHeavyCheckEnv } from "./lib/local-heavy-check-runtime.mjs"; import { runManagedCommand } from "./lib/managed-child-process.mjs"; import { createSparseTsgoSkipEnv } from "./lib/tsgo-sparse-guard.mjs"; import { isCiLikeEnv } from "./lib/vitest-local-scheduling.mjs"; @@ -17,21 +18,23 @@ const VITEST_NO_OUTPUT_TIMEOUT_ENV_KEY = "OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS"; const VITEST_NO_OUTPUT_RETRY_ENV_KEY = "OPENCLAW_VITEST_NO_OUTPUT_RETRY"; export function createChangedCheckVitestEnv(baseEnv = process.env) { + const resolvedBaseEnv = resolveLocalHeavyCheckEnv(baseEnv); const env = { - ...baseEnv, + ...resolvedBaseEnv, [VITEST_NO_OUTPUT_TIMEOUT_ENV_KEY]: - baseEnv[VITEST_NO_OUTPUT_TIMEOUT_ENV_KEY]?.trim() || + resolvedBaseEnv[VITEST_NO_OUTPUT_TIMEOUT_ENV_KEY]?.trim() || CHANGED_CHECK_VITEST_NO_OUTPUT_TIMEOUT_MS, - [VITEST_NO_OUTPUT_RETRY_ENV_KEY]: baseEnv[VITEST_NO_OUTPUT_RETRY_ENV_KEY]?.trim() || "0", + [VITEST_NO_OUTPUT_RETRY_ENV_KEY]: + resolvedBaseEnv[VITEST_NO_OUTPUT_RETRY_ENV_KEY]?.trim() || "0", }; const hasWorkerOverride = Boolean( - (baseEnv.OPENCLAW_VITEST_MAX_WORKERS ?? baseEnv.OPENCLAW_TEST_WORKERS)?.trim(), + (resolvedBaseEnv.OPENCLAW_VITEST_MAX_WORKERS ?? resolvedBaseEnv.OPENCLAW_TEST_WORKERS)?.trim(), ); - const hasParallelOverride = Boolean(baseEnv.OPENCLAW_TEST_PROJECTS_PARALLEL?.trim()); - const serialOverride = baseEnv.OPENCLAW_TEST_PROJECTS_SERIAL?.trim(); + const hasParallelOverride = Boolean(resolvedBaseEnv.OPENCLAW_TEST_PROJECTS_PARALLEL?.trim()); + const serialOverride = resolvedBaseEnv.OPENCLAW_TEST_PROJECTS_SERIAL?.trim(); if ( - !isCiLikeEnv(baseEnv) && + !isCiLikeEnv(resolvedBaseEnv) && !hasWorkerOverride && !hasParallelOverride && serialOverride !== "0" @@ -45,12 +48,13 @@ export function createChangedCheckVitestEnv(baseEnv = process.env) { export function createChangedCheckPlan(result, options = {}) { const commands = []; + const baseEnv = resolveLocalHeavyCheckEnv(options.env ?? process.env); const add = (name, args, env) => { if (!commands.some((command) => command.name === name && sameArgs(command.args, args))) { commands.push({ name, args, ...(env ? { env } : {}) }); } }; - const addTypecheck = (name, args) => add(name, args, createSparseTsgoSkipEnv(options.env)); + const addTypecheck = (name, args) => add(name, args, createSparseTsgoSkipEnv(baseEnv)); add("conflict markers", ["check:no-conflict-markers"]); @@ -159,7 +163,8 @@ export function createChangedCheckPlan(result, options = {}) { } export async function runChangedCheck(result, options = {}) { - const plan = createChangedCheckPlan(result, options); + const baseEnv = resolveLocalHeavyCheckEnv(options.env ?? process.env); + const plan = createChangedCheckPlan(result, { ...options, env: baseEnv }); printPlan(result, plan, options); if (options.dryRun) { @@ -267,7 +272,7 @@ async function runCommand(command, timings) { status = await runManagedCommand({ bin: command.bin, args: command.args, - env: command.env, + env: command.env ?? resolveLocalHeavyCheckEnv(), }); } catch (error) { console.error(error); diff --git a/scripts/lib/local-heavy-check-runtime.mjs b/scripts/lib/local-heavy-check-runtime.mjs index 9c77180a716..f7066de894d 100644 --- a/scripts/lib/local-heavy-check-runtime.mjs +++ b/scripts/lib/local-heavy-check-runtime.mjs @@ -20,6 +20,21 @@ export function isLocalCheckEnabled(env) { return raw !== "0" && raw !== "false"; } +export function isCiLikeEnv(env = process.env) { + return env.CI === "true" || env.GITHUB_ACTIONS === "true"; +} + +export function resolveLocalHeavyCheckEnv(env = process.env) { + if (isCiLikeEnv(env) || isLocalCheckEnabled(env)) { + return env; + } + + return { + ...env, + OPENCLAW_LOCAL_CHECK: "1", + }; +} + export function hasFlag(args, name) { return args.some((arg) => arg === name || arg.startsWith(`${name}=`)); } diff --git a/scripts/run-oxlint.mjs b/scripts/run-oxlint.mjs index fb400bea29e..e89b87768d2 100644 --- a/scripts/run-oxlint.mjs +++ b/scripts/run-oxlint.mjs @@ -4,6 +4,7 @@ import path from "node:path"; import { acquireLocalHeavyCheckLockSync, applyLocalOxlintPolicy, + resolveLocalHeavyCheckEnv, shouldAcquireLocalHeavyCheckLockForOxlint, } from "./lib/local-heavy-check-runtime.mjs"; import { runManagedCommand } from "./lib/managed-child-process.mjs"; @@ -147,7 +148,10 @@ async function prepareExtensionPackageBoundaryArtifacts(env) { } export async function main(argv = process.argv.slice(2), runtimeEnv = process.env) { - const { args: policyArgs, env } = applyLocalOxlintPolicy(argv, runtimeEnv); + const { args: policyArgs, env } = applyLocalOxlintPolicy( + argv, + resolveLocalHeavyCheckEnv(runtimeEnv), + ); const sparseTargets = filterSparseMissingOxlintTargets(policyArgs); const finalArgs = sparseTargets.args; if (sparseTargets.skippedTargets.length > 0) { diff --git a/scripts/run-tsgo.mjs b/scripts/run-tsgo.mjs index 5bbcbdaa599..ecdc728f47d 100644 --- a/scripts/run-tsgo.mjs +++ b/scripts/run-tsgo.mjs @@ -5,6 +5,7 @@ import { readFlagValue } from "./lib/arg-utils.mjs"; import { acquireLocalHeavyCheckLockSync, applyLocalTsgoPolicy, + resolveLocalHeavyCheckEnv, shouldAcquireLocalHeavyCheckLockForTsgo, } from "./lib/local-heavy-check-runtime.mjs"; import { @@ -12,7 +13,10 @@ import { shouldSkipSparseTsgoGuardError, } from "./lib/tsgo-sparse-guard.mjs"; -const { args: finalArgs, env } = applyLocalTsgoPolicy(process.argv.slice(2), process.env); +const { args: finalArgs, env } = applyLocalTsgoPolicy( + process.argv.slice(2), + resolveLocalHeavyCheckEnv(process.env), +); const tsgoPath = path.resolve("node_modules", ".bin", "tsgo"); const tsBuildInfoFile = readFlagValue(finalArgs, "--tsBuildInfoFile"); diff --git a/test/scripts/changed-lanes.test.ts b/test/scripts/changed-lanes.test.ts index cf57c06840f..1720ea291ff 100644 --- a/test/scripts/changed-lanes.test.ts +++ b/test/scripts/changed-lanes.test.ts @@ -99,6 +99,19 @@ describe("scripts/changed-lanes", () => { }); }); + it("reenables local-check policy for changed typecheck commands", () => { + const result = detectChangedLanes(["src/shared/string-normalization.ts"]); + const plan = createChangedCheckPlan(result, { + env: { OPENCLAW_LOCAL_CHECK: "0", PATH: "/usr/bin" }, + }); + + expect(plan.commands.find((command) => command.args[0] === "tsgo:core")?.env).toMatchObject({ + OPENCLAW_LOCAL_CHECK: "1", + OPENCLAW_TSGO_SPARSE_SKIP: "1", + PATH: "/usr/bin", + }); + }); + it("routes core test-only changes to core test lanes only", () => { const result = detectChangedLanes(["src/shared/string-normalization.test.ts"]); diff --git a/test/scripts/local-heavy-check-runtime.test.ts b/test/scripts/local-heavy-check-runtime.test.ts index e6ec79556c1..55744ffd71a 100644 --- a/test/scripts/local-heavy-check-runtime.test.ts +++ b/test/scripts/local-heavy-check-runtime.test.ts @@ -5,6 +5,7 @@ import { acquireLocalHeavyCheckLockSync, applyLocalOxlintPolicy, applyLocalTsgoPolicy, + resolveLocalHeavyCheckEnv, shouldAcquireLocalHeavyCheckLockForOxlint, shouldAcquireLocalHeavyCheckLockForTsgo, } from "../../scripts/lib/local-heavy-check-runtime.mjs"; @@ -22,14 +23,43 @@ const ROOMY_HOST = { }; function makeEnv(overrides: Record = {}) { - return { + const env = { ...process.env, OPENCLAW_LOCAL_CHECK: "1", ...overrides, }; + if (!Object.hasOwn(overrides, "OPENCLAW_LOCAL_CHECK_MODE")) { + delete env.OPENCLAW_LOCAL_CHECK_MODE; + } + return env; } describe("local-heavy-check-runtime", () => { + it("reenables local heavy-check policy for local wrapper entrypoints", () => { + expect(resolveLocalHeavyCheckEnv({ OPENCLAW_LOCAL_CHECK: "0", PATH: "/usr/bin" })).toEqual({ + OPENCLAW_LOCAL_CHECK: "1", + PATH: "/usr/bin", + }); + expect(resolveLocalHeavyCheckEnv({ OPENCLAW_LOCAL_CHECK: "false", PATH: "/usr/bin" })).toEqual({ + OPENCLAW_LOCAL_CHECK: "1", + PATH: "/usr/bin", + }); + }); + + it("preserves local-check disablement in CI", () => { + expect( + resolveLocalHeavyCheckEnv({ + CI: "true", + OPENCLAW_LOCAL_CHECK: "0", + PATH: "/usr/bin", + }), + ).toEqual({ + CI: "true", + OPENCLAW_LOCAL_CHECK: "0", + PATH: "/usr/bin", + }); + }); + it("tightens local tsgo runs on constrained hosts", () => { const { args, env } = applyLocalTsgoPolicy([], makeEnv(), CONSTRAINED_HOST);