mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 21:32:10 +03:00
feat(triage): add CHANGELOG parser for delivery detection
This commit is contained in:
33
scripts/features/lib/delivered.mjs
Normal file
33
scripts/features/lib/delivered.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Delivery detection: PR merged + CHANGELOG + git log, with confidence grading.
|
||||
*/
|
||||
|
||||
const VERSION_HEADER_RE = /^##\s+\[?(\d+\.\d+\.\d+)\]?/;
|
||||
|
||||
export function parseChangelog(text, issueNumber) {
|
||||
if (typeof text !== "string") return null;
|
||||
const needle = `#${issueNumber}`;
|
||||
const lines = text.split("\n");
|
||||
|
||||
let currentSection = null;
|
||||
let currentVersion = null;
|
||||
for (const line of lines) {
|
||||
const headerMatch = line.match(VERSION_HEADER_RE);
|
||||
if (headerMatch) {
|
||||
currentSection = line.trim();
|
||||
currentVersion = headerMatch[1];
|
||||
continue;
|
||||
}
|
||||
if (line.includes(needle) && currentSection) {
|
||||
const match = line.match(/\(#\d+\)/);
|
||||
if (match && match[0] === `(${needle})`) {
|
||||
return {
|
||||
section: currentSection,
|
||||
version: currentVersion,
|
||||
line: line.trim(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
42
tests/unit/feature-triage/delivered.test.mjs
Normal file
42
tests/unit/feature-triage/delivered.test.mjs
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, it } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { parseChangelog } from "../../../scripts/features/lib/delivered.mjs";
|
||||
|
||||
describe("parseChangelog", () => {
|
||||
it("returns section header when #N found", () => {
|
||||
const text = `
|
||||
# Changelog
|
||||
|
||||
## [3.7.2] - 2026-03-15
|
||||
|
||||
- Fix something (#980)
|
||||
- Other item
|
||||
|
||||
## [3.7.1] - 2026-03-01
|
||||
|
||||
- Earlier change (#900)
|
||||
`;
|
||||
const r = parseChangelog(text, 980);
|
||||
assert.deepEqual(r, {
|
||||
section: "## [3.7.2] - 2026-03-15",
|
||||
version: "3.7.2",
|
||||
line: "- Fix something (#980)",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns null when #N not found", () => {
|
||||
const text = `## [3.7.2]\n- Item #100\n`;
|
||||
assert.equal(parseChangelog(text, 999), null);
|
||||
});
|
||||
|
||||
it("ignores #N appearing without # prefix", () => {
|
||||
const text = `## [3.7.2]\n- Issue 980 (no hash)\n`;
|
||||
assert.equal(parseChangelog(text, 980), null);
|
||||
});
|
||||
|
||||
it("handles plain version headers without brackets/date", () => {
|
||||
const text = `## 3.7.2\n- Fix (#980)\n`;
|
||||
const r = parseChangelog(text, 980);
|
||||
assert.equal(r.version, "3.7.2");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user