Skip to content

CI: Auto cherry-pick to Gutenberg release branches - #78879

Open
cbravobernal wants to merge 3 commits into
trunkfrom
add/auto-cherry-pick-gutenberg-release
Open

cbravobernal wants to merge 3 commits into
trunkfrom
add/auto-cherry-pick-gutenberg-release

Conversation

@cbravobernal

@cbravobernal cbravobernal commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

What?

Adds .github/workflows/cherry-pick-gutenberg-release.yml, which automatically cherry-picks PRs labeled Backport to Gutenberg RC onto the current Gutenberg release branch.

It runs on every push to trunk, every 15 minutes, and on demand (workflow_dispatch). Each run:

  1. Resolves the target branch as the highest release/X.Y. Only plain X.Y names count, so scratch branches like release/23.5-cherry-pick are ignored.
  2. Finds every merged PR to trunk that still has the Backport to Gutenberg RC label, and cherry-picks them in merge order.
  3. Pushes the release branch, then for each picked PR removes the label, sets the Gutenberg X.Y milestone (as npm run other:cherry-pick does, so the changelog picks it up), and comments with the target branch and cherry-pick SHA.
  4. On conflict, comments with manual-resolution instructions and leaves the label in place.

Why?

Today these picks are done by hand. For example, #78848 opened a manual cherry-pick PR onto release/23.3. This automates the label-driven picks, the same way WP backports are already automated.

Design notes

  • No pull_request_target. Following the review discussion and zizmor's dangerous-triggers rule, the workflow never runs in the context of a PR. Instead of reacting to PR events, it sweeps for labeled PRs, like the manual script does. This works the same for PRs from forks and picks up labels added after the merge. The trade-off is that a label added after the merge waits up to 15 minutes. That's fine for RC picks.
  • Versionless label. Gutenberg's two-week cadence makes a per-release label (like WP's Backport to WP X.Y Beta/RC) impractical, so the target branch is resolved instead. The chosen target is in the PR comment, so a wrong target (e.g. a label applied after stable shipped but before the next branch is cut) is easy to spot.
  • Safe to rerun. Runs are serialized, and a pending run that gets replaced loses nothing, because every run sweeps all labeled PRs. The push happens before any PR is touched, so a failed push leaves every label in place for the next run. A hidden marker in the conflict comment stops a conflicting PR from being commented on every 15 minutes; it is retried once against the next release branch. A PR whose change is already on the branch (picked by hand, label left on) just gets the label removed.
  • Cheap when idle. The repository is only cloned when there is something to pick. Other runs make a few API calls and exit.
  • Pushes with the existing GUTENBERG_TOKEN secret, which bypasses release/* push protection (the restriction Backport to 23.3: 10 cherry-picks for stable #78848 worked around). GITHUB_TOKEN only gets contents: read plus issue/PR write.

Not covered (still manual)

  • CI-infra picks that aren't label-driven (e.g. browserslist / test-data freshness).
  • Backport to Gutenberg Minor Release; can follow in a separate PR.

Testing

Dry-run locally with both embedded scripts in a harness: real read-only GitHub API calls, real git in a scratch worktree, push and PR writes stubbed.

Needs a maintainer to watch the first real run after merge. On its first run it will pick up whichever PRs carry the label at that point.

🤖 Generated with Claude Code

@cbravobernal
cbravobernal requested a review from desrosj as a code owner June 2, 2026 11:39
@cbravobernal cbravobernal self-assigned this Jun 2, 2026
@cbravobernal cbravobernal added [Type] Build Tooling Issues or PRs related to build tooling [Type] Enhancement A suggestion for improvement. labels Jun 2, 2026
@cbravobernal
cbravobernal requested a review from Mamaduka June 2, 2026 12:16
@cbravobernal cbravobernal added [Package] Project management automation /packages/project-management-automation [Type] Project and removed [Type] Enhancement A suggestion for improvement. [Type] Build Tooling Issues or PRs related to build tooling labels Jun 2, 2026
# Using pull_request_target instead of pull_request so that the workflow
# has access to repository secrets for fork PRs.
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target
pull_request_target:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

After recent events in the security world, are we still using pull_request_target?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We are still using it. And the script is meant to run only in already reviewed and merged PRs. But happy to have a second opinion. @pkevan may help us?

@arthur791004

Copy link
Copy Markdown
Contributor

Would it be better to also support "Backport to Gutenberg Minor Release" as well?

@cbravobernal

Copy link
Copy Markdown
Contributor Author

Would it be better to also support "Backport to Gutenberg Minor Release" as well?

Gutenberg Minors are usually less common than cherry-picking to RCs before a point release, maybe we could do it in a different PR.

Mirror the existing WP Auto Cherry-Pick workflow for Gutenberg's own
release branches. On merge of a PR labeled `Backport to Gutenberg RC`,
cherry-pick the merge commit onto the highest `release/X.Y` branch,
push, remove the label, and comment the target branch + cherry-pick SHA.

The Gutenberg backport label is versionless (the two-week cadence makes
a per-release label impractical), so the target branch is resolved by
semver-sorting `release/*` and picking the highest. Conflicts post a
manual-resolution comment, matching the WP workflow.

This removes the need for manual cherry-pick PRs like #78848 for the
label-driven picks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cbravobernal
cbravobernal force-pushed the add/auto-cherry-pick-gutenberg-release branch from 34570aa to f495e7d Compare October 14, 2026 13:58
@github-actions github-actions Bot removed the [Package] Project management automation /packages/project-management-automation label Oct 14, 2026
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @gutenbergplugin.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: gutenbergplugin.

Co-authored-by: cbravobernal <cbravobernal@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: arthur791004 <arthur791004@git.wordpress.org>

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

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

Comment thread .github/workflows/cherry-pick-gutenberg-release.yml Fixed
Comment thread .github/workflows/cherry-pick-gutenberg-release.yml Fixed
Comment thread .github/workflows/cherry-pick-gutenberg-release.yml Fixed
- Only resolve plain release/X.Y branches; scratch branches like
  release/24.2-cherry-pick sorted above release/24.2 and would be picked.
- Filter in the job-level `if` and move concurrency to the job, so
  unrelated trunk merges no longer replace a pending backport run, and
  adding an unrelated label no longer retries a conflicted cherry-pick.
- Pass values through step outputs and `env` instead of GITHUB_ENV.
- Set the release milestone, as `npm run other:cherry-pick` does.
- Bump actions/checkout to v7.0.1 to match the other workflows.
- Document the workflow in the plugin release guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread .github/workflows/cherry-pick-gutenberg-release.yml Fixed
zizmor flags pull_request_target as a dangerous trigger, and it gives the
job write tokens on events any PR author can trigger. Run on push to trunk,
on a 15-minute schedule, and on demand instead, and cherry-pick every
merged PR that still carries the backport label, in merge order.

- Works the same for fork PRs, and picks up labels added after merge.
- Pushes before touching any PR, so a failed push leaves every label in
  place for the next run.
- Leaves a hidden marker in the conflict comment, so a conflicting PR is
  commented on once per release branch instead of on every run.
- Removes the label when the change is already on the branch.
- Clones the repository only when there is something to pick.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants