From f2000c7a2582cfcbae2b265e2a97e0f95f87ee5e Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 9 Sep 2026 14:53:55 +0200 Subject: [PATCH] separated into 2 steps: 1. figure out the target milestone, 2. to set it. If main branch, do nothing, if rc branch target, then set milestone to that, if developer but with equivalent PRs listed with one in an rc branch, then that is the milstone, else read the yaml file and figure it out --- .github/workflows/pr_milestone.yaml | 106 +++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 17 deletions(-) diff --git a/.github/workflows/pr_milestone.yaml b/.github/workflows/pr_milestone.yaml index 57f9b576d..c9828804e 100644 --- a/.github/workflows/pr_milestone.yaml +++ b/.github/workflows/pr_milestone.yaml @@ -20,7 +20,8 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set milestone + - name: Determine target milestone + id: determine-milestone uses: actions/github-script@v8 with: script: | @@ -38,16 +39,91 @@ jobs: const baseBranch = pullRequest.base.ref; /* - * Return early if base is main branch. Milestone is already + * 1. Return early if base is main branch. Milestone is already * managed and probably done when merging to main. */ if (baseBranch === 'main') { core.info('PR targets main. Milestone is managed separately.'); + core.setOutput('target_milestone', ''); return; } /* - * Read release targets through the GitHub API + * Helper function to set the target milestone output. + */ + const setTargetMilestoneOutput = (targetMilestone) => { + core.info(`Target milestone: ${targetMilestone}`); + core.setOutput('target_milestone', targetMilestone); + }; + + /* + * 2. If PR targets a release-candidate branch (for example 9.1.0.rc), + * set milestone to the release version prefix (for example 9.1.0) + * and return early. + */ + if (baseBranch.endsWith('.rc')) { + const targetMilestone = baseBranch.replace(/\.rc$/, ''); + + core.info( + `PR targets release-candidate branch "${baseBranch}". ` + + `Using milestone "${targetMilestone}".` + ); + + setTargetMilestoneOutput(targetMilestone); + return; + } + + /* + * 3. If PR targets developer, check "Equivalent PRs" in the PR body. + * If an equivalent PR targets an RC branch (for example 9.1.0.rc), + * use the corresponding release milestone (for example 9.1.0). + */ + if (baseBranch === 'developer') { + const equivalentPrSectionMatch = pullRequest.body?.match( + /(^|\n)#{1,6}\s*Equivalent PRs\s*\n([\s\S]*?)(?=\n#{1,6}\s+\S|\s*$)/i + ); + + const equivalentPrNumbers = + equivalentPrSectionMatch?.[2] + ? Array.from( + equivalentPrSectionMatch[2].matchAll(/#(\d+)/g), + match => Number(match[1]) + ) + : []; + + for (const equivalentPrNumber of equivalentPrNumbers) { + if (equivalentPrNumber === prNumber) { + continue; + } + + const { data: equivalentPr } = + await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: equivalentPrNumber + }); + + const equivalentBaseBranch = equivalentPr.base.ref; + + if (!equivalentBaseBranch.endsWith('.rc')) { + continue; + } + + const targetMilestone = + equivalentBaseBranch.replace(/\.rc$/, ''); + + core.info( + `Developer PR references RC PR #${equivalentPrNumber} ` + + `(${equivalentBaseBranch}). Using milestone "${targetMilestone}".` + ); + + setTargetMilestoneOutput(targetMilestone); + return; + } + } + + /* + * 4. Read release targets through the GitHub API * from the base branch of PR. */ const { data: file } = @@ -117,19 +193,22 @@ jobs: ) { targetMilestone = bugFix; } else { - core.info( + core.setFailed( 'No milestone-related labels found.' ); return; } - core.info( - `Target milestone: ${targetMilestone}` - ); + setTargetMilestoneOutput(targetMilestone); + + - name: Set milestone + if: steps.determine-milestone.outputs.target_milestone != '' + uses: actions/github-script@v8 + with: + script: | + const prNumber = ${{ inputs.pr_number }}; + const targetMilestone = '${{ steps.determine-milestone.outputs.target_milestone }}'; - /* - * Find the milestone. - */ const { data: milestones } = await github.rest.issues.listMilestones({ owner: context.repo.owner, @@ -146,15 +225,8 @@ jobs: `Milestone "${targetMilestone}" was not found.` ); return; - } else { - core.info( - `Found milestone "${targetMilestone}".` - ); } - /* - * Set the milestone. - */ await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo,