mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:50:49 +00:00
ci: split remaining slow CI lanes
This commit is contained in:
54
scripts/lib/channel-contract-test-plan.mjs
Normal file
54
scripts/lib/channel-contract-test-plan.mjs
Normal file
@@ -0,0 +1,54 @@
|
||||
import { existsSync, readdirSync } from "node:fs";
|
||||
import { join, relative } from "node:path";
|
||||
|
||||
function listContractTestFiles(rootDir = "src/channels/plugins/contracts") {
|
||||
if (!existsSync(rootDir)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return readdirSync(rootDir, { withFileTypes: true })
|
||||
.filter((entry) => entry.isFile() && entry.name.endsWith(".test.ts"))
|
||||
.map((entry) => join(rootDir, entry.name).replaceAll("\\", "/"))
|
||||
.toSorted((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
export function createChannelContractTestShards() {
|
||||
const rootDir = "src/channels/plugins/contracts";
|
||||
const groups = {
|
||||
"checks-fast-contracts-channels-registry-a": [],
|
||||
"checks-fast-contracts-channels-registry-b": [],
|
||||
"checks-fast-contracts-channels-core-a": [],
|
||||
"checks-fast-contracts-channels-core-b": [],
|
||||
"checks-fast-contracts-channels-extensions": [],
|
||||
};
|
||||
const pushBalanced = (firstKey, secondKey, file) => {
|
||||
const target = groups[firstKey].length <= groups[secondKey].length ? firstKey : secondKey;
|
||||
groups[target].push(file);
|
||||
};
|
||||
|
||||
for (const file of listContractTestFiles(rootDir)) {
|
||||
const name = relative(rootDir, file).replaceAll("\\", "/");
|
||||
if (name.startsWith("plugins-core-extension.")) {
|
||||
groups["checks-fast-contracts-channels-extensions"].push(file);
|
||||
} else if (name.startsWith("plugins-core.") || name.startsWith("plugin.")) {
|
||||
pushBalanced(
|
||||
"checks-fast-contracts-channels-core-a",
|
||||
"checks-fast-contracts-channels-core-b",
|
||||
file,
|
||||
);
|
||||
} else {
|
||||
pushBalanced(
|
||||
"checks-fast-contracts-channels-registry-a",
|
||||
"checks-fast-contracts-channels-registry-b",
|
||||
file,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Object.entries(groups).map(([checkName, includePatterns]) => ({
|
||||
checkName,
|
||||
includePatterns,
|
||||
task: "contracts-channels",
|
||||
runtime: "node",
|
||||
}));
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { existsSync, readdirSync } from "node:fs";
|
||||
import { join, relative } from "node:path";
|
||||
import { fullSuiteVitestShards } from "../../test/vitest/vitest.test-shards.mjs";
|
||||
|
||||
const EXCLUDED_FULL_SUITE_SHARDS = new Set([
|
||||
@@ -7,7 +9,137 @@ const EXCLUDED_FULL_SUITE_SHARDS = new Set([
|
||||
]);
|
||||
|
||||
const EXCLUDED_PROJECT_CONFIGS = new Set(["test/vitest/vitest.channels.config.ts"]);
|
||||
function listTestFiles(rootDir) {
|
||||
if (!existsSync(rootDir)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const files = [];
|
||||
const visit = (dir) => {
|
||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||
const path = join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
visit(path);
|
||||
continue;
|
||||
}
|
||||
if (entry.isFile() && entry.name.endsWith(".test.ts")) {
|
||||
files.push(path.replaceAll("\\", "/"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
visit(rootDir);
|
||||
return files.toSorted((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
function createAutoReplyReplySplitShards() {
|
||||
const files = listTestFiles("src/auto-reply/reply");
|
||||
const groups = {
|
||||
"auto-reply-reply-agent-runner": [],
|
||||
"auto-reply-reply-commands": [],
|
||||
"auto-reply-reply-dispatch": [],
|
||||
"auto-reply-reply-state-routing": [],
|
||||
};
|
||||
|
||||
for (const file of files) {
|
||||
const name = relative("src/auto-reply/reply", file).replaceAll("\\", "/");
|
||||
if (
|
||||
name.startsWith("agent-runner") ||
|
||||
name.startsWith("acp-") ||
|
||||
name === "abort.test.ts" ||
|
||||
name === "bash-command.stop.test.ts" ||
|
||||
name.startsWith("block-")
|
||||
) {
|
||||
groups["auto-reply-reply-agent-runner"].push(file);
|
||||
} else if (name.startsWith("commands")) {
|
||||
groups["auto-reply-reply-commands"].push(file);
|
||||
} else if (
|
||||
name.startsWith("directive-") ||
|
||||
name.startsWith("dispatch") ||
|
||||
name.startsWith("followup-") ||
|
||||
name.startsWith("get-reply")
|
||||
) {
|
||||
groups["auto-reply-reply-dispatch"].push(file);
|
||||
} else {
|
||||
groups["auto-reply-reply-state-routing"].push(file);
|
||||
}
|
||||
}
|
||||
|
||||
return Object.entries(groups).flatMap(([groupName, includePatterns]) => {
|
||||
const midpoint = Math.ceil(includePatterns.length / 2);
|
||||
return [
|
||||
{
|
||||
shardName: `${groupName}-a`,
|
||||
configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
|
||||
includePatterns: includePatterns.slice(0, midpoint),
|
||||
requiresDist: false,
|
||||
},
|
||||
{
|
||||
shardName: `${groupName}-b`,
|
||||
configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
|
||||
includePatterns: includePatterns.slice(midpoint),
|
||||
requiresDist: false,
|
||||
},
|
||||
].filter((shard) => shard.includePatterns.length > 0);
|
||||
});
|
||||
}
|
||||
|
||||
const SPLIT_NODE_SHARDS = new Map([
|
||||
[
|
||||
"core-runtime",
|
||||
[
|
||||
{
|
||||
shardName: "core-runtime-infra",
|
||||
configs: [
|
||||
"test/vitest/vitest.infra.config.ts",
|
||||
"test/vitest/vitest.hooks.config.ts",
|
||||
"test/vitest/vitest.runtime-config.config.ts",
|
||||
"test/vitest/vitest.secrets.config.ts",
|
||||
"test/vitest/vitest.logging.config.ts",
|
||||
"test/vitest/vitest.process.config.ts",
|
||||
],
|
||||
requiresDist: true,
|
||||
},
|
||||
{
|
||||
shardName: "core-runtime-media-ui",
|
||||
configs: [
|
||||
"test/vitest/vitest.media.config.ts",
|
||||
"test/vitest/vitest.media-understanding.config.ts",
|
||||
"test/vitest/vitest.tui.config.ts",
|
||||
"test/vitest/vitest.ui.config.ts",
|
||||
"test/vitest/vitest.wizard.config.ts",
|
||||
],
|
||||
requiresDist: true,
|
||||
},
|
||||
{
|
||||
shardName: "core-runtime-shared",
|
||||
configs: [
|
||||
"test/vitest/vitest.acp.config.ts",
|
||||
"test/vitest/vitest.cron.config.ts",
|
||||
"test/vitest/vitest.shared-core.config.ts",
|
||||
"test/vitest/vitest.tasks.config.ts",
|
||||
"test/vitest/vitest.utils.config.ts",
|
||||
],
|
||||
requiresDist: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
"auto-reply",
|
||||
[
|
||||
{
|
||||
shardName: "auto-reply-core",
|
||||
configs: ["test/vitest/vitest.auto-reply-core.config.ts"],
|
||||
requiresDist: false,
|
||||
},
|
||||
{
|
||||
shardName: "auto-reply-top-level",
|
||||
configs: ["test/vitest/vitest.auto-reply-top-level.config.ts"],
|
||||
requiresDist: false,
|
||||
},
|
||||
...createAutoReplyReplySplitShards(),
|
||||
],
|
||||
],
|
||||
[
|
||||
"agentic",
|
||||
[
|
||||
@@ -77,6 +209,7 @@ export function createNodeTestShards() {
|
||||
checkName: formatNodeTestShardCheckName(splitShard.shardName),
|
||||
shardName: splitShard.shardName,
|
||||
configs: splitConfigs,
|
||||
...(splitShard.includePatterns ? { includePatterns: splitShard.includePatterns } : {}),
|
||||
requiresDist: splitShard.requiresDist,
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user