[ML] Fix backport-pending label handling for auto-backports - #3128
Conversation
remove-backport-pending never ran for auto-merged backports: auto-merge was armed with GITHUB_TOKEN, so GitHub attributed the deferred merge to github-actions[bot], and merges by github-actions[bot] do not trigger workflows (GitHub's recursion guard). The source PR's backport-pending label therefore had to be cleared by hand. Arm auto-merge with the ephemeral App token (elastic-vault-github-plugin-prod[bot]) that already authors the backport PRs, falling back to GITHUB_TOKEN only when it is unavailable. GitHub attributes the deferred merge to whichever identity enabled auto-merge, so an App-identity merge triggers remove-backport-pending normally. The approval stays as github-actions[bot] (a distinct identity from the author, so it counts). This is the GitHub-recommended remedy and mirrors what elastic/kibana gets for free by merging as a machine user. Co-authored-by: Cursor <[email protected]>
|
Pinging @elastic/ml-core (Team:ML) |
|
Hi @edsavage, I've created a changelog YAML for you. |
… PRs copySourcePRLabels copied every source label except 'backport' and version labels onto the backport PRs the action creates, so backport-pending and auto-backport leaked onto them. backport-pending is misleading on a backport (it isn't itself awaiting backports) and pollutes 'pending backports' queries; auto-backport is meaningless there (the 'backport' label already guards against re-backporting). Exclude both from the copy regex; :ml, >type and other labels still propagate. Co-authored-by: Cursor <[email protected]>
There was a problem hiding this comment.
Pull request overview
Updates the auto-backport automation so that source PR cleanup (backport-pending removal) runs even when backport PRs are auto-merged, by ensuring the eventual merge is attributed to an App identity (not github-actions[bot], which is subject to GitHub Actions recursion-guard suppression). Also tightens label propagation so backport PRs don’t inherit source-only labels.
Changes:
- Arm
gh pr merge --autousing the ephemeral App token when available, while still approving viaGITHUB_TOKENto satisfy required-review rules. - Update
.backportrc.jsonto stop copyingbackport-pendingandauto-backportonto backport PRs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
.github/workflows/backport.yml |
Uses the ephemeral App token to enable auto-merge so the merge event triggers remove-backport-pending as intended. |
.backportrc.json |
Excludes backport-pending and auto-backport from copied labels so backport PRs aren’t misleadingly labeled. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Verification note — remaining test-plan items await the next auto-backport round
When that next round happens, check off:
Static confirmation already in place on |
Non-destructive verification (mechanism in place)Ahead of the next live auto-backport round, I verified the merged code/config on 1.
2.
3. Live evidence status — no genuine auto-backport round has occurred since this merged ( Next validation opportunity: #3131 carries |
Summary
The
remove-backport-pendingjob clearsbackport-pendingfrom a source PR once all of its backports have merged. It never runs for auto-merged backports: auto-merge was armed withGITHUB_TOKEN, so GitHub attributes the deferred merge togithub-actions[bot], and merges attributed togithub-actions[bot]do not trigger workflows — GitHub's built-in recursion guard (docs: "events triggered by theGITHUB_TOKENwill not create a new workflow run"). Sobackport-pendinggot stuck on the source PR and had to be removed by hand (seen on #3078 and #3115).Fix (direct, not a workaround)
Arm auto-merge with the ephemeral App token (
elastic-vault-github-plugin-prod[bot]) that already authors the backport PRs, instead ofGITHUB_TOKEN. GitHub attributes a deferred auto-merge to whichever identity enabled it, and merges by a GitHub App identity do trigger downstream workflows — soremove-backport-pendingfires normally on merge.github-actions[bot](step-levelGITHUB_TOKEN), a distinct identity from the ephemeral-token author, so it satisfies the required review (a token can't approve its own PR).GITHUB_TOKENonly when the ephemeral token is unavailable (Token Policy not registered); in that degraded case cleanup still needs a manual touch, but backports still open and can be merged by a human.This is the GitHub-recommended remedy (use an App/PAT identity for the merge, per the docs above) and reuses the exact infrastructure we already rely on to make CI trigger on backport PRs. It's the same thing
elastic/kibanagets for free by authoring/merging backports as thekibanamachineuser rather thangithub-actions[bot].Supersedes #3127 (scheduled-sweep backstop), which treated the symptom rather than the cause.
Test plan
main.>bug/auto-backportPR with version labels; confirm backports open (ephemeral-authored), are approved bygithub-actions[bot], and auto-merge on green.remove-backport-pendingruns (check the Actions tab for the backport PR's merged event) andbackport-pendingis cleared from the source PR without manual intervention.Fixes the
GITHUB_TOKEN-suppression cleanup gap from the auto-backport-and-merge work (#3094, #3103, #3122).Implications for the auto-backport-and-merge workflow — no change to the merge gate
This is strictly additive to the auto-backport-and-merge flow validated in #3122/#3115. The "merge only when CI is green" guarantee is enforced by branch protection, not by the token that arms auto-merge, so it is untouched:
9.5/9.4/8.19) require thebuildkite/ml-cpp-pr-buildsrollup +CLAstatus checks and 1 approving review, with no push restrictions (restrictions: none).gh pr merge --autohonours these regardless of which identity enabled it — GitHub still holds the merge until CI is green and the review is satisfied.github-actions[bot]), which is what un-suppresses the on-mergeremove-backport-pendingrun. Timing/behaviour of the merge itself is identical.Nothing new is triggered that shouldn't be:
backportjob on a backport PR's merge event stays skipped (!contains(labels,'backport')), so no recursive backporting.remove-backport-pendingnewly fires, which is the goal.Permissions: release branches have
restrictions: none, and the TokenPolicy (elastic/catalog-info #4297) grants the ephemeral identitycontents: write+pull_requests: write, so it can complete the merge once the gate passes. If it ever couldn't,gh pr mergeerrors are swallowed (|| echo ::warning) and the PR simply stays open — fail-safe: the worst case is a stuck-open PR, never a premature or unreviewed merge.Fallback path unchanged: if the ephemeral token isn't minted,
MERGE_TOKENfalls back toGITHUB_TOKEN, exactly matching today's behaviour (backports open, auto-merge armed, cleanup needs a manual touch).Also: stop copying
backport-pending/auto-backportonto the backport PRs.backportrc.json'scopySourcePRLabelscopied every source label exceptbackportand version labels onto the backports the action creates, sobackport-pendingandauto-backportleaked onto them (observed on #3125/#3126).backport-pendingon a backport is misleading (it isn't itself awaiting backports) and pollutes "pending backports" queries;auto-backportis meaningless there (thebackportlabel already guards against re-backporting).Fix: exclude both from the copy regex —
:ml,>typeand other labels still propagate.main-only, same as the merge-identity change (the backport action runs frommain's config when a source PR merges tomain).Test plan (label copy)
backport+:ml+>type+ their version label, but notbackport-pendingorauto-backport.