fix(test): ignore local check opt-out in dev wrappers

This commit is contained in:
Vincent Koc
2026-04-25 03:31:44 -07:00
parent 87aa0f813c
commit 0c9dacf902
6 changed files with 84 additions and 13 deletions

View File

@@ -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);

View File

@@ -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}=`));
}

View File

@@ -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) {

View File

@@ -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");

View File

@@ -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"]);

View File

@@ -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<string, string | undefined> = {}) {
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);