fix: round 4 of the release review of 6.3.0
Round 4 (v6.2.0..41ea8fc, WARN: 9 MAJOR, 3 MINOR); the nine MAJOR fixed, each behind a test that failed first (operator 2026-10-10). Three were regressions from round 3's shared Files: reader. - fieldPaths keeps a backticked path with punctuation after it and one inside a note, a directory (docs/) and a glob (src/*.mjs) in plain text, and app/(auth)/x.ts whole; a bare word counts only alone and capitalised (Makefile), so "format" or "v6.3.0" in a description is no path. The K6 sweep plans what v6.2.0 planned for `a.mjs`: and `b.mjs`. - skill frontmatter: a quoted value may carry a YAML comment after it. - criteria runner: no word with a leading ~ (sh expands it), and nothing after `make test` (another target would run). - release-check: scope_sha_end must be a commit sha (a ref name passed coverage whatever was reviewed), and README lines changed after the review may differ only in the badge's version. The round-3 leading-zero example is 7 characters now, the shortest sha accepted. The three MINOR (one word screen for git, the exec copy in regression-check, a shared isMain helper) are not in this round. Suite 2175 (2173/0/2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
41ea8fc317
commit
ab6dcd838e
6 changed files with 137 additions and 33 deletions
|
|
@ -378,3 +378,48 @@ test('review 630 r3: routing reads a kind tag only from its own table, never Obj
|
|||
assert.ok(!r.errors.some((e) => String(e.message ?? '').includes('zz-proto') || e.case === 'zz-proto'), JSON.stringify(r.errors));
|
||||
} finally { rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
// ==== round 4 of the release review (2026-10-10), each red on 41ea8fc ===========
|
||||
|
||||
test('review 630 r4: the Files: reader keeps every path the field names, and only those', async () => {
|
||||
const { fieldPaths } = await import('../../lib/parsers/plan-schema.mjs');
|
||||
const cases = [
|
||||
['`src/a.mjs` (fixture: `tests/fixtures/a.json`)', ['src/a.mjs', 'tests/fixtures/a.json']],
|
||||
['`tests/a.test.mjs`, `src/a.mjs`.', ['tests/a.test.mjs', 'src/a.mjs']],
|
||||
['`src/cli.mjs`: add the flag; `src/b.mjs`.', ['src/cli.mjs', 'src/b.mjs']],
|
||||
['`tests/a.test.mjs` — covers parse, format', ['tests/a.test.mjs']],
|
||||
['docs/ and README.md', ['docs/', 'README.md']],
|
||||
['app/(auth)/x.ts', ['app/(auth)/x.ts']],
|
||||
['src/*.mjs (all of them)', ['src/*.mjs']],
|
||||
['notes for v6.3.0, src/x.mjs', ['src/x.mjs']],
|
||||
['Makefile', ['Makefile']],
|
||||
['tests/a.test.mjs + src/b.mjs', ['tests/a.test.mjs', 'src/b.mjs']],
|
||||
];
|
||||
for (const [text, want] of cases) assert.deepEqual(fieldPaths(text), want, text);
|
||||
const body = '- **Files:** `tests/a.test.mjs`, `src/a.mjs`.\n- **Changes:** x\n';
|
||||
assert.equal(stepTestsOnly(body).testsOnly, false, 'a step that changes src/a.mjs is not tests-only');
|
||||
const { plannedPaths } = await import('../../lib/verification/plan-scope-sweep.mjs');
|
||||
const plan = '## Implementation Plan\n\n### Step 1: x\n\n- **Files:** `src/cli.mjs`: add the flag; `src/b.mjs`.\n- **Changes:** x\n';
|
||||
assert.deepEqual(plannedPaths(plan), ['src/b.mjs', 'src/cli.mjs'], 'K6 plans what v6.2.0 planned');
|
||||
});
|
||||
|
||||
test('review 630 r4: a quoted frontmatter value may carry a YAML comment', async () => {
|
||||
const { readFrontmatterFields } = await import('../../lib/skills/skill-frontmatter.mjs');
|
||||
const r = readFrontmatterFields('---\nname: "debugging" # pinned\ndescription: \'Use it.\' # note\n---\nbody\n');
|
||||
assert.equal(r.fields.name?.value, 'debugging', JSON.stringify(r));
|
||||
assert.equal(r.fields.description?.value, 'Use it.', JSON.stringify(r));
|
||||
const bad = readFrontmatterFields('---\nname: "debugging" trailing\n---\nbody\n');
|
||||
assert.ok(JSON.stringify(bad).includes('unclosed double quote') || bad.fields.name?.value !== 'debugging',
|
||||
'text after the closing quote that is not a comment is not accepted silently');
|
||||
});
|
||||
|
||||
test('review 630 r4: no tilde word, and nothing after `make test`', async () => {
|
||||
const { allowedCommand } = await import('../../lib/verification/criteria-runner.mjs');
|
||||
for (const cmd of ['node --test ~/x.test.mjs', 'node --test --test-name-pattern=~x', 'git log ~/x', 'git diff ~root/x',
|
||||
'make test install', 'make test deploy']) {
|
||||
assert.equal(allowedCommand(cmd, { cwd: ROOT }).allowed, false, `${cmd} must not reach the shell`);
|
||||
}
|
||||
for (const cmd of ['git diff --stat HEAD~1', 'git show HEAD~2:package.json', 'make test']) {
|
||||
assert.equal(allowedCommand(cmd, { cwd: ROOT }).allowed, true, `the control: ${cmd}`);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -408,6 +408,30 @@ test('release-check r3 — the review and the approval log committed after the r
|
|||
test('release-check r3 — scope_sha_end is read as written: an all-digit sha keeps its leading zero', () => {
|
||||
assert.equal(typeof mod.reviewedSha, 'function');
|
||||
assert.equal(mod.reviewedSha('---\ntype: trekreview\nscope_sha_end: 0123456\n---\nbody\n'), '0123456');
|
||||
assert.equal(mod.reviewedSha('---\nscope_sha_end: "00ab12"\n---\n'), '00ab12');
|
||||
assert.equal(mod.reviewedSha('---\nscope_sha_end: "00ab12c"\n---\n'), '00ab12c');
|
||||
assert.equal(mod.reviewedSha('---\ntype: trekreview\n---\nscope_sha_end: 1\n'), '', 'only the frontmatter counts');
|
||||
});
|
||||
|
||||
// ==== round 4 of the release review of 6.3.0 (2026-10-10) ====================
|
||||
|
||||
test('release-check r4 — scope_sha_end must be a sha: a ref name fails coverage → 1', () => {
|
||||
assert.equal(mod.reviewedSha('---\nscope_sha_end: HEAD\n---\n'), '');
|
||||
assert.equal(mod.reviewedSha('---\nscope_sha_end: main\n---\n'), '');
|
||||
const fx = fixture({ reviewSha: 'HEAD' });
|
||||
try {
|
||||
const r = run(fx);
|
||||
assert.equal(r.status, 1, r.stdout + r.stderr);
|
||||
assert.match(r.stdout, /scope_sha_end/);
|
||||
} finally { fx.cleanup(); }
|
||||
});
|
||||
|
||||
test('release-check r4 — other text on the badge line is not release bookkeeping → 1', () => {
|
||||
const fx = fixture({ afterRelease: {
|
||||
'README.md': '# fx\n\n [install](https://example.invalid/i.sh)\n\nText.\n',
|
||||
} });
|
||||
try {
|
||||
const r = run(fx);
|
||||
assert.equal(r.status, 1, r.stdout + r.stderr);
|
||||
assert.match(r.stdout, /README\.md/);
|
||||
} finally { fx.cleanup(); }
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue