mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
test: route changed runner edits narrowly
This commit is contained in:
@@ -8,8 +8,7 @@ import {
|
||||
} from "./changed-lanes.mjs";
|
||||
import { booleanFlag, parseFlagArgs, stringFlag } from "./lib/arg-utils.mjs";
|
||||
import { printTimingSummary } from "./lib/check-timing-summary.mjs";
|
||||
|
||||
const ROUTABLE_TEST_PATH_RE = /^(?:src|test|extensions|ui|packages|apps)(?:\/|$)/u;
|
||||
import { resolveChangedTestTargetPlan } from "./test-projects.test-support.mjs";
|
||||
|
||||
export function createChangedCheckPlan(result) {
|
||||
const commands = [];
|
||||
@@ -25,6 +24,7 @@ export function createChangedCheckPlan(result) {
|
||||
return {
|
||||
commands,
|
||||
testTargets: [],
|
||||
runChangedTestsBroad: false,
|
||||
runFullTests: false,
|
||||
runExtensionTests: false,
|
||||
summary: "docs-only",
|
||||
@@ -41,6 +41,7 @@ export function createChangedCheckPlan(result) {
|
||||
return {
|
||||
commands,
|
||||
testTargets: [],
|
||||
runChangedTestsBroad: false,
|
||||
runFullTests: true,
|
||||
runExtensionTests: false,
|
||||
summary: "all",
|
||||
@@ -82,10 +83,12 @@ export function createChangedCheckPlan(result) {
|
||||
add("pairing account guard", ["lint:auth:pairing-account-scope"]);
|
||||
}
|
||||
|
||||
const testTargets = result.paths.filter((changedPath) => ROUTABLE_TEST_PATH_RE.test(changedPath));
|
||||
const testPlan = resolveChangedTestTargetPlan(result.paths);
|
||||
const runChangedTestsBroad = testPlan.mode === "broad";
|
||||
return {
|
||||
commands,
|
||||
testTargets,
|
||||
testTargets: testPlan.targets,
|
||||
runChangedTestsBroad,
|
||||
runFullTests: false,
|
||||
runExtensionTests: result.extensionImpactFromCore,
|
||||
summary: Object.entries(lanes)
|
||||
@@ -118,6 +121,21 @@ export async function runChangedCheck(result, options = {}) {
|
||||
printSummary(timings, options);
|
||||
return status;
|
||||
}
|
||||
} else if (plan.runChangedTestsBroad) {
|
||||
const testArgs = options.explicitPaths
|
||||
? ["scripts/test-projects.mjs"]
|
||||
: ["scripts/test-projects.mjs", "--changed", options.base ?? "origin/main"];
|
||||
const status = await runNode(
|
||||
{
|
||||
name: options.explicitPaths ? "tests all" : "tests changed broad",
|
||||
args: testArgs,
|
||||
},
|
||||
timings,
|
||||
);
|
||||
if (status !== 0) {
|
||||
printSummary(timings, options);
|
||||
return status;
|
||||
}
|
||||
} else if (plan.testTargets.length > 0) {
|
||||
const status = await runNode(
|
||||
{
|
||||
@@ -154,6 +172,9 @@ function printPlan(result, plan, options) {
|
||||
if (result.extensionImpactFromCore) {
|
||||
console.error(`${prefix} core contract changed; extension tests included`);
|
||||
}
|
||||
if (plan.runChangedTestsBroad) {
|
||||
console.error(`${prefix} broad changed tests included`);
|
||||
}
|
||||
for (const reason of result.reasons) {
|
||||
console.error(`${prefix} ${reason}`);
|
||||
}
|
||||
@@ -246,5 +267,8 @@ if (isDirectRun()) {
|
||||
? listStagedChangedPaths()
|
||||
: listChangedPathsFromGit({ base: args.base, head: args.head });
|
||||
const result = detectChangedLanes(paths);
|
||||
process.exitCode = await runChangedCheck(result, args);
|
||||
process.exitCode = await runChangedCheck(result, {
|
||||
...args,
|
||||
explicitPaths: args.paths.length > 0,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,6 +35,11 @@ export function resolveChangedTargetArgs(
|
||||
listChangedPaths?: (baseRef: string, cwd: string) => string[],
|
||||
): string[] | null;
|
||||
|
||||
export function resolveChangedTestTargetPlan(changedPaths: string[]): {
|
||||
mode: "none" | "broad" | "targets";
|
||||
targets: string[];
|
||||
};
|
||||
|
||||
export function listFullExtensionVitestProjectConfigs(): string[];
|
||||
|
||||
export function createVitestRunSpecs(
|
||||
|
||||
@@ -168,9 +168,27 @@ const BROAD_CHANGED_RERUN_PATTERNS = [
|
||||
/^vitest(?:\..+)?\.(?:config\.ts|paths\.mjs)$/u,
|
||||
/^test\/vitest\/vitest\.(?:config|shared\.config|scoped-config|performance-config)\.ts$/u,
|
||||
/^test\/helpers\//u,
|
||||
/^scripts\/run-vitest\.mjs$/u,
|
||||
/^scripts\/test-projects(?:\.test-support)?\.mjs$/u,
|
||||
];
|
||||
const TOOLING_SOURCE_TEST_TARGETS = new Map([
|
||||
["scripts/changed-lanes.mjs", ["test/scripts/changed-lanes.test.ts"]],
|
||||
["scripts/check-changed.mjs", ["test/scripts/changed-lanes.test.ts"]],
|
||||
["scripts/lib/vitest-local-scheduling.mjs", ["test/scripts/vitest-local-scheduling.test.ts"]],
|
||||
[
|
||||
"scripts/run-vitest.mjs",
|
||||
["test/scripts/test-projects.test.ts", "test/scripts/vitest-local-scheduling.test.ts"],
|
||||
],
|
||||
["scripts/test-projects.mjs", ["test/scripts/test-projects.test.ts"]],
|
||||
["scripts/test-projects.test-support.d.mts", ["test/scripts/test-projects.test.ts"]],
|
||||
["scripts/test-projects.test-support.mjs", ["test/scripts/test-projects.test.ts"]],
|
||||
]);
|
||||
const TOOLING_TEST_TARGETS = new Map([
|
||||
["test/scripts/changed-lanes.test.ts", ["test/scripts/changed-lanes.test.ts"]],
|
||||
["test/scripts/test-projects.test.ts", ["test/scripts/test-projects.test.ts"]],
|
||||
[
|
||||
"test/scripts/vitest-local-scheduling.test.ts",
|
||||
["test/scripts/vitest-local-scheduling.test.ts"],
|
||||
],
|
||||
]);
|
||||
const VITEST_CONFIG_TARGET_KIND_BY_PATH = new Map(
|
||||
Object.entries(VITEST_CONFIG_BY_KIND).map(([kind, config]) => [config, kind]),
|
||||
);
|
||||
@@ -239,7 +257,29 @@ function isVitestConfigTargetForKind(kind, targetArg, cwd) {
|
||||
}
|
||||
|
||||
function listChangedPathsFromGit(baseRef, cwd) {
|
||||
return execFileSync("git", ["diff", "--name-only", `${baseRef}...HEAD`], {
|
||||
return [
|
||||
...new Set([
|
||||
...runGitNameOnlyDiff(cwd, [`${baseRef}...HEAD`]),
|
||||
...runGitNameOnlyDiff(cwd, ["--cached", "--diff-filter=ACMR"]),
|
||||
...runGitNameOnlyDiff(cwd, ["--diff-filter=ACMR"]),
|
||||
...runGitLsFiles(cwd, ["--others", "--exclude-standard"]),
|
||||
]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
function runGitNameOnlyDiff(cwd, extraArgs) {
|
||||
return execFileSync("git", ["diff", "--name-only", ...extraArgs], {
|
||||
cwd,
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
})
|
||||
.split("\n")
|
||||
.map((line) => normalizePathPattern(line.trim()))
|
||||
.filter((line) => line.length > 0);
|
||||
}
|
||||
|
||||
function runGitLsFiles(cwd, extraArgs) {
|
||||
return execFileSync("git", ["ls-files", ...extraArgs], {
|
||||
cwd,
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
@@ -290,10 +330,45 @@ function shouldKeepBroadChangedRun(changedPaths) {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveToolingChangedTestTargets(changedPaths) {
|
||||
const targets = [];
|
||||
for (const changedPath of changedPaths) {
|
||||
const testTargets =
|
||||
TOOLING_SOURCE_TEST_TARGETS.get(changedPath) ?? TOOLING_TEST_TARGETS.get(changedPath);
|
||||
if (!testTargets) {
|
||||
return null;
|
||||
}
|
||||
targets.push(...testTargets);
|
||||
}
|
||||
return [...new Set(targets)];
|
||||
}
|
||||
|
||||
function isRoutableChangedTarget(changedPath) {
|
||||
return /^(?:src|test|extensions|ui|packages)(?:\/|$)/u.test(changedPath);
|
||||
}
|
||||
|
||||
export function resolveChangedTestTargetPlan(changedPaths) {
|
||||
if (changedPaths.length === 0) {
|
||||
return { mode: "none", targets: [] };
|
||||
}
|
||||
const toolingTargets = resolveToolingChangedTestTargets(changedPaths);
|
||||
if (toolingTargets) {
|
||||
return { mode: "targets", targets: toolingTargets };
|
||||
}
|
||||
if (shouldKeepBroadChangedRun(changedPaths)) {
|
||||
return { mode: "broad", targets: [] };
|
||||
}
|
||||
const changedLanes = detectChangedLanes(changedPaths);
|
||||
if (changedLanes.lanes.all) {
|
||||
return { mode: "broad", targets: [] };
|
||||
}
|
||||
const targets = changedPaths.filter(isRoutableChangedTarget);
|
||||
if (changedLanes.extensionImpactFromCore) {
|
||||
targets.push("extensions");
|
||||
}
|
||||
return { mode: "targets", targets: [...new Set(targets)] };
|
||||
}
|
||||
|
||||
export function listFullExtensionVitestProjectConfigs() {
|
||||
return (
|
||||
fullSuiteVitestShards.find((shard) => shard.config === FULL_EXTENSIONS_VITEST_CONFIG)
|
||||
@@ -311,19 +386,11 @@ export function resolveChangedTargetArgs(
|
||||
return null;
|
||||
}
|
||||
const changedPaths = listChangedPaths(baseRef, cwd);
|
||||
if (changedPaths.length === 0 || shouldKeepBroadChangedRun(changedPaths)) {
|
||||
const plan = resolveChangedTestTargetPlan(changedPaths);
|
||||
if (plan.mode === "broad") {
|
||||
return null;
|
||||
}
|
||||
const changedLanes = detectChangedLanes(changedPaths);
|
||||
if (changedLanes.lanes.all) {
|
||||
return null;
|
||||
}
|
||||
const routablePaths = changedPaths.filter(isRoutableChangedTarget);
|
||||
const targets = [...routablePaths];
|
||||
if (changedLanes.extensionImpactFromCore) {
|
||||
targets.push("extensions");
|
||||
}
|
||||
return [...new Set(targets)];
|
||||
return plan.targets;
|
||||
}
|
||||
|
||||
function classifyTarget(arg, cwd) {
|
||||
|
||||
Reference in New Issue
Block a user