mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-22 23:21:17 +00:00
perf(ci): balance node test shards and gate heavy CI lanes by changed scope (#108091)
This commit is contained in:
committed by
GitHub
parent
9b6361a50c
commit
57761ebe8c
113
.github/workflows/ci.yml
vendored
113
.github/workflows/ci.yml
vendored
@@ -540,8 +540,22 @@ jobs:
|
||||
console.warn(`Changed Node test planning failed; using compact full suite: ${error}`);
|
||||
}
|
||||
}
|
||||
// Targeted (narrow-diff) PRs skip the heavy packaging lanes unless the
|
||||
// diff touches surfaces those lanes exist to prove: test-only diffs
|
||||
// cannot change dist bytes, and QA smoke re-proves packaging/scenario
|
||||
// surfaces that unit shards plus build smokes already cover elsewhere.
|
||||
const changedScopeHasBuildImpact =
|
||||
changedNodeTestShards === null ||
|
||||
typeof changedNodeTestPlan.hasBuildArtifactAffectingChange !== "function" ||
|
||||
changedNodeTestPlan.hasBuildArtifactAffectingChange(changedPaths);
|
||||
const changedScopeHasQaImpact =
|
||||
changedNodeTestShards === null ||
|
||||
typeof changedNodeTestPlan.hasQaSmokeAffectingChange !== "function" ||
|
||||
changedNodeTestPlan.hasQaSmokeAffectingChange(changedPaths);
|
||||
const runBuildArtifacts = runNodeFull && changedScopeHasBuildImpact;
|
||||
const runQaSmokeCi =
|
||||
runNodeFull &&
|
||||
changedScopeHasQaImpact &&
|
||||
(!frozenTarget || existsSync("extensions/qa-lab/src/ci-smoke-plan.ts"));
|
||||
const nodeTestShards = runNodeFull
|
||||
? (changedNodeTestShards
|
||||
@@ -571,8 +585,12 @@ jobs:
|
||||
const nodeTestNonDistShards = nodeTestShards.filter((shard) => !shard.requires_dist);
|
||||
const nodeTestDistShards = nodeTestShards.filter((shard) => shard.requires_dist);
|
||||
// Targeted jobs cannot discover repository-scanning boundary tests
|
||||
// through imports, so preserve the existing full boundary gate.
|
||||
const runNodeCoreDist = changedNodeTestShards !== null || nodeTestDistShards.length > 0;
|
||||
// through imports. Keep the full boundary gate inside build-artifacts
|
||||
// when that lane runs; test-only targeted plans carry their own
|
||||
// nondist changed-boundary shard instead.
|
||||
const runNodeCoreDist =
|
||||
(changedNodeTestShards !== null && runBuildArtifacts) ||
|
||||
nodeTestDistShards.length > 0;
|
||||
const channelContractShards = runNodeFull ? createChannelContractTestShards() : [];
|
||||
const protocolCoverageRequested = runNode || runIosBuild || runAndroid;
|
||||
const runProtocolEventCoverage =
|
||||
@@ -587,7 +605,7 @@ jobs:
|
||||
run_android: runAndroid,
|
||||
run_skills_python: runSkillsPython,
|
||||
run_windows: runWindows,
|
||||
run_build_artifacts: runNodeFull,
|
||||
run_build_artifacts: runBuildArtifacts,
|
||||
run_checks_fast_core: checksFastCoreTasks.length > 0,
|
||||
run_checks_fast: runNodeFull,
|
||||
historical_target: historicalTarget,
|
||||
@@ -1297,10 +1315,10 @@ jobs:
|
||||
;;
|
||||
contracts-plugins-ci-routing)
|
||||
pnpm test:contracts:plugins
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/ci-changed-node-test-plan.test.ts test/scripts/ci-workflow-guards.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/ci-changed-node-test-plan.test.ts test/scripts/ci-run-node-test-shard.test.ts test/scripts/ci-workflow-guards.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
|
||||
;;
|
||||
ci-routing)
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/ci-changed-node-test-plan.test.ts test/scripts/ci-workflow-guards.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/ci-changed-node-test-plan.test.ts test/scripts/ci-run-node-test-shard.test.ts test/scripts/ci-workflow-guards.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
|
||||
;;
|
||||
max-lines-ratchet)
|
||||
if ! has_package_script "check:max-lines-ratchet"; then
|
||||
@@ -1682,83 +1700,8 @@ jobs:
|
||||
OPENCLAW_VITEST_SHARD_NAME: ${{ matrix.shard_name }}
|
||||
OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "300000"
|
||||
OPENCLAW_VITEST_NO_OUTPUT_RETRY: "1"
|
||||
OPENCLAW_TEST_PROJECTS_PARALLEL: "2"
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node --input-type=module <<'EOF'
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
const targets = JSON.parse(process.env.OPENCLAW_NODE_TEST_TARGETS_JSON ?? "null");
|
||||
if (Array.isArray(targets) && targets.length > 0) {
|
||||
// One file per process preserves the isolation boundaries encoded by
|
||||
// full-suite include-pattern shards while keeping one runner job.
|
||||
for (const target of targets) {
|
||||
const result = spawnSync(
|
||||
"pnpm",
|
||||
["exec", "node", "scripts/test-projects.mjs", target],
|
||||
{ env: process.env, stdio: "inherit" },
|
||||
);
|
||||
if (result.status !== 0) {
|
||||
process.exit(result.status ?? 1);
|
||||
}
|
||||
}
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const groups = JSON.parse(process.env.OPENCLAW_NODE_TEST_GROUPS_JSON ?? "null");
|
||||
const plans = Array.isArray(groups) && groups.length > 0
|
||||
? groups
|
||||
: [{
|
||||
configs: JSON.parse(process.env.OPENCLAW_NODE_TEST_CONFIGS_JSON ?? "[]"),
|
||||
env: JSON.parse(process.env.OPENCLAW_NODE_TEST_ENV_JSON ?? "null"),
|
||||
includePatterns: JSON.parse(
|
||||
process.env.OPENCLAW_NODE_TEST_INCLUDE_PATTERNS_JSON ?? "null",
|
||||
),
|
||||
shard_name: process.env.OPENCLAW_VITEST_SHARD_NAME,
|
||||
}];
|
||||
for (const plan of plans) {
|
||||
const configs = plan.configs;
|
||||
if (!Array.isArray(configs) || configs.length === 0) {
|
||||
console.error("Missing node test shard configs");
|
||||
process.exit(1);
|
||||
}
|
||||
const childEnv = {
|
||||
...process.env,
|
||||
...(plan.shard_name ? { OPENCLAW_VITEST_SHARD_NAME: plan.shard_name } : {}),
|
||||
};
|
||||
if (plan.env && typeof plan.env === "object" && !Array.isArray(plan.env)) {
|
||||
for (const [key, value] of Object.entries(plan.env)) {
|
||||
if (typeof value === "string") {
|
||||
childEnv[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Array.isArray(plan.includePatterns) && plan.includePatterns.length > 0) {
|
||||
const includeFile = join(
|
||||
process.env.RUNNER_TEMP ?? ".",
|
||||
`node-test-include-${process.env.GITHUB_JOB ?? "local"}-${Date.now()}.json`,
|
||||
);
|
||||
writeFileSync(includeFile, JSON.stringify(plan.includePatterns), "utf8");
|
||||
childEnv.OPENCLAW_VITEST_INCLUDE_FILE = includeFile;
|
||||
} else {
|
||||
delete childEnv.OPENCLAW_VITEST_INCLUDE_FILE;
|
||||
}
|
||||
const result = spawnSync(
|
||||
"pnpm",
|
||||
["exec", "node", "scripts/test-projects.mjs", ...configs],
|
||||
{
|
||||
env: childEnv,
|
||||
stdio: "inherit",
|
||||
},
|
||||
);
|
||||
if ((result.status ?? 1) !== 0) {
|
||||
process.exit(result.status ?? 1);
|
||||
}
|
||||
}
|
||||
EOF
|
||||
run: node scripts/ci-run-node-test-shard.mjs
|
||||
|
||||
# Types, lint, and format check shards.
|
||||
check-shard:
|
||||
@@ -1794,7 +1737,9 @@ jobs:
|
||||
runner: blacksmith-4vcpu-ubuntu-2404
|
||||
- check_name: check-test-types
|
||||
task: test-types
|
||||
runner: blacksmith-4vcpu-ubuntu-2404
|
||||
# Slowest static lane (~3.5min on 4 vCPU); extra cores shorten the
|
||||
# PR critical path for roughly the same billed core-minutes.
|
||||
runner: blacksmith-16vcpu-ubuntu-2404
|
||||
steps:
|
||||
- *linux_node_checkout_step
|
||||
- name: Setup Node environment
|
||||
@@ -1904,7 +1849,9 @@ jobs:
|
||||
- check_name: check-additional-boundaries-a
|
||||
group: boundaries
|
||||
boundary_shard: 1/4
|
||||
runner: blacksmith-8vcpu-ubuntu-2404
|
||||
# This shard runs ~4min on 8 vCPU and regularly owns the PR wall
|
||||
# clock; extra cores shorten it for similar billed core-minutes.
|
||||
runner: blacksmith-16vcpu-ubuntu-2404
|
||||
- check_name: check-additional-boundaries-bcd
|
||||
group: boundaries
|
||||
boundary_shard: 2/4,3/4,4/4
|
||||
|
||||
Reference in New Issue
Block a user