From a84ff3534469647d4d5667b272a3bf2a28aabe92 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sat, 10 Oct 2026 22:39:48 -0500 Subject: [PATCH] fix: support upstream workspace CI partition --- .../run-vitest-stable-shard.test.mjs | 16 +++++++--- scripts/run-vitest-stable.mjs | 31 +++++++++++++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/scripts/__tests__/run-vitest-stable-shard.test.mjs b/scripts/__tests__/run-vitest-stable-shard.test.mjs index a044c67c15..cf9957d919 100644 --- a/scripts/__tests__/run-vitest-stable-shard.test.mjs +++ b/scripts/__tests__/run-vitest-stable-shard.test.mjs @@ -107,9 +107,17 @@ test("general shards retain scripts and route-named suites outside the serialize ]) assert.ok(general.selectedGeneralServerSuites.includes(file), `missing configured server suite: ${file}`); }); -test("shard flags are rejected for the workspaces-b group", () => { - const result = dryRun(["--mode", "general", "--group", "general-workspaces-b", "--shard-index", "0", "--shard-count", "3"]); - assert.notEqual(result.status, 0, "workspaces-b must not accept shard flags"); +for (const group of ["general-workspaces-b", "general-workspaces-c"]) { + test(`shard flags are rejected for the ${group} group`, () => { + const result = dryRun(["--mode", "general", "--group", group, "--shard-index", "0", "--shard-count", "3"]); + assert.notEqual(result.status, 0, `${group} must not accept shard flags`); + }); +} + +test("workspaces-c selects only the db project", () => { + const selected = dryRunJson(["--mode", "general", "--group", "general-workspaces-c"]); + assert.deepEqual(selected.workspaceProjects, ["@paperclipai/db"]); + assert.equal(selected.workspacesVitestShard, null); }); test("workspace lanes cover every non-server project in the root Vitest configuration", () => { @@ -118,7 +126,7 @@ test("workspace lanes cover every non-server project in the root Vitest configur assert.ok(roots.includes("server"), "expected the explicit root Vitest project list"); const expected = roots.filter(root => root !== "server") .map(root => JSON.parse(readFileSync(path.join(repoRoot, root, "package.json"), "utf8")).name).sort(); - const actual = ["general-workspaces-a", "general-workspaces-b"] + const actual = ["general-workspaces-a", "general-workspaces-b", "general-workspaces-c"] .flatMap(group => dryRunJson(["--mode", "general", "--group", group]).workspaceProjects).sort(); assert.deepEqual(actual, expected, "no configured project may be silently omitted or run twice"); }); diff --git a/scripts/run-vitest-stable.mjs b/scripts/run-vitest-stable.mjs index dd00f145cd..a62f90094e 100644 --- a/scripts/run-vitest-stable.mjs +++ b/scripts/run-vitest-stable.mjs @@ -117,9 +117,27 @@ function excludedServerSuites(groupName) { } const generalWorkspacesAGroupName = "general-workspaces-a"; const generalWorkspacesBGroupName = "general-workspaces-b"; +const generalWorkspacesCGroupName = "general-workspaces-c"; const generalWorkspacesAProjects = ["@paperclipai/ui", "paperclipai"]; -const generalWorkspacesBProjects = nonServerProjects.filter((project) => !generalWorkspacesAProjects.includes(project)); -const generalGroupNames = [generalServerGroupName, generalWorkspacesAGroupName, generalWorkspacesBGroupName]; +// The db project runs in its own lane. Its vitest invocation took 168-250s +// of a 436-513s workspaces-b job (PR runs 38084171761, 38083084276 and +// 38083020834, 2026-10-10), which made workspaces-b the slowest check once +// the server shards were rebalanced. Vitest's native --shard would not help +// here: the project is already file-parallel and client.test.ts alone is +// 117-189s of its wall time, so a hash-ordered slice can land both of its +// slow suites on one runner. Splitting by project is deterministic and +// leaves the remaining projects at ~265-275s of vitest time, roughly level +// with this lane. +const generalWorkspacesCProjects = ["@paperclipai/db"]; +const generalWorkspacesBProjects = nonServerProjects.filter( + (project) => !generalWorkspacesAProjects.includes(project) && !generalWorkspacesCProjects.includes(project), +); +const generalGroupNames = [ + generalServerGroupName, + generalWorkspacesAGroupName, + generalWorkspacesBGroupName, + generalWorkspacesCGroupName, +]; const allowedGeneralGroupNames = [ ...generalGroupNames, generalServerWithoutChatGroupName, @@ -520,6 +538,11 @@ function runGeneralGroup(routeTests, groupName, shardIndex = null, shardCount = return; } + if (groupName === generalWorkspacesCGroupName) { + runProjectGroup(generalWorkspacesCProjects, groupName); + return; + } + fail(`Unknown group "${groupName}".`); } @@ -604,7 +627,9 @@ if (options.dryRun) { ? generalWorkspacesAProjects : options.group === generalWorkspacesBGroupName ? generalWorkspacesBProjects - : null, + : options.group === generalWorkspacesCGroupName + ? generalWorkspacesCProjects + : null, workspacesVitestShard: options.group === generalWorkspacesAGroupName && options.shardCount !== null &&