refactor(test): consolidate script declaration contracts (#100992)

This commit is contained in:
Dallin Romney 2026-07-06 10:26:51 -07:00 committed by GitHub
parent f8307bb44c
commit d2e6ccf4bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 174 additions and 208 deletions

View file

@ -14,8 +14,21 @@ export type InstallSmokeScope = {
runFullInstallSmoke: boolean;
};
export type NodeFastScope = {
runFastOnly: boolean;
runPluginContracts: boolean;
runCiRouting: boolean;
};
export type ChangedScopeArgs = {
base: string;
head: string;
mergeHeadFirstParent: boolean;
};
export function detectChangedScope(changedPaths: string[]): ChangedScope;
export function shouldRunNativeI18n(changedPaths: string[]): boolean;
export function detectNodeFastScope(changedPaths: string[]): NodeFastScope;
export function detectInstallSmokeScope(changedPaths: string[]): InstallSmokeScope;
export function listChangedPaths(
base: string,
@ -27,10 +40,8 @@ export function writeGitHubOutput(
scope: ChangedScope,
outputPath?: string,
installSmokeScope?: InstallSmokeScope,
nodeFastScope?: {
runFastOnly: boolean;
runPluginContracts: boolean;
runCiRouting: boolean;
},
nodeFastScope?: NodeFastScope,
runNativeI18n?: boolean,
): void;
export function parseArgs(argv: string[]): ChangedScopeArgs;

View file

@ -11,12 +11,92 @@ export type ResolveRouteResult = {
loop?: boolean;
};
export type MirroredDocsDir = {
cleanup: () => void;
dir: string;
mirroredClawHub: boolean;
};
export type ScriptSpawnOptions = {
cwd: string;
env?: NodeJS.ProcessEnv;
shell?: boolean;
stdio: string;
};
export type ScriptSpawnResult = {
status: number | null;
error?: { code?: string };
};
export type ScriptSpawn = (
command: string,
args: string[],
options: ScriptSpawnOptions,
) => ScriptSpawnResult;
export type ScriptInvocation = {
command: string;
args: string[];
options?: Partial<ScriptSpawnOptions> & {
detached?: boolean;
windowsVerbatimArguments?: boolean;
};
};
export function normalizeRoute(route: string): string;
export function resolveRoute(
route: string,
options?: { redirects?: Map<string, string>; routes?: Set<string> },
): ResolveRouteResult;
export function auditDocsLinks(): {
export function sanitizeDocsConfigForEnglishOnly(value: unknown): unknown;
export function prepareMirroredDocsDir(
sourceDir?: string,
options?: {
resolveClawHubRepoPathImpl?: (
value?: string,
options?: { required?: boolean },
) => string | undefined;
syncClawHubDocsTreeImpl?: (
targetDocsDir: string,
options?: { repoPath?: string; required?: boolean },
) => unknown;
},
): MirroredDocsDir;
export function prepareAnchorAuditDocsDir(sourceDir?: string): string;
export function resolveMintlifyAnchorAuditInvocation(params: {
cwd: string;
nodeVersion?: string;
spawnSyncImpl: ScriptSpawn;
env?: NodeJS.ProcessEnv;
nodeExecPath?: string;
npmExecPath?: string;
platform?: NodeJS.Platform;
comSpec?: string;
}): ScriptInvocation;
export function auditDocsLinks(options?: {
docsDir?: string;
allowExternalClawHubRoutes?: boolean;
}): {
checked: number;
broken: BrokenDocLink[];
};
export function runDocsLinkAuditCli(options?: {
args?: string[];
comSpec?: string;
env?: NodeJS.ProcessEnv;
nodeExecPath?: string;
nodeVersion?: string;
npmExecPath?: string;
platform?: NodeJS.Platform;
spawnSyncImpl?: ScriptSpawn;
prepareAnchorAuditDocsDirImpl?: (sourceDir?: string) => string;
prepareMirroredDocsDirImpl?: (sourceDir?: string) => MirroredDocsDir;
cleanupAnchorAuditDocsDirImpl?: (dir: string) => void;
}): number;

View file

@ -1,3 +1,5 @@
import type { VitestHostInfo } from "./lib/vitest-local-scheduling.mjs";
export type VitestRunPlan = {
config: string;
forwardedArgs: string[];
@ -11,9 +13,19 @@ export type VitestRunSpec = {
includeFilePath: string | null;
includePatterns: string[] | null;
pnpmArgs: string[];
preflightPnpmArgs: string[] | null;
watchMode: boolean;
};
export type FailedVitestShard = {
code?: number | null;
config: string;
includePatterns?: string[] | null;
noOutputTimedOut?: boolean;
order?: number;
signal?: string | null;
};
export type ChangedTestTargetOptions = {
cwd?: string;
env?: Record<string, string | undefined>;
@ -29,6 +41,13 @@ export type ChangedTestTargetPlan = {
export const DEFAULT_TEST_PROJECTS_VITEST_NO_OUTPUT_TIMEOUT_MS: string;
export const DEFAULT_TEST_PROJECTS_VITEST_NO_OUTPUT_HEARTBEAT_MS: string;
export function orderFullSuiteSpecsForParallelRun<T extends { config: string }>(
specs: T[],
shardTimings?: ReadonlyMap<string, number>,
): T[];
export function formatNoChangedTestTargetLines(skippedBroadFallbackPaths: string[]): string[];
export function parseTestProjectsArgs(
args: string[],
cwd?: string,
@ -45,6 +64,22 @@ export function buildVitestRunPlans(
options?: ChangedTestTargetOptions,
): VitestRunPlan[];
export function buildFullSuiteVitestRunPlans(args: string[], cwd?: string): VitestRunPlan[];
export function shouldUseLocalFullSuiteParallelByDefault(
env?: Record<string, string | undefined>,
): boolean;
export function shouldExpandLocalFullSuiteShardsByDefault(
env?: Record<string, string | undefined>,
): boolean;
export function resolveParallelFullSuiteConcurrency(
specCount: number,
env?: Record<string, string | undefined>,
hostInfo?: VitestHostInfo,
): number;
export function resolveChangedTargetArgs(
args: string[],
cwd?: string,
@ -75,6 +110,8 @@ export function createVitestRunSpecs(
},
): VitestRunSpec[];
export function createVitestPreflightPnpmArgs(config: string): string[] | null;
export function findUnmatchedExplicitTestTargets(
args: string[],
cwd?: string,
@ -84,21 +121,45 @@ export function findUnmatchedExplicitTestTargets(
includePattern?: string;
}>;
export function applyDefaultVitestNoOutputTimeout(
specs: VitestRunSpec[],
export function applyDefaultVitestNoOutputTimeout<
T extends { config: string; env: NodeJS.ProcessEnv; watchMode: boolean },
>(
specs: T[],
params?: {
env?: Record<string, string | undefined>;
},
): VitestRunSpec[];
): Array<Omit<T, "env"> & { env: NodeJS.ProcessEnv }>;
export function applyDefaultMultiSpecVitestCachePaths(
specs: VitestRunSpec[],
export function applyDefaultMultiSpecVitestCachePaths<
T extends { config: string; env: NodeJS.ProcessEnv; watchMode: boolean },
>(
specs: T[],
params?: {
cwd?: string;
env?: Record<string, string | undefined>;
},
): VitestRunSpec[];
): Array<Omit<T, "env"> & { env: NodeJS.ProcessEnv }>;
export function applyParallelVitestCachePaths<T extends { config: string; env: NodeJS.ProcessEnv }>(
specs: T[],
params?: {
cwd?: string;
env?: NodeJS.ProcessEnv;
},
): Array<Omit<T, "env"> & { env: NodeJS.ProcessEnv }>;
export function shouldRetryVitestNoOutputTimeout(env?: Record<string, string | undefined>): boolean;
export function shouldAcquireLocalHeavyCheckLock(
runSpecs: Array<Pick<VitestRunSpec, "config" | "includePatterns" | "watchMode">>,
env?: Record<string, string | undefined>,
): boolean;
export function writeVitestIncludeFile(filePath: string, includePatterns: string[]): void;
export function formatFailedShardDigest(
failures: FailedVitestShard[],
options?: { limit?: number },
): string[];
export function buildVitestArgs(args: string[], cwd?: string): string[];

View file

@ -18,19 +18,3 @@ declare module "../../scripts/watch-node.mjs" {
lockDisabled?: boolean;
}): Promise<number>;
}
declare module "../../scripts/ci-changed-scope.mjs" {
export function detectChangedScope(paths: string[]): {
runNode: boolean;
runMacos: boolean;
runAndroid: boolean;
runWindows: boolean;
runSkillsPython: boolean;
runChangedSmoke: boolean;
runControlUiI18n: boolean;
};
export function detectInstallSmokeScope(paths: string[]): {
runFastInstallSmoke: boolean;
runFullInstallSmoke: boolean;
};
}

View file

@ -13,39 +13,7 @@ const {
listChangedPaths,
parseArgs,
shouldRunNativeI18n,
} = (await import("../../scripts/ci-changed-scope.mjs")) as unknown as {
detectChangedScope: (paths: string[]) => {
runNode: boolean;
runMacos: boolean;
runIosBuild: boolean;
runAndroid: boolean;
runWindows: boolean;
runSkillsPython: boolean;
runChangedSmoke: boolean;
runControlUiI18n: boolean;
};
detectInstallSmokeScope: (paths: string[]) => {
runFastInstallSmoke: boolean;
runFullInstallSmoke: boolean;
};
detectNodeFastScope: (paths: string[]) => {
runFastOnly: boolean;
runPluginContracts: boolean;
runCiRouting: boolean;
};
shouldRunNativeI18n: (paths: string[]) => boolean;
listChangedPaths: (
base: string,
head?: string,
cwd?: string,
preferMergeHeadFirstParent?: boolean,
) => string[];
parseArgs: (argv: string[]) => {
base: string;
head: string;
mergeHeadFirstParent: boolean;
};
};
} = await import("../../scripts/ci-changed-scope.mjs");
const markerPaths: string[] = [];
const tempDirs: string[] = [];

View file

@ -12,48 +12,7 @@ const {
resolveRoute,
runDocsLinkAuditCli,
sanitizeDocsConfigForEnglishOnly,
} = (await import("../../scripts/docs-link-audit.mjs")) as unknown as {
normalizeRoute: (route: string) => string;
prepareAnchorAuditDocsDir: (sourceDir?: string) => string;
prepareMirroredDocsDir: (
sourceDir?: string,
options?: {
resolveClawHubRepoPathImpl?: (value?: string, options?: { required?: boolean }) => string;
syncClawHubDocsTreeImpl?: (
targetDocsDir: string,
options?: { repoPath?: string; required?: boolean },
) => unknown;
},
) => {
cleanup: () => void;
dir: string;
mirroredClawHub: boolean;
};
resolveRoute: (
route: string,
options?: { redirects?: Map<string, string>; routes?: Set<string> },
) => { ok: boolean; terminal: string; loop?: boolean };
runDocsLinkAuditCli: (options?: {
args?: string[];
nodeVersion?: string;
spawnSyncImpl?: (
command: string,
args: string[],
options: { cwd: string; env?: NodeJS.ProcessEnv; shell?: boolean; stdio: string },
) => { status: number | null; error?: { code?: string } };
env?: NodeJS.ProcessEnv;
nodeExecPath?: string;
npmExecPath?: string;
prepareAnchorAuditDocsDirImpl?: (sourceDir?: string) => string;
cleanupAnchorAuditDocsDirImpl?: (dir: string) => void;
prepareMirroredDocsDirImpl?: (sourceDir?: string) => {
cleanup: () => void;
dir: string;
mirroredClawHub: boolean;
};
}) => number;
sanitizeDocsConfigForEnglishOnly: (value: unknown) => unknown;
};
} = await import("../../scripts/docs-link-audit.mjs");
describe("docs-link-audit", () => {
function tempEntries(prefix: string): Set<string> {

View file

@ -16,98 +16,7 @@ const {
resolveChangedTargetArgs,
resolveChangedTestTargetPlan,
resolveParallelFullSuiteConcurrency,
} = (await import("../../scripts/test-projects.test-support.mjs")) as unknown as {
applyParallelVitestCachePaths: (
specs: Array<{
config: string;
env: NodeJS.ProcessEnv;
}>,
params?: {
cwd?: string;
env?: NodeJS.ProcessEnv;
},
) => Array<{
config: string;
env: NodeJS.ProcessEnv;
}>;
buildFullSuiteVitestRunPlans: (
args: string[],
cwd?: string,
) => Array<{
config: string;
forwardedArgs: string[];
includePatterns: string[] | null;
watchMode: boolean;
}>;
buildVitestArgs: (args: string[], cwd?: string) => string[];
buildVitestRunPlans: (
args: string[],
cwd?: string,
listChangedPaths?: (baseRef: string, cwd: string) => string[],
) => Array<{
config: string;
forwardedArgs: string[];
includePatterns: string[] | null;
watchMode: boolean;
}>;
createVitestRunSpecs: (
args: string[],
params?: {
baseEnv?: NodeJS.ProcessEnv;
cwd?: string;
tempDir?: string;
},
) => Array<{
config: string;
env: NodeJS.ProcessEnv;
includeFilePath: string | null;
includePatterns: string[] | null;
pnpmArgs: string[];
watchMode: boolean;
}>;
findUnmatchedExplicitTestTargets: (
args: string[],
cwd?: string,
) => Array<{
target: string;
reason: "glob-matched-no-files" | "path-does-not-exist" | "target-matched-no-test-files";
includePattern?: string;
}>;
parseTestProjectsArgs: (
args: string[],
cwd?: string,
) => {
forwardedArgs: string[];
targetArgs: string[];
watchMode: boolean;
};
resolveChangedTargetArgs: (
args: string[],
cwd?: string,
listChangedPaths?: (baseRef: string, cwd: string) => string[],
options?: {
cwd?: string;
env?: NodeJS.ProcessEnv;
broad?: boolean;
},
) => string[] | null;
resolveChangedTestTargetPlan: (
changedPaths: string[],
) =>
| { mode: "none"; targets: string[] }
| { mode: "targets"; targets: string[] }
| { mode: "broad"; targets: string[] };
resolveParallelFullSuiteConcurrency: (
specCount: number,
env?: NodeJS.ProcessEnv,
hostInfo?: {
cpuCount?: number;
loadAverage1m?: number;
totalMemoryBytes?: number;
freeMemoryBytes?: number;
},
) => number;
};
} = await import("../../scripts/test-projects.test-support.mjs");
const runVitestModulePath = "../../scripts/run-vitest.mjs";
const { resolveVitestCliEntry, resolveVitestNodeArgs } = (await import(

View file

@ -10,6 +10,10 @@ import {
resolveLocalVitestMaxWorkers as resolveLocalVitestMaxWorkersImpl,
resolveLocalVitestScheduling as resolveLocalVitestSchedulingImpl,
} from "../../scripts/lib/vitest-local-scheduling.mjs";
import type {
LocalVitestScheduling,
VitestHostInfo,
} from "../../scripts/lib/vitest-local-scheduling.mjs";
import {
BUNDLED_PLUGIN_ROOT_DIR,
BUNDLED_PLUGIN_TEST_GLOB,
@ -17,19 +21,9 @@ import {
import { loadVitestExperimentalConfig } from "./vitest.performance-config.ts";
import { shouldPrintVitestThrottle } from "./vitest.system-load.ts";
type VitestHostInfo = {
cpuCount?: number;
loadAverage1m?: number;
totalMemoryBytes?: number;
};
export type OpenClawVitestPool = "forks" | "threads";
export type LocalVitestScheduling = {
maxWorkers: number;
fileParallelism: boolean;
throttledBySystem: boolean;
};
export type { LocalVitestScheduling };
export const jsdomOptimizedDeps = {
optimizer: {
@ -41,7 +35,7 @@ export const jsdomOptimizedDeps = {
};
function detectVitestHostInfo(): Required<VitestHostInfo> {
return detectVitestHostInfoImpl() as Required<VitestHostInfo>;
return detectVitestHostInfoImpl();
}
export function resolveLocalVitestMaxWorkers(
@ -57,7 +51,7 @@ export function resolveLocalVitestScheduling(
system: VitestHostInfo = detectVitestHostInfo(),
pool: OpenClawVitestPool = resolveDefaultVitestPool(env),
): LocalVitestScheduling {
return resolveLocalVitestSchedulingImpl(env, system, pool) as LocalVitestScheduling;
return resolveLocalVitestSchedulingImpl(env, system, pool);
}
export function resolveDefaultVitestPool(