mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-11 23:36:51 +02:00
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 <noreply@anthropic.com>
This commit is contained in:
1 parent
88433c1be7
commit
c324d00806
1 file changed
+54
-2
@@ -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`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user