ci: keep the boot check off proxies, catch continue-on-error in any literal spelling (#35) #42

Merged
maximus merged 7 commits from issue-35-ci-pin-followups into main 2026-10-01 22:00:54 +00:00
Showing only changes of commit 32db0f81d5 - Show all commits

View file

@ -15,10 +15,13 @@ const dockerfile = fs.readFileSync(path.join(ROOT, "Dockerfile"), "utf-8");
// Comment lines stripped, so an explanation that quotes a key cannot satisfy // Comment lines stripped, so an explanation that quotes a key cannot satisfy
// (or break) a pin. // (or break) a pin.
const ciCode = ci function stripCommentLines(text) {
.split("\n") return text
.filter((line) => !/^\s*#/.test(line)) .split("\n")
.join("\n"); .filter((line) => !/^\s*#/.test(line))
.join("\n");
}
const ciCode = stripCommentLines(ci);
// Lines of a top-level-indented block (` pull_request:`), up to the next key at // Lines of a top-level-indented block (` pull_request:`), up to the next key at
// the same or a lower indentation. // the same or a lower indentation.
@ -77,10 +80,32 @@ describe("CI workflow", () => {
if (/^\s*uses:|\n\s*uses:/.test(step)) expect(step).not.toMatch(/working-directory:/); if (/^\s*uses:|\n\s*uses:/.test(step)) expect(step).not.toMatch(/working-directory:/);
} }
}); });
// `continue-on-error: true` turns a red step green without a trace in the
// commit status. Any spelling of the key counts: a block key or a list item,
// but also a flow mapping and a quoted key, which a pin anchored at the start
// of the line let through (#35). Unanchored on purpose: the key quoted in a
// `run:` script, a step name or a trailing comment fails the pin too, loudly.
// Only full comment lines are exempt, being stripped from `ciCode`.
const CONTINUE_ON_ERROR = /continue-on-error["']?\s*:/;
test("never lets a failing step pass", () => { test("never lets a failing step pass", () => {
// `continue-on-error: true` turns a red step green without a trace in the expect(ciCode).not.toMatch(CONTINUE_ON_ERROR);
// commit status. Anchored on the key position, so only a real key counts. });
expect(ciCode).not.toMatch(/^\s*(- )?continue-on-error\s*:/m);
// The detector itself, through the same comment stripping as `ciCode`. Anchor
// it at the start of the line again and the last two spellings turn red.
test.each([
["a block key", " - name: x\n run: npm test\n continue-on-error: true"],
["a list item", " - continue-on-error: true\n run: npm test"],
["a flow mapping", " - { name: x, run: false, continue-on-error: true }"],
["a quoted key", ' - name: x\n "continue-on-error": true'],
])("the continue-on-error pin catches %s", (_, step) => {
expect(stripCommentLines(step)).toMatch(CONTINUE_ON_ERROR);
});
test("the continue-on-error pin ignores a full comment line quoting the key", () => {
expect(stripCommentLines(" # never add continue-on-error: true here")).not.toMatch(CONTINUE_ON_ERROR);
}); });
}); });