Skip to content

Commit f30da6d

Browse files
committed
fix(scripts): move check-ci-filter-parity's fixture builders inside selfTest()
The fixture builder, its condition constant and its declaration-table helper sat at module scope while being used only by selfTest(). dispatch-gates.mjs blanks self-test BODIES before scanning a gate's module body for the path literals it reads, so a module-scope fixture helper escapes that blanking and its fixture globs are read as the gate's declared population. The two subtree globs the core/crosspkg defaults spell put this gate in the MATCHED column for 5326 tracked files it never opens. Its real population is .github/workflows/ci.yml and its own source. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
1 parent 3637731 commit f30da6d

1 file changed

Lines changed: 48 additions & 27 deletions

File tree

‎scripts/check-ci-filter-parity.mjs‎

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -382,35 +382,56 @@ function list(root = REPO_ROOT, table = CROSS_PACKAGE_TEST_INPUTS) {
382382
// is a different file and must be named), and a declaration under a root that
383383
// appears nowhere at all.
384384

385-
/** A ci.yml source carrying the two scheduling lists, in the real shape. */
386-
const REAL_TEST_IF =
387-
"${{ !cancelled() && (needs.filter.outputs.core != 'false' || needs.filter.outputs.crosspkg != 'false') }}";
388-
389-
function fixtureWorkflow({ core, crosspkg, condition = REAL_TEST_IF } = {}) {
390-
const list = (entries) => entries.map((e) => ` - '${e}'`).join('\n');
391-
return [
392-
'name: CI',
393-
'jobs:',
394-
' filter:',
395-
' steps:',
396-
' - uses: dorny/paths-filter@v4',
397-
' id: changes',
398-
' with:',
399-
' filters: |',
400-
' core:',
401-
list(core ?? ['packages/**', '.github/workflows/ci.yml']),
402-
` ${REMEDY_FILTER}:`,
403-
list(crosspkg ?? ['scripts/**']),
404-
' test:',
405-
` if: ${JSON.stringify(condition)}`,
406-
' steps:',
407-
' - run: echo test',
408-
].join('\n');
409-
}
410-
411-
const table = (globs) => ({ '@objectstack/probe': { globs } });
385+
// ⛔ The fixture builders below live INSIDE `selfTest()` and must stay there
386+
// (#10841). `scripts/pm/dispatch-gates.mjs` scans a gate's MODULE BODY for the
387+
// path literals it reads -- blanking comments and self-test BODIES first -- and
388+
// prints the gate as a local gate for every card those literals cover. A fixture
389+
// helper hoisted to module scope escapes that blanking, and its fixture globs are
390+
// then read as this gate's declared population.
391+
//
392+
// Measured on `3637731e2` before the move: this gate's hint set was
393+
// `.github/workflows/ci.yml` (real) plus the two subtree globs the `core`/
394+
// `crosspkg` defaults spell and the fixture table's package name (all three
395+
// fabricated), and the pair census put it in the MATCHED column for 5328 of 6511
396+
// tracked files. Its real population is ci.yml and its own source: 2. A
397+
// fabricated lead is pasted into a dispatch prompt and cannot be told apart from
398+
// an earned one, so the cost was paid by every card under two of the largest
399+
// directories in the tree.
400+
//
401+
// A fixture that must be module-scope for some other reason can still be spelled
402+
// safely -- assemble it from unslashed halves the way `DEFAULT_BASE_REF` does in
403+
// dispatch-gates.mjs, so only the joined value is pathy and it exists at runtime
404+
// alone.
412405

413406
export async function selfTest() {
407+
/** A ci.yml source carrying the two scheduling lists, in the real shape. */
408+
const REAL_TEST_IF =
409+
"${{ !cancelled() && (needs.filter.outputs.core != 'false' || needs.filter.outputs.crosspkg != 'false') }}";
410+
411+
function fixtureWorkflow({ core, crosspkg, condition = REAL_TEST_IF } = {}) {
412+
const list = (entries) => entries.map((e) => ` - '${e}'`).join('\n');
413+
return [
414+
'name: CI',
415+
'jobs:',
416+
' filter:',
417+
' steps:',
418+
' - uses: dorny/paths-filter@v4',
419+
' id: changes',
420+
' with:',
421+
' filters: |',
422+
' core:',
423+
list(core ?? ['packages/**', '.github/workflows/ci.yml']),
424+
` ${REMEDY_FILTER}:`,
425+
list(crosspkg ?? ['scripts/**']),
426+
' test:',
427+
` if: ${JSON.stringify(condition)}`,
428+
' steps:',
429+
' - run: echo test',
430+
].join('\n');
431+
}
432+
433+
const table = (globs) => ({ '@objectstack/probe': { globs } });
434+
414435
const failures = [];
415436
let checked = 0;
416437
const assert = (cond, label) => {

0 commit comments

Comments
 (0)