perf(test): expand light lane routing
This commit is contained in:
@@ -61,6 +61,7 @@ Think of the suites as “increasing realism” (and increasing flakiness/cost):
|
|||||||
- `pnpm test`, `pnpm test:watch`, and `pnpm test:perf:imports` route explicit file/directory targets through scoped lanes first, so `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` avoids paying the full root project startup tax.
|
- `pnpm test`, `pnpm test:watch`, and `pnpm test:perf:imports` route explicit file/directory targets through scoped lanes first, so `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` avoids paying the full root project startup tax.
|
||||||
- `pnpm test:changed` expands changed git paths into the same scoped lanes when the diff only touches routable source/test files; config/setup edits still fall back to the broad root-project rerun.
|
- `pnpm test:changed` expands changed git paths into the same scoped lanes when the diff only touches routable source/test files; config/setup edits still fall back to the broad root-project rerun.
|
||||||
- Selected `plugin-sdk` and `commands` tests also route through dedicated light lanes that skip `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy files stay on the existing lanes.
|
- Selected `plugin-sdk` and `commands` tests also route through dedicated light lanes that skip `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy files stay on the existing lanes.
|
||||||
|
- Selected `plugin-sdk` and `commands` helper source files also map changed-mode runs to explicit sibling tests in those light lanes, so helper edits avoid rerunning the full heavy suite for that directory.
|
||||||
- Embedded runner note:
|
- Embedded runner note:
|
||||||
- When you change message-tool discovery inputs or compaction runtime context,
|
- When you change message-tool discovery inputs or compaction runtime context,
|
||||||
keep both levels of coverage.
|
keep both levels of coverage.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ title: "Tests"
|
|||||||
- `pnpm test:changed`: expands changed git paths into scoped Vitest lanes when the diff only touches routable source/test files. Config/setup changes still fall back to the native root projects run so wiring edits rerun broadly when needed.
|
- `pnpm test:changed`: expands changed git paths into scoped Vitest lanes when the diff only touches routable source/test files. Config/setup changes still fall back to the native root projects run so wiring edits rerun broadly when needed.
|
||||||
- `pnpm test`: routes explicit file/directory targets through scoped Vitest lanes, but still falls back to the native root projects run when you do a full untargeted sweep.
|
- `pnpm test`: routes explicit file/directory targets through scoped Vitest lanes, but still falls back to the native root projects run when you do a full untargeted sweep.
|
||||||
- Selected `plugin-sdk` and `commands` test files now route through dedicated light lanes that keep only `test/setup.ts`, leaving runtime-heavy cases on their existing lanes.
|
- Selected `plugin-sdk` and `commands` test files now route through dedicated light lanes that keep only `test/setup.ts`, leaving runtime-heavy cases on their existing lanes.
|
||||||
|
- Selected `plugin-sdk` and `commands` helper source files also map `pnpm test:changed` to explicit sibling tests in those light lanes, so small helper edits avoid rerunning the heavy runtime-backed suites.
|
||||||
- Base Vitest config now defaults to `pool: "threads"` and `isolate: false`, with the shared non-isolated runner enabled across the repo configs.
|
- Base Vitest config now defaults to `pool: "threads"` and `isolate: false`, with the shared non-isolated runner enabled across the repo configs.
|
||||||
- `pnpm test:channels` runs `vitest.channels.config.ts`.
|
- `pnpm test:channels` runs `vitest.channels.config.ts`.
|
||||||
- `pnpm test:extensions` runs `vitest.extensions.config.ts`.
|
- `pnpm test:extensions` runs `vitest.extensions.config.ts`.
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import fs from "node:fs";
|
|||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { isChannelSurfaceTestFile } from "../vitest.channel-paths.mjs";
|
import { isChannelSurfaceTestFile } from "../vitest.channel-paths.mjs";
|
||||||
import { isCommandsLightTestFile } from "../vitest.commands-light-paths.mjs";
|
import {
|
||||||
|
isCommandsLightTarget,
|
||||||
|
resolveCommandsLightIncludePattern,
|
||||||
|
} from "../vitest.commands-light-paths.mjs";
|
||||||
import { isAcpxExtensionRoot } from "../vitest.extension-acpx-paths.mjs";
|
import { isAcpxExtensionRoot } from "../vitest.extension-acpx-paths.mjs";
|
||||||
import { isBlueBubblesExtensionRoot } from "../vitest.extension-bluebubbles-paths.mjs";
|
import { isBlueBubblesExtensionRoot } from "../vitest.extension-bluebubbles-paths.mjs";
|
||||||
import { isDiffsExtensionRoot } from "../vitest.extension-diffs-paths.mjs";
|
import { isDiffsExtensionRoot } from "../vitest.extension-diffs-paths.mjs";
|
||||||
@@ -19,7 +22,10 @@ import { isTelegramExtensionRoot } from "../vitest.extension-telegram-paths.mjs"
|
|||||||
import { isVoiceCallExtensionRoot } from "../vitest.extension-voice-call-paths.mjs";
|
import { isVoiceCallExtensionRoot } from "../vitest.extension-voice-call-paths.mjs";
|
||||||
import { isWhatsAppExtensionRoot } from "../vitest.extension-whatsapp-paths.mjs";
|
import { isWhatsAppExtensionRoot } from "../vitest.extension-whatsapp-paths.mjs";
|
||||||
import { isZaloExtensionRoot } from "../vitest.extension-zalo-paths.mjs";
|
import { isZaloExtensionRoot } from "../vitest.extension-zalo-paths.mjs";
|
||||||
import { isPluginSdkLightTestFile } from "../vitest.plugin-sdk-paths.mjs";
|
import {
|
||||||
|
isPluginSdkLightTarget,
|
||||||
|
resolvePluginSdkLightIncludePattern,
|
||||||
|
} from "../vitest.plugin-sdk-paths.mjs";
|
||||||
import { isBoundaryTestFile, isBundledPluginDependentUnitTestFile } from "../vitest.unit-paths.mjs";
|
import { isBoundaryTestFile, isBundledPluginDependentUnitTestFile } from "../vitest.unit-paths.mjs";
|
||||||
import { resolveVitestCliEntry, resolveVitestNodeArgs } from "./run-vitest.mjs";
|
import { resolveVitestCliEntry, resolveVitestNodeArgs } from "./run-vitest.mjs";
|
||||||
|
|
||||||
@@ -320,7 +326,7 @@ function classifyTarget(arg, cwd) {
|
|||||||
return "logging";
|
return "logging";
|
||||||
}
|
}
|
||||||
if (relative.startsWith("src/plugin-sdk/")) {
|
if (relative.startsWith("src/plugin-sdk/")) {
|
||||||
return isPluginSdkLightTestFile(relative) ? "pluginSdkLight" : "pluginSdk";
|
return isPluginSdkLightTarget(relative) ? "pluginSdkLight" : "pluginSdk";
|
||||||
}
|
}
|
||||||
if (relative.startsWith("src/process/")) {
|
if (relative.startsWith("src/process/")) {
|
||||||
return "process";
|
return "process";
|
||||||
@@ -344,7 +350,7 @@ function classifyTarget(arg, cwd) {
|
|||||||
return "cli";
|
return "cli";
|
||||||
}
|
}
|
||||||
if (relative.startsWith("src/commands/")) {
|
if (relative.startsWith("src/commands/")) {
|
||||||
return isCommandsLightTestFile(relative) ? "commandLight" : "command";
|
return isCommandsLightTarget(relative) ? "commandLight" : "command";
|
||||||
}
|
}
|
||||||
if (relative.startsWith("src/auto-reply/")) {
|
if (relative.startsWith("src/auto-reply/")) {
|
||||||
return "autoReply";
|
return "autoReply";
|
||||||
@@ -367,6 +373,19 @@ function classifyTarget(arg, cwd) {
|
|||||||
return "default";
|
return "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveLightLaneIncludePatterns(kind, targetArg, cwd) {
|
||||||
|
const relative = toRepoRelativeTarget(targetArg, cwd);
|
||||||
|
if (kind === "pluginSdkLight") {
|
||||||
|
const includePattern = resolvePluginSdkLightIncludePattern(relative);
|
||||||
|
return includePattern ? [includePattern] : null;
|
||||||
|
}
|
||||||
|
if (kind === "commandLight") {
|
||||||
|
const includePattern = resolveCommandsLightIncludePattern(relative);
|
||||||
|
return includePattern ? [includePattern] : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function createVitestArgs(params) {
|
function createVitestArgs(params) {
|
||||||
return [
|
return [
|
||||||
"exec",
|
"exec",
|
||||||
@@ -618,7 +637,10 @@ export function buildVitestRunPlans(
|
|||||||
grouped.every((targetArg) => isFileLikeTarget(toRepoRelativeTarget(targetArg, cwd))));
|
grouped.every((targetArg) => isFileLikeTarget(toRepoRelativeTarget(targetArg, cwd))));
|
||||||
const includePatterns = useCliTargetArgs
|
const includePatterns = useCliTargetArgs
|
||||||
? null
|
? null
|
||||||
: grouped.map((targetArg) => toScopedIncludePattern(targetArg, cwd));
|
: grouped.flatMap((targetArg) => {
|
||||||
|
const lightLanePatterns = resolveLightLaneIncludePatterns(kind, targetArg, cwd);
|
||||||
|
return lightLanePatterns ?? [toScopedIncludePattern(targetArg, cwd)];
|
||||||
|
});
|
||||||
const scopedTargetArgs = useCliTargetArgs ? grouped : [];
|
const scopedTargetArgs = useCliTargetArgs ? grouped : [];
|
||||||
plans.push({
|
plans.push({
|
||||||
config,
|
config,
|
||||||
|
|||||||
@@ -467,9 +467,15 @@ const CORE_SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [
|
let cachedSecretTargetRegistry: SecretTargetRegistryEntry[] | null = null;
|
||||||
...CORE_SECRET_TARGET_REGISTRY,
|
|
||||||
...listChannelSecretTargetRegistryEntries(),
|
|
||||||
];
|
|
||||||
|
|
||||||
export { SECRET_TARGET_REGISTRY };
|
export function getSecretTargetRegistry(): SecretTargetRegistryEntry[] {
|
||||||
|
if (cachedSecretTargetRegistry) {
|
||||||
|
return cachedSecretTargetRegistry;
|
||||||
|
}
|
||||||
|
cachedSecretTargetRegistry = [
|
||||||
|
...CORE_SECRET_TARGET_REGISTRY,
|
||||||
|
...listChannelSecretTargetRegistryEntries(),
|
||||||
|
];
|
||||||
|
return cachedSecretTargetRegistry;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { OpenClawConfig } from "../config/config.js";
|
import type { OpenClawConfig } from "../config/config.js";
|
||||||
import { getPath } from "./path-utils.js";
|
import { getPath } from "./path-utils.js";
|
||||||
import { SECRET_TARGET_REGISTRY } from "./target-registry-data.js";
|
import { getSecretTargetRegistry } from "./target-registry-data.js";
|
||||||
import {
|
import {
|
||||||
compileTargetRegistryEntry,
|
compileTargetRegistryEntry,
|
||||||
expandPathTokens,
|
expandPathTokens,
|
||||||
@@ -14,15 +14,19 @@ import type {
|
|||||||
SecretTargetRegistryEntry,
|
SecretTargetRegistryEntry,
|
||||||
} from "./target-registry-types.js";
|
} from "./target-registry-types.js";
|
||||||
|
|
||||||
const COMPILED_SECRET_TARGET_REGISTRY = SECRET_TARGET_REGISTRY.map(compileTargetRegistryEntry);
|
let compiledSecretTargetRegistryState: {
|
||||||
const OPENCLAW_COMPILED_SECRET_TARGETS = COMPILED_SECRET_TARGET_REGISTRY.filter(
|
authProfilesCompiledSecretTargets: CompiledTargetRegistryEntry[];
|
||||||
(entry) => entry.configFile === "openclaw.json",
|
authProfilesTargetsById: Map<string, CompiledTargetRegistryEntry[]>;
|
||||||
);
|
compiledSecretTargetRegistry: CompiledTargetRegistryEntry[];
|
||||||
const AUTH_PROFILES_COMPILED_SECRET_TARGETS = COMPILED_SECRET_TARGET_REGISTRY.filter(
|
knownTargetIds: Set<string>;
|
||||||
(entry) => entry.configFile === "auth-profiles.json",
|
openClawCompiledSecretTargets: CompiledTargetRegistryEntry[];
|
||||||
);
|
openClawTargetsById: Map<string, CompiledTargetRegistryEntry[]>;
|
||||||
|
targetsByType: Map<string, CompiledTargetRegistryEntry[]>;
|
||||||
|
} | null = null;
|
||||||
|
|
||||||
function buildTargetTypeIndex(): Map<string, CompiledTargetRegistryEntry[]> {
|
function buildTargetTypeIndex(
|
||||||
|
compiledSecretTargetRegistry: CompiledTargetRegistryEntry[],
|
||||||
|
): Map<string, CompiledTargetRegistryEntry[]> {
|
||||||
const byType = new Map<string, CompiledTargetRegistryEntry[]>();
|
const byType = new Map<string, CompiledTargetRegistryEntry[]>();
|
||||||
const append = (type: string, entry: CompiledTargetRegistryEntry) => {
|
const append = (type: string, entry: CompiledTargetRegistryEntry) => {
|
||||||
const existing = byType.get(type);
|
const existing = byType.get(type);
|
||||||
@@ -32,7 +36,7 @@ function buildTargetTypeIndex(): Map<string, CompiledTargetRegistryEntry[]> {
|
|||||||
}
|
}
|
||||||
byType.set(type, [entry]);
|
byType.set(type, [entry]);
|
||||||
};
|
};
|
||||||
for (const entry of COMPILED_SECRET_TARGET_REGISTRY) {
|
for (const entry of compiledSecretTargetRegistry) {
|
||||||
append(entry.targetType, entry);
|
append(entry.targetType, entry);
|
||||||
for (const alias of entry.targetTypeAliases ?? []) {
|
for (const alias of entry.targetTypeAliases ?? []) {
|
||||||
append(alias, entry);
|
append(alias, entry);
|
||||||
@@ -41,12 +45,11 @@ function buildTargetTypeIndex(): Map<string, CompiledTargetRegistryEntry[]> {
|
|||||||
return byType;
|
return byType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TARGETS_BY_TYPE = buildTargetTypeIndex();
|
function buildConfigTargetIdIndex(
|
||||||
const KNOWN_TARGET_IDS = new Set(COMPILED_SECRET_TARGET_REGISTRY.map((entry) => entry.id));
|
entries: CompiledTargetRegistryEntry[],
|
||||||
|
): Map<string, CompiledTargetRegistryEntry[]> {
|
||||||
function buildConfigTargetIdIndex(): Map<string, CompiledTargetRegistryEntry[]> {
|
|
||||||
const byId = new Map<string, CompiledTargetRegistryEntry[]>();
|
const byId = new Map<string, CompiledTargetRegistryEntry[]>();
|
||||||
for (const entry of OPENCLAW_COMPILED_SECRET_TARGETS) {
|
for (const entry of entries) {
|
||||||
const existing = byId.get(entry.id);
|
const existing = byId.get(entry.id);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
existing.push(entry);
|
existing.push(entry);
|
||||||
@@ -57,23 +60,29 @@ function buildConfigTargetIdIndex(): Map<string, CompiledTargetRegistryEntry[]>
|
|||||||
return byId;
|
return byId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OPENCLAW_TARGETS_BY_ID = buildConfigTargetIdIndex();
|
function getCompiledSecretTargetRegistryState() {
|
||||||
|
if (compiledSecretTargetRegistryState) {
|
||||||
function buildAuthProfileTargetIdIndex(): Map<string, CompiledTargetRegistryEntry[]> {
|
return compiledSecretTargetRegistryState;
|
||||||
const byId = new Map<string, CompiledTargetRegistryEntry[]>();
|
|
||||||
for (const entry of AUTH_PROFILES_COMPILED_SECRET_TARGETS) {
|
|
||||||
const existing = byId.get(entry.id);
|
|
||||||
if (existing) {
|
|
||||||
existing.push(entry);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
byId.set(entry.id, [entry]);
|
|
||||||
}
|
}
|
||||||
return byId;
|
const compiledSecretTargetRegistry = getSecretTargetRegistry().map(compileTargetRegistryEntry);
|
||||||
|
const openClawCompiledSecretTargets = compiledSecretTargetRegistry.filter(
|
||||||
|
(entry) => entry.configFile === "openclaw.json",
|
||||||
|
);
|
||||||
|
const authProfilesCompiledSecretTargets = compiledSecretTargetRegistry.filter(
|
||||||
|
(entry) => entry.configFile === "auth-profiles.json",
|
||||||
|
);
|
||||||
|
compiledSecretTargetRegistryState = {
|
||||||
|
authProfilesCompiledSecretTargets,
|
||||||
|
authProfilesTargetsById: buildConfigTargetIdIndex(authProfilesCompiledSecretTargets),
|
||||||
|
compiledSecretTargetRegistry,
|
||||||
|
knownTargetIds: new Set(compiledSecretTargetRegistry.map((entry) => entry.id)),
|
||||||
|
openClawCompiledSecretTargets,
|
||||||
|
openClawTargetsById: buildConfigTargetIdIndex(openClawCompiledSecretTargets),
|
||||||
|
targetsByType: buildTargetTypeIndex(compiledSecretTargetRegistry),
|
||||||
|
};
|
||||||
|
return compiledSecretTargetRegistryState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AUTH_PROFILES_TARGETS_BY_ID = buildAuthProfileTargetIdIndex();
|
|
||||||
|
|
||||||
function normalizeAllowedTargetIds(targetIds?: Iterable<string>): Set<string> | null {
|
function normalizeAllowedTargetIds(targetIds?: Iterable<string>): Set<string> | null {
|
||||||
if (targetIds === undefined) {
|
if (targetIds === undefined) {
|
||||||
return null;
|
return null;
|
||||||
@@ -170,7 +179,7 @@ function toResolvedPlanTarget(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function listSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] {
|
export function listSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] {
|
||||||
return COMPILED_SECRET_TARGET_REGISTRY.map((entry) => ({
|
return getCompiledSecretTargetRegistryState().compiledSecretTargetRegistry.map((entry) => ({
|
||||||
id: entry.id,
|
id: entry.id,
|
||||||
targetType: entry.targetType,
|
targetType: entry.targetType,
|
||||||
...(entry.targetTypeAliases ? { targetTypeAliases: [...entry.targetTypeAliases] } : {}),
|
...(entry.targetTypeAliases ? { targetTypeAliases: [...entry.targetTypeAliases] } : {}),
|
||||||
@@ -194,11 +203,15 @@ export function listSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isKnownSecretTargetType(value: unknown): value is string {
|
export function isKnownSecretTargetType(value: unknown): value is string {
|
||||||
return typeof value === "string" && TARGETS_BY_TYPE.has(value);
|
return (
|
||||||
|
typeof value === "string" && getCompiledSecretTargetRegistryState().targetsByType.has(value)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isKnownSecretTargetId(value: unknown): value is string {
|
export function isKnownSecretTargetId(value: unknown): value is string {
|
||||||
return typeof value === "string" && KNOWN_TARGET_IDS.has(value);
|
return (
|
||||||
|
typeof value === "string" && getCompiledSecretTargetRegistryState().knownTargetIds.has(value)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolvePlanTargetAgainstRegistry(candidate: {
|
export function resolvePlanTargetAgainstRegistry(candidate: {
|
||||||
@@ -207,7 +220,7 @@ export function resolvePlanTargetAgainstRegistry(candidate: {
|
|||||||
providerId?: string;
|
providerId?: string;
|
||||||
accountId?: string;
|
accountId?: string;
|
||||||
}): ResolvedPlanTarget | null {
|
}): ResolvedPlanTarget | null {
|
||||||
const entries = TARGETS_BY_TYPE.get(candidate.type);
|
const entries = getCompiledSecretTargetRegistryState().targetsByType.get(candidate.type);
|
||||||
if (!entries || entries.length === 0) {
|
if (!entries || entries.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -240,7 +253,7 @@ export function resolvePlanTargetAgainstRegistry(candidate: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function resolveConfigSecretTargetByPath(pathSegments: string[]): ResolvedPlanTarget | null {
|
export function resolveConfigSecretTargetByPath(pathSegments: string[]): ResolvedPlanTarget | null {
|
||||||
for (const entry of OPENCLAW_COMPILED_SECRET_TARGETS) {
|
for (const entry of getCompiledSecretTargetRegistryState().openClawCompiledSecretTargets) {
|
||||||
if (!entry.includeInPlan) {
|
if (!entry.includeInPlan) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -268,10 +281,11 @@ export function discoverConfigSecretTargetsByIds(
|
|||||||
targetIds?: Iterable<string>,
|
targetIds?: Iterable<string>,
|
||||||
): DiscoveredConfigSecretTarget[] {
|
): DiscoveredConfigSecretTarget[] {
|
||||||
const allowedTargetIds = normalizeAllowedTargetIds(targetIds);
|
const allowedTargetIds = normalizeAllowedTargetIds(targetIds);
|
||||||
|
const registryState = getCompiledSecretTargetRegistryState();
|
||||||
const discoveryEntries = resolveDiscoveryEntries({
|
const discoveryEntries = resolveDiscoveryEntries({
|
||||||
allowedTargetIds,
|
allowedTargetIds,
|
||||||
defaultEntries: OPENCLAW_COMPILED_SECRET_TARGETS,
|
defaultEntries: registryState.openClawCompiledSecretTargets,
|
||||||
entriesById: OPENCLAW_TARGETS_BY_ID,
|
entriesById: registryState.openClawTargetsById,
|
||||||
});
|
});
|
||||||
return discoverSecretTargetsFromEntries(config, discoveryEntries);
|
return discoverSecretTargetsFromEntries(config, discoveryEntries);
|
||||||
}
|
}
|
||||||
@@ -285,16 +299,17 @@ export function discoverAuthProfileSecretTargetsByIds(
|
|||||||
targetIds?: Iterable<string>,
|
targetIds?: Iterable<string>,
|
||||||
): DiscoveredConfigSecretTarget[] {
|
): DiscoveredConfigSecretTarget[] {
|
||||||
const allowedTargetIds = normalizeAllowedTargetIds(targetIds);
|
const allowedTargetIds = normalizeAllowedTargetIds(targetIds);
|
||||||
|
const registryState = getCompiledSecretTargetRegistryState();
|
||||||
const discoveryEntries = resolveDiscoveryEntries({
|
const discoveryEntries = resolveDiscoveryEntries({
|
||||||
allowedTargetIds,
|
allowedTargetIds,
|
||||||
defaultEntries: AUTH_PROFILES_COMPILED_SECRET_TARGETS,
|
defaultEntries: registryState.authProfilesCompiledSecretTargets,
|
||||||
entriesById: AUTH_PROFILES_TARGETS_BY_ID,
|
entriesById: registryState.authProfilesTargetsById,
|
||||||
});
|
});
|
||||||
return discoverSecretTargetsFromEntries(store, discoveryEntries);
|
return discoverSecretTargetsFromEntries(store, discoveryEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listAuthProfileSecretTargetEntries(): SecretTargetRegistryEntry[] {
|
export function listAuthProfileSecretTargetEntries(): SecretTargetRegistryEntry[] {
|
||||||
return COMPILED_SECRET_TARGET_REGISTRY.filter(
|
return getCompiledSecretTargetRegistryState().compiledSecretTargetRegistry.filter(
|
||||||
(entry) => entry.configFile === "auth-profiles.json" && entry.includeInAudit,
|
(entry) => entry.configFile === "auth-profiles.json" && entry.includeInAudit,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,4 +93,64 @@ describe("scripts/test-projects changed-target routing", () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("routes changed plugin-sdk source allowlist files to sibling light tests", () => {
|
||||||
|
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
|
||||||
|
"src/plugin-sdk/lazy-value.ts",
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(plans).toEqual([
|
||||||
|
{
|
||||||
|
config: "vitest.plugin-sdk-light.config.ts",
|
||||||
|
forwardedArgs: [],
|
||||||
|
includePatterns: ["src/plugin-sdk/lazy-value.test.ts"],
|
||||||
|
watchMode: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("routes changed commands source allowlist files to sibling light tests", () => {
|
||||||
|
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
|
||||||
|
"src/commands/status-overview-values.ts",
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(plans).toEqual([
|
||||||
|
{
|
||||||
|
config: "vitest.commands-light.config.ts",
|
||||||
|
forwardedArgs: [],
|
||||||
|
includePatterns: ["src/commands/status-overview-values.test.ts"],
|
||||||
|
watchMode: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps non-allowlisted plugin-sdk source files on the heavy lane", () => {
|
||||||
|
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
|
||||||
|
"src/plugin-sdk/facade-runtime.ts",
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(plans).toEqual([
|
||||||
|
{
|
||||||
|
config: "vitest.plugin-sdk.config.ts",
|
||||||
|
forwardedArgs: [],
|
||||||
|
includePatterns: ["src/plugin-sdk/**/*.test.ts"],
|
||||||
|
watchMode: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps non-allowlisted commands source files on the heavy lane", () => {
|
||||||
|
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
|
||||||
|
"src/commands/channels.add.ts",
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(plans).toEqual([
|
||||||
|
{
|
||||||
|
config: "vitest.commands.config.ts",
|
||||||
|
forwardedArgs: [],
|
||||||
|
includePatterns: ["src/commands/**/*.test.ts"],
|
||||||
|
watchMode: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import {
|
||||||
|
isCommandsLightTarget,
|
||||||
|
resolveCommandsLightIncludePattern,
|
||||||
|
} from "../vitest.commands-light-paths.mjs";
|
||||||
|
import {
|
||||||
|
isPluginSdkLightTarget,
|
||||||
|
resolvePluginSdkLightIncludePattern,
|
||||||
|
} from "../vitest.plugin-sdk-paths.mjs";
|
||||||
|
|
||||||
|
describe("light vitest path routing", () => {
|
||||||
|
it("maps plugin-sdk allowlist source and test files to sibling light tests", () => {
|
||||||
|
expect(isPluginSdkLightTarget("src/plugin-sdk/lazy-value.ts")).toBe(true);
|
||||||
|
expect(isPluginSdkLightTarget("src/plugin-sdk/lazy-value.test.ts")).toBe(true);
|
||||||
|
expect(resolvePluginSdkLightIncludePattern("src/plugin-sdk/lazy-value.ts")).toBe(
|
||||||
|
"src/plugin-sdk/lazy-value.test.ts",
|
||||||
|
);
|
||||||
|
expect(resolvePluginSdkLightIncludePattern("src/plugin-sdk/lazy-value.test.ts")).toBe(
|
||||||
|
"src/plugin-sdk/lazy-value.test.ts",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps non-allowlisted plugin-sdk files off the light lane", () => {
|
||||||
|
expect(isPluginSdkLightTarget("src/plugin-sdk/facade-runtime.ts")).toBe(false);
|
||||||
|
expect(resolvePluginSdkLightIncludePattern("src/plugin-sdk/facade-runtime.ts")).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps commands allowlist source and test files to sibling light tests", () => {
|
||||||
|
expect(isCommandsLightTarget("src/commands/text-format.ts")).toBe(true);
|
||||||
|
expect(isCommandsLightTarget("src/commands/text-format.test.ts")).toBe(true);
|
||||||
|
expect(resolveCommandsLightIncludePattern("src/commands/text-format.ts")).toBe(
|
||||||
|
"src/commands/text-format.test.ts",
|
||||||
|
);
|
||||||
|
expect(resolveCommandsLightIncludePattern("src/commands/text-format.test.ts")).toBe(
|
||||||
|
"src/commands/text-format.test.ts",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps non-allowlisted commands files off the light lane", () => {
|
||||||
|
expect(isCommandsLightTarget("src/commands/channels.add.ts")).toBe(false);
|
||||||
|
expect(resolveCommandsLightIncludePattern("src/commands/channels.add.ts")).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,12 +1,53 @@
|
|||||||
const normalizeRepoPath = (value) => value.replaceAll("\\", "/");
|
const normalizeRepoPath = (value) => value.replaceAll("\\", "/");
|
||||||
|
|
||||||
export const commandsLightTestFiles = [
|
const commandsLightEntries = [
|
||||||
"src/commands/cleanup-utils.test.ts",
|
{ source: "src/commands/cleanup-utils.ts", test: "src/commands/cleanup-utils.test.ts" },
|
||||||
"src/commands/dashboard.links.test.ts",
|
{
|
||||||
"src/commands/doctor-browser.test.ts",
|
source: "src/commands/dashboard.links.ts",
|
||||||
"src/commands/doctor-gateway-auth-token.test.ts",
|
test: "src/commands/dashboard.links.test.ts",
|
||||||
|
},
|
||||||
|
{ source: "src/commands/doctor-browser.ts", test: "src/commands/doctor-browser.test.ts" },
|
||||||
|
{
|
||||||
|
source: "src/commands/doctor-gateway-auth-token.ts",
|
||||||
|
test: "src/commands/doctor-gateway-auth-token.test.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "src/commands/sandbox-formatters.ts",
|
||||||
|
test: "src/commands/sandbox-formatters.test.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "src/commands/status-overview-rows.ts",
|
||||||
|
test: "src/commands/status-overview-rows.test.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "src/commands/status-overview-surface.ts",
|
||||||
|
test: "src/commands/status-overview-surface.test.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "src/commands/status-overview-values.ts",
|
||||||
|
test: "src/commands/status-overview-values.test.ts",
|
||||||
|
},
|
||||||
|
{ source: "src/commands/text-format.ts", test: "src/commands/text-format.test.ts" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const commandsLightIncludePatternByFile = new Map(
|
||||||
|
commandsLightEntries.flatMap(({ source, test }) => [
|
||||||
|
[source, test],
|
||||||
|
[test, test],
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const commandsLightSourceFiles = commandsLightEntries.map(({ source }) => source);
|
||||||
|
export const commandsLightTestFiles = commandsLightEntries.map(({ test }) => test);
|
||||||
|
|
||||||
|
export function isCommandsLightTarget(file) {
|
||||||
|
return commandsLightIncludePatternByFile.has(normalizeRepoPath(file));
|
||||||
|
}
|
||||||
|
|
||||||
export function isCommandsLightTestFile(file) {
|
export function isCommandsLightTestFile(file) {
|
||||||
return commandsLightTestFiles.includes(normalizeRepoPath(file));
|
return commandsLightTestFiles.includes(normalizeRepoPath(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveCommandsLightIncludePattern(file) {
|
||||||
|
return commandsLightIncludePatternByFile.get(normalizeRepoPath(file)) ?? null;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,14 +1,56 @@
|
|||||||
const normalizeRepoPath = (value) => value.replaceAll("\\", "/");
|
const normalizeRepoPath = (value) => value.replaceAll("\\", "/");
|
||||||
|
|
||||||
export const pluginSdkLightTestFiles = [
|
const pluginSdkLightEntries = [
|
||||||
"src/plugin-sdk/acp-runtime.test.ts",
|
{ source: "src/plugin-sdk/acp-runtime.ts", test: "src/plugin-sdk/acp-runtime.test.ts" },
|
||||||
"src/plugin-sdk/provider-entry.test.ts",
|
{ source: "src/plugin-sdk/allow-from.ts", test: "src/plugin-sdk/allow-from.test.ts" },
|
||||||
"src/plugin-sdk/runtime.test.ts",
|
{
|
||||||
"src/plugin-sdk/temp-path.test.ts",
|
source: "src/plugin-sdk/keyed-async-queue.ts",
|
||||||
"src/plugin-sdk/text-chunking.test.ts",
|
test: "src/plugin-sdk/keyed-async-queue.test.ts",
|
||||||
"src/plugin-sdk/webhook-targets.test.ts",
|
},
|
||||||
|
{ source: "src/plugin-sdk/lazy-value.ts", test: "src/plugin-sdk/lazy-value.test.ts" },
|
||||||
|
{
|
||||||
|
source: "src/plugin-sdk/persistent-dedupe.ts",
|
||||||
|
test: "src/plugin-sdk/persistent-dedupe.test.ts",
|
||||||
|
},
|
||||||
|
{ source: "src/plugin-sdk/provider-entry.ts", test: "src/plugin-sdk/provider-entry.test.ts" },
|
||||||
|
{
|
||||||
|
source: "src/plugin-sdk/provider-model-shared.ts",
|
||||||
|
test: "src/plugin-sdk/provider-model-shared.test.ts",
|
||||||
|
},
|
||||||
|
{ source: "src/plugin-sdk/provider-tools.ts", test: "src/plugin-sdk/provider-tools.test.ts" },
|
||||||
|
{
|
||||||
|
source: "src/plugin-sdk/status-helpers.ts",
|
||||||
|
test: "src/plugin-sdk/status-helpers.test.ts",
|
||||||
|
},
|
||||||
|
{ source: "src/plugin-sdk/temp-path.ts", test: "src/plugin-sdk/temp-path.test.ts" },
|
||||||
|
{
|
||||||
|
source: "src/plugin-sdk/text-chunking.ts",
|
||||||
|
test: "src/plugin-sdk/text-chunking.test.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "src/plugin-sdk/webhook-targets.ts",
|
||||||
|
test: "src/plugin-sdk/webhook-targets.test.ts",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const pluginSdkLightIncludePatternByFile = new Map(
|
||||||
|
pluginSdkLightEntries.flatMap(({ source, test }) => [
|
||||||
|
[source, test],
|
||||||
|
[test, test],
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const pluginSdkLightSourceFiles = pluginSdkLightEntries.map(({ source }) => source);
|
||||||
|
export const pluginSdkLightTestFiles = pluginSdkLightEntries.map(({ test }) => test);
|
||||||
|
|
||||||
|
export function isPluginSdkLightTarget(file) {
|
||||||
|
return pluginSdkLightIncludePatternByFile.has(normalizeRepoPath(file));
|
||||||
|
}
|
||||||
|
|
||||||
export function isPluginSdkLightTestFile(file) {
|
export function isPluginSdkLightTestFile(file) {
|
||||||
return pluginSdkLightTestFiles.includes(normalizeRepoPath(file));
|
return pluginSdkLightTestFiles.includes(normalizeRepoPath(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolvePluginSdkLightIncludePattern(file) {
|
||||||
|
return pluginSdkLightIncludePatternByFile.get(normalizeRepoPath(file)) ?? null;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user