mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-19 21:52:21 +03:00
* chore(ci): add test-masking PR-context gate to release-green pre-flight Reproduce check:test-masking (vs origin/main) inside validate-release-green so non-allowlisted net-assert reductions surface in the local pre-flight instead of in a ~40-min CI layer on the release PR. run() now merges a per-gate opts.env so GITHUB_BASE_REF reaches the child. HARD gate; skipped under --quick. Context: v3.8.43 release cost 3 CI round-trips for PR-context gates (test-masking, file-size, pr-evidence) that check:release-green did not reproduce locally. * chore(release): add contributors generator + uncovered-commit reconciliation helpers - scripts/release/gen-contributors.mjs: reproducible `### 🙌 Contributors` table for a CHANGELOG version (parenthetical-group parser → accurate per-PR attribution, noise-handle denylist). v3.8.43 shipped without the section (a real miss) because it was hand-built. npm run release:contributors <version> [--inject]. - scripts/release/list-uncovered-commits.mjs: lists commits since the last tag with no CHANGELOG bullet (v3.8.43 had 123/176 uncovered at reconciliation start). Advisory, maintainer-side. npm run release:uncovered. - 20 unit tests (parenthetical attribution, noise exclusion, idempotent injection, coverage window). * chore(quality): absorb web-cookie-providers-new file-size drift from #5928 (base-red on release/v3.8.44)
111 lines
4.0 KiB
TypeScript
111 lines
4.0 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
const mod = await import("../../scripts/release/gen-contributors.mjs");
|
|
const {
|
|
extractVersionSection,
|
|
parseContributors,
|
|
renderContributors,
|
|
injectContributors,
|
|
NOISE_HANDLES,
|
|
} = mod;
|
|
|
|
const FIXTURE = `# Changelog
|
|
|
|
## [Unreleased]
|
|
|
|
---
|
|
|
|
## [3.9.0] — 2026-08-01
|
|
|
|
### ✨ New Features
|
|
|
|
- **feat(a):** thing one. ([#100](https://github.com/x/y/pull/100) — thanks @alice)
|
|
- **feat(b):** uses \`@toon-format/toon\` and \`@dnd-kit\`. ([#101](https://github.com/x/y/pull/101) — thanks @bob)
|
|
|
|
### 🔧 Bug Fixes
|
|
|
|
- **fix(c):** direct commit fix. (thanks @carol)
|
|
- **fix(d):** extracted. Extracted from [#102](https://github.com/x/y/pull/102) by [@dave](https://github.com/dave).
|
|
|
|
### 📝 Maintenance
|
|
|
|
- **refactor(rollup):** god-file split ([#200](https://github.com/x/y/pull/200), [#201](https://github.com/x/y/pull/201) — thanks @erin); editorconfig ([#202](https://github.com/x/y/pull/202) — thanks @frank). — thanks @diegosouzapw
|
|
|
|
---
|
|
|
|
## [3.8.99] — 2026-07-31
|
|
|
|
### 🔧 Bug Fixes
|
|
|
|
- **fix(z):** other version, must not leak. ([#999](https://github.com/x/y/pull/999) — thanks @zoe)
|
|
|
|
---
|
|
`;
|
|
|
|
test("extractVersionSection returns only the target version body (not the next section)", () => {
|
|
const sec = extractVersionSection(FIXTURE, "3.9.0");
|
|
assert.ok(sec.includes("thing one"), "includes 3.9.0 content");
|
|
assert.ok(!sec.includes("must not leak"), "excludes 3.8.99 content");
|
|
assert.ok(!sec.includes("#999"), "does not bleed into next version");
|
|
});
|
|
|
|
test("parseContributors credits per parenthetical group, not a flat scan", () => {
|
|
const agg = parseContributors(extractVersionSection(FIXTURE, "3.9.0"));
|
|
// rollup: erin gets 200+201, frank gets 202 — NOT both getting all three
|
|
assert.deepEqual(
|
|
[...agg.get("erin")].sort((a, b) => a - b),
|
|
[200, 201]
|
|
);
|
|
assert.deepEqual([...agg.get("frank")], [202]);
|
|
// simple bullets
|
|
assert.deepEqual([...agg.get("alice")], [100]);
|
|
// direct-commit credit with no PR ref
|
|
assert.ok(agg.has("carol") && agg.get("carol").size === 0);
|
|
// "Extracted from #N by @X"
|
|
assert.deepEqual([...agg.get("dave")], [102]);
|
|
});
|
|
|
|
test("noise handles and the maintainer are excluded from the contributor map", () => {
|
|
const agg = parseContributors(extractVersionSection(FIXTURE, "3.9.0"));
|
|
assert.ok(!agg.has("toon-format"), "package scope is not a contributor");
|
|
assert.ok(!agg.has("dnd-kit"), "package scope is not a contributor");
|
|
assert.ok(!agg.has("diegosouzapw"), "maintainer is rendered separately, not in the map");
|
|
assert.ok(NOISE_HANDLES.has("toon-format"));
|
|
});
|
|
|
|
test("renderContributors emits an alphabetical table with maintainer last", () => {
|
|
const agg = parseContributors(extractVersionSection(FIXTURE, "3.9.0"));
|
|
const table = renderContributors("3.9.0", agg);
|
|
assert.ok(table.startsWith("### 🙌 Contributors"));
|
|
const rows = table.split("\n").filter((l) => l.startsWith("| [@"));
|
|
const handles = rows.map((r) => r.match(/@([A-Za-z0-9_-]+)/)[1]);
|
|
assert.equal(handles[handles.length - 1], "diegosouzapw", "maintainer is last");
|
|
const external = handles.slice(0, -1);
|
|
assert.deepEqual(
|
|
external,
|
|
[...external].sort((a, b) => a.localeCompare(b)),
|
|
"external sorted"
|
|
);
|
|
assert.ok(table.includes("| [@carol](https://github.com/carol) | direct commit / report |"));
|
|
});
|
|
|
|
test("injectContributors inserts before the closing --- and is idempotent", () => {
|
|
const once = injectContributors(
|
|
FIXTURE,
|
|
"3.9.0",
|
|
renderContributors("3.9.0", parseContributors(extractVersionSection(FIXTURE, "3.9.0")))
|
|
);
|
|
assert.ok(once.includes("### 🙌 Contributors"), "section injected");
|
|
// 3.8.99 untouched
|
|
assert.ok(once.includes("must not leak"));
|
|
// idempotent: injecting again does not duplicate
|
|
const twice = injectContributors(
|
|
once,
|
|
"3.9.0",
|
|
renderContributors("3.9.0", parseContributors(extractVersionSection(once, "3.9.0")))
|
|
);
|
|
const count = (twice.match(/### 🙌 Contributors/g) || []).length;
|
|
assert.equal(count, 1, "no duplicate Contributors section on re-run");
|
|
});
|