diff --git a/release/src/linked-issues.ts b/release/src/linked-issues.ts index c76892720eb41a026df5ac59ed603daab00d28ae..4662c1923f7e4549cdb9a256922f1f9fcbd9150f 100644 --- a/release/src/linked-issues.ts +++ b/release/src/linked-issues.ts @@ -22,3 +22,9 @@ export function getPRsFromCommitMessage(message: string) { return result.map(r => Number(r[1])); } + +// backport PRs just have a pr number in the body without a keyword +export function getBackportSourcePRNumber(body: string) { + const matches = body.match(/#(\d+)/); + return matches ? Number(matches[1]) : null; +} diff --git a/release/src/linked-issues.unit.spec.ts b/release/src/linked-issues.unit.spec.ts index b832b4522d1a98b90d76b06bb4e2c6550cc1a540..9efa996af2c48e83bae1bc343fb985635e418eeb 100644 --- a/release/src/linked-issues.unit.spec.ts +++ b/release/src/linked-issues.unit.spec.ts @@ -1,4 +1,4 @@ -import { getLinkedIssues, getPRsFromCommitMessage } from "./linked-issues"; +import { getLinkedIssues, getPRsFromCommitMessage, getBackportSourcePRNumber } from "./linked-issues"; const closingKeywords = [ "Close", @@ -131,3 +131,18 @@ describe("getPRsFromCommitMessage", () => { expect(getPRsFromCommitMessage("Backport (#1234) and (#4567)")).toEqual([1234, 4567]); }); }); + +describe("getBackportSourcePRNumber", () => { + it("should return `null` when no PR is found", () => { + expect(getBackportSourcePRNumber("")).toBeNull(); + expect(getBackportSourcePRNumber("Lorem ipsum dolor sit amet.")).toBeNull(); + expect(getBackportSourcePRNumber("#yolo")).toBeNull(); + + }); + + it("should return the pr number when it is found", () => { + expect(getBackportSourcePRNumber("#4567")).toBe(4567); + expect(getBackportSourcePRNumber(" #4567 ")).toBe(4567); + expect(getBackportSourcePRNumber("backports #4567 and #6789")).toBe(4567); + }); +}); diff --git a/release/src/milestones.ts b/release/src/milestones.ts index 12c810ac87d1e39d6e5b2dbfc76da1980d90a4ee..1d1c9f230047463b15b80581d2651623f4fb8bcb 100644 --- a/release/src/milestones.ts +++ b/release/src/milestones.ts @@ -1,7 +1,7 @@ import _ from "underscore"; import { getMilestones } from "./github"; -import { getLinkedIssues, getPRsFromCommitMessage } from "./linked-issues"; +import { getLinkedIssues, getPRsFromCommitMessage, getBackportSourcePRNumber } from "./linked-issues"; import type { Issue, GithubProps, Milestone } from "./types"; import { getMajorVersion, @@ -54,13 +54,17 @@ async function getOriginalPR({ pull_number: pullRequestNumber, }); - if (pull?.data && isBackport(pull.data)) { - return getOriginalPR({ - github, - repo, - owner, - pullRequestNumber: pull.data.number - }); + if (pull?.data && isBackport(pull.data) && pull.data.body) { + const sourcePRNumber = getBackportSourcePRNumber(pull.data.body); + if (sourcePRNumber && sourcePRNumber !== pullRequestNumber) { + console.log('found backport PR', pull.data.number, 'source PR', sourcePRNumber); + return getOriginalPR({ + github, + repo, + owner, + pullRequestNumber: sourcePRNumber, + }); + } } const linkedIssues = await getLinkedIssues(pull.data.body ?? ''); @@ -182,9 +186,11 @@ export async function setMilestoneForCommits({ }))); } - console.log(`Tagging ${issuesToTag.length} issues with milestone ${nextMilestone.title}`) + const uniqueIssuesToTag = _.uniq(issuesToTag); + + console.log(`Tagging ${uniqueIssuesToTag.length} issues with milestone ${nextMilestone.title}`) - for (const issueNumber of issuesToTag) { // for loop to avoid rate limiting + for (const issueNumber of uniqueIssuesToTag) { // for loop to avoid rate limiting await setMilestone({ github, owner, repo, issueNumber, milestone: nextMilestone }); } }