ci: split auto-reply shard timing

This commit is contained in:
Peter Steinberger
2026-04-25 23:46:56 +01:00
parent 1531123d35
commit 496d90c3b5
13 changed files with 382 additions and 96 deletions

View File

@@ -216,10 +216,16 @@ describe("scripts/lib/ci-node-test-plan.mjs", () => {
shardName: "auto-reply-core-top-level",
},
{
checkName: "checks-node-auto-reply-reply-agent-dispatch",
checkName: "checks-node-auto-reply-reply-agent-runner",
configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
requiresDist: false,
shardName: "auto-reply-reply-agent-dispatch",
shardName: "auto-reply-reply-agent-runner",
},
{
checkName: "checks-node-auto-reply-reply-dispatch",
configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
requiresDist: false,
shardName: "auto-reply-reply-dispatch",
},
{
checkName: "checks-node-auto-reply-reply-commands-state-routing",

View File

@@ -1,5 +1,9 @@
import { describe, expect, it } from "vitest";
import { summarizeRunTimings } from "../../scripts/ci-run-timings.mjs";
import {
parseRunTimingArgs,
selectLatestMainPushCiRun,
summarizeRunTimings,
} from "../../scripts/ci-run-timings.mjs";
describe("scripts/ci-run-timings.mjs", () => {
it("separates queue time from job duration", () => {
@@ -46,4 +50,58 @@ describe("scripts/ci-run-timings.mjs", () => {
["slow", 20],
]);
});
it("selects the push CI run for the current main SHA", () => {
expect(
selectLatestMainPushCiRun(
[
{
databaseId: 3,
event: "issue_comment",
headSha: "current",
},
{
databaseId: 2,
event: "push",
headSha: "older",
},
{
databaseId: 1,
event: "push",
headSha: "current",
},
],
"current",
),
).toMatchObject({ databaseId: 1 });
});
it("falls back to the newest push CI run when the exact SHA has not appeared yet", () => {
expect(
selectLatestMainPushCiRun(
[
{
databaseId: 4,
event: "issue_comment",
headSha: "current",
},
{
databaseId: 3,
event: "push",
headSha: "previous",
},
],
"current",
),
).toMatchObject({ databaseId: 3 });
});
it("ignores pnpm passthrough sentinels when parsing monitor args", () => {
expect(parseRunTimingArgs(["--latest-main", "--", "--limit", "3"])).toEqual({
explicitRunId: undefined,
limit: 3,
recentLimit: null,
useLatestMain: true,
});
});
});

View File

@@ -0,0 +1,91 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import {
createShardTimingSample,
readShardTimings,
resolveShardTimingKey,
writeShardTimings,
} from "../../scripts/lib/vitest-shard-timings.mjs";
describe("scripts/lib/vitest-shard-timings.mjs", () => {
it("uses the config path as the timing key for whole-config runs", () => {
expect(
resolveShardTimingKey({
config: "test/vitest/vitest.unit-fast.config.ts",
env: {},
includePatterns: null,
}),
).toBe("test/vitest/vitest.unit-fast.config.ts");
});
it("uses the CI shard name for include-pattern timing keys", () => {
expect(
resolveShardTimingKey({
config: "test/vitest/vitest.auto-reply-reply.config.ts",
env: { OPENCLAW_VITEST_SHARD_NAME: "auto-reply/reply agent dispatch" },
includePatterns: ["src/auto-reply/reply/agent-runner.test.ts"],
}),
).toBe("test/vitest/vitest.auto-reply-reply.config.ts#auto-reply-reply-agent-dispatch");
});
it("falls back to a stable include-pattern hash outside CI", () => {
const first = resolveShardTimingKey({
config: "test/vitest/vitest.auto-reply-reply.config.ts",
env: {},
includePatterns: ["src/auto-reply/reply/agent-runner.test.ts"],
});
const second = resolveShardTimingKey({
config: "test/vitest/vitest.auto-reply-reply.config.ts",
env: {},
includePatterns: ["src/auto-reply/reply/agent-runner.test.ts"],
});
expect(first).toBe(second);
expect(first).toMatch(/^test\/vitest\/vitest\.auto-reply-reply\.config\.ts#include-1-/u);
});
it("persists include-pattern timing metadata", () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-shard-timings-"));
const env = {
OPENCLAW_TEST_PROJECTS_TIMINGS_PATH: path.join(tempDir, "timings.json"),
OPENCLAW_VITEST_SHARD_NAME: "auto-reply-reply-agent-runner",
};
const sample = createShardTimingSample(
{
config: "test/vitest/vitest.auto-reply-reply.config.ts",
env,
includePatterns: ["src/auto-reply/reply/agent-runner.test.ts"],
watchMode: false,
},
1234,
);
expect(sample).toEqual({
baseConfig: "test/vitest/vitest.auto-reply-reply.config.ts",
config: "test/vitest/vitest.auto-reply-reply.config.ts#auto-reply-reply-agent-runner",
durationMs: 1234,
includePatternCount: 1,
});
writeShardTimings([sample], tempDir, env);
expect(readShardTimings(tempDir, env)).toEqual(
new Map([
["test/vitest/vitest.auto-reply-reply.config.ts#auto-reply-reply-agent-runner", 1234],
]),
);
expect(
JSON.parse(fs.readFileSync(env.OPENCLAW_TEST_PROJECTS_TIMINGS_PATH, "utf8")).configs[
"test/vitest/vitest.auto-reply-reply.config.ts#auto-reply-reply-agent-runner"
],
).toMatchObject({
averageMs: 1234,
baseConfig: "test/vitest/vitest.auto-reply-reply.config.ts",
includePatternCount: 1,
lastMs: 1234,
sampleCount: 1,
});
});
});