From c324d0080617c05007ad62c2a7118375c04a330a Mon Sep 17 00:00:00 2001 From: devinfoley <139239+devinfoley@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:15:01 +0000 Subject: [PATCH] test(ci): check whole matrix entries for shard keys The workspaces-b/c guard matched only the line right after group_label, so a comment between keys could hide a shard setting. Parse each `- group:` matrix entry with comment lines removed and assert the unsharded lanes set no shard_ keys, after confirming the parser sees the shard keys on the workspaces-a entries. Co-Authored-By: Claude Fable 5.1 --- .../run-vitest-stable-shard.test.mjs | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/scripts/__tests__/run-vitest-stable-shard.test.mjs b/scripts/__tests__/run-vitest-stable-shard.test.mjs index b541d44f41..3dd3e9680e 100644 --- a/scripts/__tests__/run-vitest-stable-shard.test.mjs +++ b/scripts/__tests__/run-vitest-stable-shard.test.mjs @@ -125,6 +125,50 @@ test("workspace lanes cover every non-server project in the root Vitest configur assert.deepEqual(actual, expected, "no configured project may be silently omitted or run twice"); }); +// Collects every `- group:` matrix entry in a workflow with the keys it sets. +// Comment and blank lines are dropped first, and an entry ends only when the +// indentation returns to the item level, so a comment between two keys cannot +// hide a shard setting from the assertions below. +function matrixEntries(text) { + const entries = []; + let current = null; + for (const line of text.split("\n")) { + if (/^\s*(#|$)/.test(line)) continue; + const indent = line.match(/^ */)[0].length; + const item = line.match(/^ *- group: (\S+)/); + if (item) { + current = { group: item[1], indent, keys: ["group"] }; + entries.push(current); + continue; + } + if (!current) continue; + if (indent <= current.indent) { current = null; continue; } + const key = line.match(/^ *([A-Za-z_]+):/); + if (key) current.keys.push(key[1]); + } + return entries; +} + +test("matrixEntries sees shard keys that sit behind comments or later in the entry", () => { + const entries = matrixEntries([ + " include:", + " - group: general-workspaces-b", + " group_label: workspaces-b", + " # a comment between keys must not hide the shard setting", + " shard_index: 0", + "", + " shard_count: 3", + " - group: general-workspaces-c", + " group_label: workspaces-c", + " steps:", + " - name: unrelated", + " shard_index: 9", + ].join("\n")); + assert.deepEqual(entries.map(entry => entry.group), ["general-workspaces-b", "general-workspaces-c"]); + assert.deepEqual(entries[0].keys, ["group", "group_label", "shard_index", "shard_count"]); + assert.deepEqual(entries[1].keys, ["group", "group_label"], "keys after the matrix must not leak into the last entry"); +}); + test("workspaces-c runs the db project alone and workspaces-b no longer carries it", () => { // The db project was 168-250s of the 436-513s workspaces-b vitest time // (PR runs 38084171761, 38083084276 and 38083020834, 2026-10-10), so it @@ -136,9 +180,17 @@ test("workspaces-c runs the db project alone and workspaces-b no longer carries assert.ok(!workspacesB.workspaceProjects.includes("@paperclipai/db"), "db must not run twice"); assert.ok(workspacesB.workspaceProjects.length > 0, "workspaces-b must still run its other projects"); for (const workflow of ["pr-trusted.yml", "release-verify.yml"]) { - const text = readFileSync(path.join(repoRoot, ".github", "workflows", workflow), "utf8"); + const entries = matrixEntries(readFileSync(path.join(repoRoot, ".github", "workflows", workflow), "utf8")); + // The parser must demonstrably see shard keys in this workflow, otherwise + // the unsharded assertions below could pass for the wrong reason. + const sharded = entries.filter(entry => entry.group === "general-workspaces-a"); + assert.ok(sharded.length > 0 && sharded.every(entry => entry.keys.includes("shard_index") && entry.keys.includes("shard_count")), + `${workflow} must carry the sharded workspaces-a entries`); for (const group of ["general-workspaces-b", "general-workspaces-c"]) { - assert.match(text, new RegExp(`- group: ${group}\\n\\s+group_label: [^\\n]+\\n(?!\\s+shard_)`), `${workflow} must run ${group} unsharded`); + const matching = entries.filter(entry => entry.group === group); + assert.equal(matching.length, 1, `${workflow} must run ${group} exactly once`); + assert.ok(matching[0].keys.includes("group_label"), `${workflow} must label the ${group} job`); + assert.deepEqual(matching[0].keys.filter(key => key.startsWith("shard_")), [], `${workflow} must run ${group} unsharded`); } } });