Skip to content

[ML] Auto-approve backport PRs so auto-merge can complete#3094

Draft
edsavage wants to merge 3 commits into
elastic:mainfrom
edsavage:feature/auto-approve-backports
Draft

[ML] Auto-approve backport PRs so auto-merge can complete#3094
edsavage wants to merge 3 commits into
elastic:mainfrom
edsavage:feature/auto-approve-backports

Conversation

@edsavage

@edsavage edsavage commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Backport PRs opened by the auto-backport workflow have auto-merge enabled but never merge (e.g. #3092). The release branches require one approving review via the org-wide ruleset [org] Require a PR (id 221255, source: elastic), which has no bypass actors. The backport PR was authored by github-actions[bot], which (a) cannot approve its own PR and (b) does not trigger CI on the PR it opens — so the required review is never satisfied and auto-merge stays BLOCKED.

What this PR changes

Adopts the production-proven author-with-ephemeral-token / approve-with-GITHUB_TOKEN pattern (used by elastic/cloud, elastic/elasticsearch-ruby and the ECP GitOps repos such as elastic/catalog-sync-config):

  • Mints a short-lived token from Elastic's central ephemeral-token service (elastic/ci-gh-actions/fetch-github-token@v1, ci-prod, via OIDC->Vault) before the backport action and passes it as the action's github_token, so the backport PRs are authored by the ephemeral-token identity. This makes them (a) a distinct identity from github-actions[bot] and (b) subject to CI.
  • Approves each backport PR with GITHUB_TOKEN (github-actions[bot]) — a different identity from the author, so the approval counts — then enables auto-merge (squash).
  • Adds id-token: write for OIDC.
  • Safe no-op before the Token Policy is registered: the token fetch uses continue-on-error and the workflow falls back to authoring with GITHUB_TOKEN; auto-approval is skipped with a warning and the backport awaits a manual approval.

Why this counts (verified, not assumed)

elastic/catalog-sync-config merges renovate PRs under the identical org-only ruleset (221255 + 1225254; count: 1, require_code_owner_review: false, require_last_push_approval: false — same as ml-cpp): a PR authored by one bot and approved by github-actions[bot] (a non-author identity) shows reviewDecision: APPROVED and auto-merges (e.g. elastic/catalog-sync-config#83, elastic/catalog-info#4264). ml-cpp already has Allow GitHub Actions to create and approve pull requests enabled (can_approve_pull_request_reviews: true). GitHub's only relevant restriction is self-approval, which the author != approver split avoids.

Required to activate (not in this repo)

Register the GitHub Token Policy in elastic/catalog-info (elastic/catalog-info#4281), scoped as:

  • bound_claims.workflow_ref: elastic/ml-cpp/.github/workflows/backport.yml@*
  • permissionset.additional_permissions: { contents: write, pull_requests: write } (contents to push the backport branch, pull_requests to open the PR), selector repository: elastic/ml-cpp
  • owner: group:ml-core

Notes

  • The earlier approach (approve with the ephemeral token) relied on an app holding only pull_requests: write being an eligible approver, which has no production precedent in the org. This pattern instead approves with GITHUB_TOKEN, which is proven to count.
  • elastic/ci-gh-actions/fetch-github-token@v1 is used by tag; happy to pin to a SHA if org policy requires it.

Test plan

  • Merge with the Token Policy unregistered -> a subsequent backport still opens the PR (authored by github-actions[bot]) + arms auto-merge, logs the "ephemeral token unavailable" warning, and does not fail.
  • Register the Token Policy, trigger a backport, and confirm the PR is authored by the ephemeral-token identity, CI runs, github-actions[bot] approves it, and it merges once checks pass.

Made with Cursor

Backport PRs already have auto-merge enabled, but they never merge because the
release branches require one approving review via an org-wide ruleset ("[org]
Require a PR") that has no bypass actors. The bot that opens the backport
(github-actions[bot]) cannot approve its own PR, so the review requirement is
never satisfied.

Mirror the Elasticsearch auto-backport-and-merge model: mint a short-lived
token for a dedicated backport-approver GitHub App (a distinct, non-author
identity) and have it approve each backport PR, after which the existing
auto-merge step completes once required checks pass.

The approval step is skipped when the App credentials are not configured, so
this is a safe no-op until ML_BACKPORT_APPROVER_APP_ID (variable) and
ML_BACKPORT_APPROVER_PRIVATE_KEY (secret) are set.

Co-authored-by: Cursor <cursoragent@cursor.com>
@edsavage
edsavage marked this pull request as draft July 22, 2026 22:05
edsavage and others added 2 commits July 23, 2026 10:27
Rework the auto-approve step to mint a short-lived token from Elastic's central
ephemeral-token GitHub App (elastic/ci-gh-actions/fetch-github-token, OIDC ->
Vault) instead of a bespoke, self-owned GitHub App, which we cannot get approved
to create. The ephemeral-token identity approves each clean, bot-authored
backport so the org-wide "[org] Require a PR" review requirement is satisfied and
the existing auto-merge can complete.

The token fetch uses continue-on-error so the workflow stays safe until the
backport Token Policy is registered in elastic/catalog-info: the approval is
skipped with a warning and backports simply await a manual approval.

Requires: a TokenPolicy (pull_requests: write, scoped to elastic/ml-cpp, bound to
this workflow ref) registered in elastic/catalog-info, and confirmation from
Platform Engineering Productivity that an ephemeral-token approval counts toward
the required review.

Co-authored-by: Cursor <cursoragent@cursor.com>
…h-GITHUB_TOKEN

Adopt the production-proven pattern used by elastic/cloud, elasticsearch-ruby
and the ECP GitOps repos: mint the ephemeral token before the backport action
and use it to author the backport PRs, then approve with GITHUB_TOKEN
(github-actions[bot]).

Because the PRs are authored by the ephemeral-token identity, github-actions[bot]
is a distinct identity and its approval counts toward the org "[org] Require a PR"
ruleset (verified against elastic/catalog-sync-config, which merges under the
identical org-only ruleset). Authoring with a real token also makes CI actually
run on the backport PRs. Falls back to GITHUB_TOKEN authoring (no auto-approval)
when the Token Policy is not yet registered.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants