Skip to content

Add milestone automation for merged PRs#356

Merged
cbravobernal merged 5 commits into
trunkfrom
feature/milestone-automation
Jul 10, 2026
Merged

Add milestone automation for merged PRs#356
cbravobernal merged 5 commits into
trunkfrom
feature/milestone-automation

Conversation

@kraftbj

@kraftbj kraftbj commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a GitHub workflow that assigns merged, unmilestoned pull requests targeting trunk to 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

Current state Action
No milestone Assign the open milestone named by the NEXT_MILESTONE repository variable
Open milestone Keep it unchanged
Closed milestone Keep it unchanged and add one idempotent warning comment

The workflow reads the PR's live state, handles paginated GitHub API responses, runs only for merges into trunk, and uses only issues: write permission. It fails visibly rather than guessing when NEXT_MILESTONE is missing or invalid.

The release documentation now explains how to configure the target:

gh variable set NEXT_MILESTONE --body "X.Y.Z"

The repository is configured with open milestone 6.9.2 and NEXT_MILESTONE=6.9.2. Released milestones through 6.9.1 have been closed.

Closes #152

Test plan

  • Exercise open, closed, duplicate-warning, assignment, missing-variable, and missing-target paths with mocked GitHub API responses
  • Parse the workflow as YAML
  • Run Prettier against the workflow
  • Run markdownlint against the release documentation
  • Run git diff --check
  • Merge an unmilestoned PR into trunk and confirm it receives milestone 6.9.2

Use 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.

@github-actions

github-actions Bot commented Jan 14, 2026

Copy link
Copy Markdown

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 props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props kraftbj, cbravobernal, bernhard-reiter, priethor.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@codecov

codecov Bot commented Jan 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.53%. Comparing base (9becdab) to head (62ddd94).
⚠️ Report is 1 commits behind head on trunk.

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     
Flag Coverage Δ
e2e-js 45.84% <ø> (-0.02%) ⬇️
e2e-php 40.40% <ø> (-1.97%) ⬇️
javascript 15.07% <ø> (ø)
phpunit 29.95% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ockham

ockham commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

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?

@kraftbj

kraftbj commented Jan 22, 2026

Copy link
Copy Markdown
Contributor Author

I'm fine backing off the closed milestone process. It may be a solution in search of a problem.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_target workflow 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.

Comment on lines +80 to +88
// 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}\`.`
});

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +39
// 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'
});

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
// 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
}
);

Copilot uses AI. Check for mistakes.
name: Assign milestone to merged PR
runs-on: ubuntu-24.04
permissions:
pull-requests: write

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
pull-requests: write

Copilot uses AI. Check for mistakes.
@cbravobernal cbravobernal added this to the 6.9.2 milestone Jul 10, 2026
@cbravobernal
cbravobernal merged commit 50ee89d into trunk Jul 10, 2026
20 checks passed
@cbravobernal cbravobernal added [Type] Project Management documentation Improvements or additions to documentation github_actions Pull requests that update GitHub Actions code labels Jul 10, 2026 — with ChatGPT Codex Connector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation github_actions Pull requests that update GitHub Actions code [Type] Project Management

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release management: classify PRs in the right milestone to generate changelog

4 participants