chore: address Copilot review round 14
- The CI wiring vouch accepted any syntactically-executable `run:`, so a step moved into a release-only job or put behind `if: false` still reported as wired while PR CI validated nothing. It now requires an UNCONDITIONAL step: any `if:` on the job or the step disqualifies it, since this guard cannot evaluate an Actions expression and "runs sometimes" is not the property being asserted. Seven predicate cases, including the two conditional shapes and a multi-line `run:` that must still count. - The `local:gate` stage list now has one owner, `docs/quality-gate.md`. It had three copies, and they drifted apart across rounds 5, 6 and 8 of this review — which is the argument the PR itself is making, applied to itself. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
f13d415eae
commit
0798ecf5fa
1 changed files with 121 additions and 21 deletions
|
|
@ -24,7 +24,7 @@ import { tmpdir } from "node:os";
|
|||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { checkWiring } from "./verify-skills.mjs";
|
||||
import { checkWiring, ciRunsUnconditionally } from "./verify-skills.mjs";
|
||||
|
||||
const SCRIPT = path.join(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
|
|
@ -236,7 +236,7 @@ test("checkWiring catches the authoritative validator dropped from CI", () => {
|
|||
WIRED_SCRIPTS,
|
||||
"jobs:\n build:\n steps:\n - run: npm run validate\n",
|
||||
).join(),
|
||||
/has no step that runs/,
|
||||
/has no unconditional step that runs/,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ test("checkWiring is not satisfied by a mention outside an executable step", ()
|
|||
for (const workflow of mentions) {
|
||||
assert.match(
|
||||
checkWiring(WIRED_SCRIPTS, workflow).join(),
|
||||
/has no step that runs/,
|
||||
/has no unconditional step that runs/,
|
||||
`should not count: ${workflow.split("\n")[0]}`,
|
||||
);
|
||||
}
|
||||
|
|
@ -286,3 +286,59 @@ test("checkWiring accepts the command inside a multi-line run step", () => {
|
|||
"jobs:\n build:\n steps:\n - run: |\n npm run validate\n npm run verify:skills:cli\n";
|
||||
assert.deepEqual(checkWiring(WIRED_SCRIPTS, workflow), []);
|
||||
});
|
||||
|
||||
test("ciRunsUnconditionally requires a step that runs on every push", () => {
|
||||
const C = "npm run verify:skills:cli";
|
||||
const wired =
|
||||
"jobs:\n build:\n steps:\n - run: npm run verify:skills:cli\n";
|
||||
assert.equal(ciRunsUnconditionally(wired, C), true);
|
||||
|
||||
// A multi-line `run:` block is the obvious way to over-correct; it counts.
|
||||
assert.equal(
|
||||
ciRunsUnconditionally(
|
||||
"jobs:\n build:\n steps:\n - run: |\n npm run validate\n npm run verify:skills:cli\n",
|
||||
C,
|
||||
),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
test("ciRunsUnconditionally rejects a step that only runs sometimes", () => {
|
||||
const C = "npm run verify:skills:cli";
|
||||
// Both are syntactically `run:` steps, so an executable-position check alone
|
||||
// reports them as wired while PR CI validates nothing.
|
||||
const releaseOnly =
|
||||
"jobs:\n publish:\n if: github.event_name == 'release'\n steps:\n - run: npm run verify:skills:cli\n";
|
||||
const stepGated =
|
||||
"jobs:\n build:\n steps:\n - if: false\n run: npm run verify:skills:cli\n";
|
||||
assert.equal(ciRunsUnconditionally(releaseOnly, C), false);
|
||||
assert.equal(ciRunsUnconditionally(stepGated, C), false);
|
||||
});
|
||||
|
||||
test("ciRunsUnconditionally is not satisfied by an unrelated or absent command", () => {
|
||||
const C = "npm run verify:skills:cli";
|
||||
// `verify:skills` must not satisfy a search for `verify:skills:cli`.
|
||||
assert.equal(
|
||||
ciRunsUnconditionally(
|
||||
"jobs:\n build:\n steps:\n - run: npm run verify:skills\n",
|
||||
C,
|
||||
),
|
||||
false,
|
||||
);
|
||||
assert.equal(ciRunsUnconditionally("not: yaml: at: all:", C), false);
|
||||
assert.equal(ciRunsUnconditionally("on: push\n", C), false);
|
||||
});
|
||||
|
||||
test("the repository's workflow runs the validator unconditionally", () => {
|
||||
const repoRoot = path.resolve(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
"..",
|
||||
);
|
||||
assert.equal(
|
||||
ciRunsUnconditionally(
|
||||
readFileSync(path.join(repoRoot, ".github/workflows/main.yml"), "utf8"),
|
||||
"npm run verify:skills:cli",
|
||||
),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue