From 8cca3630aec577dc820aaf181e7f06ed8eb1f8cc Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Tue, 19 May 2026 02:41:38 -0300 Subject: [PATCH] fix(triage): use word-boundary matching in parseChangelog per spec --- scripts/features/lib/delivered.mjs | 12 +++++++++--- tests/unit/feature-triage/delivered.test.mjs | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/scripts/features/lib/delivered.mjs b/scripts/features/lib/delivered.mjs index fbdf6b8c3f..56e869da4a 100644 --- a/scripts/features/lib/delivered.mjs +++ b/scripts/features/lib/delivered.mjs @@ -6,6 +6,7 @@ const VERSION_HEADER_RE = /^##\s+\[?(\d+\.\d+\.\d+)\]?/; export function parseChangelog(text, issueNumber) { if (typeof text !== "string") return null; + if (!Number.isInteger(issueNumber) || issueNumber <= 0) return null; const needle = `#${issueNumber}`; const lines = text.split("\n"); @@ -18,9 +19,14 @@ export function parseChangelog(text, issueNumber) { currentVersion = headerMatch[1]; continue; } - if (line.includes(needle) && currentSection) { - const match = line.match(/\(#\d+\)/); - if (match && match[0] === `(${needle})`) { + if (!currentSection) continue; + // Match #N with word boundary: look for needle followed by non-word char or end + const idx = line.indexOf(needle); + if (idx !== -1) { + const nextIdx = idx + needle.length; + const nextChar = line[nextIdx]; + const isWordBoundary = nextIdx >= line.length || /\W/.test(nextChar); + if (isWordBoundary) { return { section: currentSection, version: currentVersion, diff --git a/tests/unit/feature-triage/delivered.test.mjs b/tests/unit/feature-triage/delivered.test.mjs index 77c12ae912..316e337dba 100644 --- a/tests/unit/feature-triage/delivered.test.mjs +++ b/tests/unit/feature-triage/delivered.test.mjs @@ -39,4 +39,11 @@ describe("parseChangelog", () => { const r = parseChangelog(text, 980); assert.equal(r.version, "3.7.2"); }); + + it("matches #N with word boundary (not only inside parentheses)", () => { + const text = `## [3.7.2]\n- Fixed by #980.\n`; + const r = parseChangelog(text, 980); + assert.equal(r.version, "3.7.2"); + assert.match(r.line, /#980/); + }); });