diff --git a/.agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs b/.agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs index c71ed0a6027a..f123b24f002e 100644 --- a/.agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs +++ b/.agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs @@ -684,7 +684,7 @@ export function contributionRecordTarget(section) { } export function pullRequestTitleFromCommitSubject(subject, number) { - const match = subject.match(/^(?\S(?:.*?\S)?)(?<pr> \(#(?<number>[1-9]\d*)\))\k<pr>*$/u); + const match = subject.match(/^(?<title>\S(?:.*\S)?)(?<! \(#\d+\)) \(#(?<number>[1-9]\d*)\)$/u); return match?.groups?.number === String(number) ? match.groups.title : undefined; } @@ -839,7 +839,7 @@ function appendReferences(references, additions) { function normalizedCommitSubject(subject) { return subject - .replace(/\s+\(#\d+\)\s*$/, "") + .replace(/(?:\s+\(#\d+\))+\s*$/, "") .replace(/\s+/g, " ") .trim() .toLowerCase(); diff --git a/test/scripts/verify-release-notes.test.ts b/test/scripts/verify-release-notes.test.ts index e7c80e9a024b..e63845dee4d8 100644 --- a/test/scripts/verify-release-notes.test.ts +++ b/test/scripts/verify-release-notes.test.ts @@ -58,13 +58,13 @@ describe("release-note verification", () => { }); it("accepts only canonical commit PR suffixes", () => { + const repeated = "Fix status (#102147) (#102147)"; + const distinct = "Fix status (#120582) (#120584)"; expect(pullRequestTitleFromCommitSubject("Fix status (#102147)", 102147)).toBe("Fix status"); - expect(pullRequestTitleFromCommitSubject("Fix status (#102147) (#102147)", 102147)).toBe( - "Fix status", - ); + expect(pullRequestTitleFromCommitSubject(repeated, 102147)).toBeUndefined(); + expect(pullRequestTitleFromCommitSubject(distinct, 120584)).toBeUndefined(); expect(pullRequestTitleFromCommitSubject("Fix status(#102147)", 102147)).toBeUndefined(); expect(pullRequestTitleFromCommitSubject("Fix status (#0102147)", 102147)).toBeUndefined(); - expect(pullRequestTitleFromCommitSubject("Fix status (#0)", 0)).toBeUndefined(); expect(pullRequestTitleFromCommitSubject(" Fix status (#102147)", 102147)).toBeUndefined(); expect(pullRequestTitleFromCommitSubject("Fix status (#102147) ", 102147)).toBeUndefined(); expect(pullRequestTitleFromCommitSubject("Fix status (#102148)", 102147)).toBeUndefined(); @@ -481,6 +481,12 @@ describe("release-note verification", () => { }, ]), ).toEqual([mainCommit.hash]); + const backportSubject = "fix(gateway): retain work admission across hosted wizard steps"; + mainCommit.subject = `${backportSubject} (#120582)`; + integratedBackport.subject = `${mainCommit.subject} (#120584)`; + expect(canonicalMainCommitMatches(integratedBackport, [mainCommit])).toEqual([mainCommit.hash]); + const malformed = { ...integratedBackport, subject: `${backportSubject}(#120582) (#120584)` }; + expect(canonicalMainCommitMatches(malformed, [mainCommit])).toEqual([]); expect(canonicalPullRequests([456], [123])).toEqual([123]); });