feat: add port-to-next label for forward-porting merged PRs - #24753
Merged
Conversation
Adds a generic `port-to-next` label that mirrors the `backport-to-*` labels but with a fixed target: on merge, the PR is cherry-picked onto an accumulating `port-to-next-staging` branch that opens/updates a single PR into `merge-train/spartan` (which flows to `next`). Reuses `scripts/backport_to_staging.sh` via optional STAGING_BRANCH / STAGING_PR_TITLE env overrides (defaults keep existing backport behavior). The backport workflow now resolves either label family; the update-pr-body and auto-merge (8h) automations cover the new staging branch.
Point the port-to-next staging PR at `next` rather than the merge-train/spartan train. Because `next` enforces squashed PRs, the staging PR now carries `ci-no-squash`, plumbed through a new optional STAGING_PR_LABELS env override in backport_to_staging.sh (applied on both PR creation and pre-existing staging PRs).
Adds a scheduled sweep that keeps `next` fed with the v5-next release line, alongside the per-PR port-to-next label. `port-v5-next-to-next.yml` runs daily (06:30 UTC) and via workflow_dispatch, calling `scripts/port_to_next.sh`. The script rebuilds the `port-v5-next-to-next` branch fresh from `next`, merges v5-next in, and — if that yields a delta — force-pushes and opens/updates one `ci-no-squash` PR into `next`. Rebuilding each run keeps the PR at the current delta and self-heals after merge (a later run finds nothing to port and closes the stale PR). Conflicts abort without disturbing the existing PR and notify #backports; the PR is left for human review (not auto-merged).
Switch the daily forward-port from a rebuild-each-run model to a long-lived `port-v5-next-to-next` branch that merges both next and v5-next in on each run. This preserves any conflict resolution pushed to the branch across runs (fast-forward push). Once the PR merges and the branch becomes an ancestor of next, the next run rebuilds it fresh from next with a --force-with-lease push. Conflicts abort without disturbing the existing PR and are resolved on the port branch.
On a merge conflict the daily forward-port now commits the conflicted merge (markers included) so the PR is still opened/updated as a resolution target, rather than aborting and leaving no PR. The script emits `conflicts` and `pr_url` step outputs; the workflow posts the PR link and conflicted files to #backports, with a separate notification reserved for genuine (non-conflict) failures.
spalladino
approved these changes
Jul 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a generic
port-to-nextlabel — the mirror image of the existingbackport-to-*labels, but with a single fixed target.When a merged PR carries
port-to-next, its merge commit is cherry-picked onto an accumulatingport-to-next-stagingbranch, which opens/updates one PR directly intonext. This gives us a one-click way to forward-port a fix landed on a release line intonext.How it works
Reuses the existing backport machinery rather than building a parallel system:
scripts/backport_to_staging.sh— honours optionalSTAGING_BRANCH/STAGING_PR_TITLE/STAGING_PR_LABELSenv overrides; defaults preserve today'sbackport-to-*behaviour, so the/backportskill and manual callers are unaffected. Labels are applied on both PR creation and a pre-existing staging PR..github/workflows/backport.yml— the label check now matchesbackport-to-,port-to-next. A resolve step maps the label family to(target, staging branch, PR title, labels, verb):port-to-next→ targetnext, stagingport-to-next-staging, labelsci-no-squash.port-to-nexttakes precedence if both families are present. Success/failure comments and the Slack + ClaudeBox conflict dispatch use the resolved values.merge-train-update-pr-body.yml—port-to-next-stagingadded to the push triggers so the PR body's commit list stays current.merge-train-auto-merge.yml— a newBRANCH_PATTERN=port-to-next(8h inactivity) auto-merge job, matching the backport-train job..claude/claudebox/backport.md+ merge-train-infra skill — document the port variant.The
port-to-nextGitHub label has been created on the repo.Daily forward-port sweep
In addition to the per-PR label, a scheduled job keeps
nextfed with everything on thev5-nextrelease line:.github/workflows/port-v5-next-to-next.yml— runs daily at 06:30 UTC (and onworkflow_dispatch, with an optionalsource_branchinput).scripts/port_to_next.sh— checks out the long-livedport-v5-next-to-nextbranch, merges bothnextandv5-nextinto it, and — if that produces a delta — opens/updates oneci-no-squashPR intonext.The branch is long-lived and accumulating, so any conflict resolution pushed to it is preserved across runs (fast-forward push). Once the PR is merged (the branch becomes an ancestor of
next), the next run rebuilds it fresh fromnextwith a--force-with-leasepush; a run with no delta overnextcloses the stale PR.On a merge conflict the run does not bail: it commits the conflicted merge (markers included) so the PR is still opened/updated as a resolution target, and posts the PR link + conflicted files to
#backports. Resolve by checking out the port branch, fixing the markers, and pushing. This PR is intentionally not auto-merged — it is left for human review.Notes
next, which enforces squashed PRs, so it carriesci-no-squashto allow the accumulated commits throughsquashed-pr-check.yml.Testing
Label-resolution logic exercised locally for all cases (port-only, backport, precedence, no-match); the
CREATE_ARGSlabel plumbing, script syntax (bash -n), verb capitalisation, and YAML validity all checked.