Add milestone automation for merged PRs#356
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## trunk #356 +/- ##
============================================
- Coverage 53.84% 52.53% -1.32%
Complexity 4423 4423
============================================
Files 298 298
Lines 39468 39468
============================================
- Hits 21251 20733 -518
- Misses 18217 18735 +518
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
I'm not entirely sure about the closed milestone behavior. I'm not sure I like the idea that an aspect of a PR that I set manually -- the milestone -- might be automatically changed when I merge it. I guess it's meant to help me in case I forget to assign a new milestone if the previous one was already closed, but to me, it seems like it actually removes confidence, because now it feels like I'll always have to double-check. Maybe I'm biased by my experience with Gutenberg, where the milestone is closed when the RC is published, meaning that any bugfixes that need to go in afterwards and before the stable version is released will need to be assigned a closed milestone. I guess the release workflow is different for SCF (?) Anyway, how about we don't update the milestone if it's closed and instead add a comment to notify the PR author to make sure they're aware? |
|
I'm fine backing off the closed milestone process. It may be a solution in search of a problem. |
There was a problem hiding this comment.
Pull request overview
Adds a GitHub Actions workflow to automatically manage milestones on merged pull requests, supporting the repo’s release/changelog process (Fixes #152).
Changes:
- Introduces a
pull_request_targetworkflow that runs when PRs are closed and merged. - Selects a “target” milestone from open milestones using due-date-first, then version-title sorting.
- Assigns the target milestone when a merged PR has no milestone; posts a comment when the PR has a closed milestone.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Case 3: PR has a closed milestone - notify but don't change | ||
| console.log(`PR #${prNumber} has closed milestone: ${currentMilestone.title}. Adding notification comment.`); | ||
|
|
||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| body: `This PR was merged with a closed milestone (\`${currentMilestone.title}\`). Please verify this is intentional.\n\nIf not, the next open milestone is \`${targetMilestone.title}\`.` | ||
| }); |
There was a problem hiding this comment.
The workflow’s “closed milestone” branch only adds a comment and does not move the PR to the earliest open milestone. This conflicts with the PR description/expected behavior (“Updates to earliest open milestone + adds comment”) and the sample comment text (which says it was moved). Update this branch to call the Issues update API to set milestone: targetMilestone.number before/alongside creating the notification comment, and align the comment text accordingly.
| // Fetch all open milestones | ||
| const { data: milestones } = await github.rest.issues.listMilestones({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| state: 'open', | ||
| sort: 'due_on', | ||
| direction: 'asc' | ||
| }); |
There was a problem hiding this comment.
issues.listMilestones is paginated (default page size is limited), but this script only reads the first page. If there are more open milestones than the first page, the “earliest open milestone” selection can be wrong (especially for milestones without due dates that rely on title sorting). Consider fetching all pages (e.g., via Octokit pagination) or at least setting per_page: 100 and paging until exhausted before sorting.
| // Fetch all open milestones | |
| const { data: milestones } = await github.rest.issues.listMilestones({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| sort: 'due_on', | |
| direction: 'asc' | |
| }); | |
| // Fetch all open milestones (handle pagination) | |
| const milestones = await github.paginate( | |
| github.rest.issues.listMilestones, | |
| { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| sort: 'due_on', | |
| direction: 'asc', | |
| per_page: 100 | |
| } | |
| ); |
| name: Assign milestone to merged PR | ||
| runs-on: ubuntu-24.04 | ||
| permissions: | ||
| pull-requests: write |
There was a problem hiding this comment.
This job only calls Issues APIs (issues.listMilestones, issues.update, issues.createComment). Per GitHub’s fine-grained GITHUB_TOKEN permissions, issues: write is sufficient for updating a PR milestone and creating an issue comment on a PR, so pull-requests: write appears unnecessary. Dropping it would reduce the workflow’s privilege surface.
| pull-requests: write |
Summary
Adds a GitHub workflow that assigns merged, unmilestoned pull requests targeting
trunkto the explicitly configured next release milestone. The approach is inspired by Gutenberg's project-management automation, while keeping SCF's irregular and parallel release lines under maintainer control.Behavior
NEXT_MILESTONErepository variableThe workflow reads the PR's live state, handles paginated GitHub API responses, runs only for merges into
trunk, and uses onlyissues: writepermission. It fails visibly rather than guessing whenNEXT_MILESTONEis missing or invalid.The release documentation now explains how to configure the target:
The repository is configured with open milestone
6.9.2andNEXT_MILESTONE=6.9.2. Released milestones through6.9.1have been closed.Closes #152
Test plan
git diff --checktrunkand confirm it receives milestone6.9.2Use of AI Tools
Codex reviewed the original workflow, implemented the requested update under maintainer direction, and exercised its behavior with mocked GitHub API responses. The resulting changes were reviewed and validated locally before push.