From 75bbaea96a6f633db91f43deea64c2e0cfc873e3 Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 23 Dec 2025 13:54:27 -0500 Subject: [PATCH 1/4] ci: add workflow to assign milestone based on target branch Automatically assigns milestones to PRs based on their target branch. PRs targeting v*-dev branches get the corresponding v*.0 milestone assigned. --- .github/workflows/milestone.yml | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/milestone.yml diff --git a/.github/workflows/milestone.yml b/.github/workflows/milestone.yml new file mode 100644 index 00000000000..378f6a1eed4 --- /dev/null +++ b/.github/workflows/milestone.yml @@ -0,0 +1,67 @@ +name: Assign Milestone + +on: + pull_request: + types: [opened, reopened, edited] + branches: + - master + - "v*-dev" + +jobs: + assign-milestone: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Assign milestone based on target branch + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + const baseBranch = pr.base.ref; + + // Skip if PR already has a milestone + if (pr.milestone) { + console.log(`PR already has milestone: ${pr.milestone.title}`); + return; + } + + // Skip if targeting master + if (baseBranch === 'master') { + console.log('PR targets master, skipping milestone assignment'); + return; + } + + // Parse v*-dev branch pattern + const match = baseBranch.match(/^v(\d+\.\d+)-dev$/); + if (!match) { + console.log(`Branch ${baseBranch} does not match v*-dev pattern`); + return; + } + + const milestoneName = `v${match[1]}.0`; + console.log(`Looking for milestone: ${milestoneName}`); + + // Find the milestone + const milestones = await github.rest.issues.listMilestones({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open' + }); + + const milestone = milestones.data.find(m => m.title === milestoneName); + + if (!milestone) { + console.log(`Milestone ${milestoneName} not found`); + return; + } + + // Assign the milestone + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + milestone: milestone.number + }); + + console.log(`Assigned milestone ${milestoneName} to PR #${pr.number}`); From f6fa3024ad7e7e37fdeb77567ef9611ff5520ecf Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 23 Dec 2025 14:05:51 -0500 Subject: [PATCH 2/4] ci: add warning annotation if milestone not found --- .github/workflows/milestone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/milestone.yml b/.github/workflows/milestone.yml index 378f6a1eed4..83b04b4c52b 100644 --- a/.github/workflows/milestone.yml +++ b/.github/workflows/milestone.yml @@ -52,7 +52,7 @@ jobs: const milestone = milestones.data.find(m => m.title === milestoneName); if (!milestone) { - console.log(`Milestone ${milestoneName} not found`); + core.warning(`Milestone ${milestoneName} not found. Create it to enable automatic assignment.`); return; } From 6fb3ba49f4fbf1e3178199e68272bd7983e3c1be Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 23 Dec 2025 13:57:47 -0500 Subject: [PATCH 3/4] debug --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 62be4cc3d0c..c5cd9922e4a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +test + :

From 7a548cff8d2c1335694f21433a578f15aebb869b Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 23 Dec 2025 15:39:25 -0500 Subject: [PATCH 4/4] ci: allow milestone updates and add issues permission - Add issues:write permission required for updating PR milestones - Remove extraneous branch filter (handled in script) - Allow updating existing milestones when target branch changes - Skip if PR already has the correct milestone --- .github/workflows/milestone.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/milestone.yml b/.github/workflows/milestone.yml index 83b04b4c52b..969592c1500 100644 --- a/.github/workflows/milestone.yml +++ b/.github/workflows/milestone.yml @@ -3,15 +3,14 @@ name: Assign Milestone on: pull_request: types: [opened, reopened, edited] - branches: - - master - - "v*-dev" jobs: assign-milestone: runs-on: ubuntu-latest permissions: pull-requests: write + # Following needed because PRs are technically under issues + issues: write steps: - name: Assign milestone based on target branch uses: actions/github-script@v7 @@ -20,12 +19,6 @@ jobs: const pr = context.payload.pull_request; const baseBranch = pr.base.ref; - // Skip if PR already has a milestone - if (pr.milestone) { - console.log(`PR already has milestone: ${pr.milestone.title}`); - return; - } - // Skip if targeting master if (baseBranch === 'master') { console.log('PR targets master, skipping milestone assignment'); @@ -40,6 +33,13 @@ jobs: } const milestoneName = `v${match[1]}.0`; + + // Skip if PR already has the correct milestone + if (pr.milestone && pr.milestone.title === milestoneName) { + console.log(`PR already has correct milestone: ${pr.milestone.title}`); + return; + } + console.log(`Looking for milestone: ${milestoneName}`); // Find the milestone @@ -56,7 +56,10 @@ jobs: return; } - // Assign the milestone + // Assign or update the milestone + if (pr.milestone) { + console.log(`Updating milestone from ${pr.milestone.title} to ${milestoneName}`); + } await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo,