Skip to content

backport: post a backport checklist automatically on pull requests targeting main #19213

Description

@mrodm

Summary

Add a package detection utility script and a two-workflow pair that automatically posts a backport checklist comment on any PR targeting main that touches packages with active backport branches. The checklist lets authors opt in to backporting on a per-branch basis — no label required. Nothing is backported until a box is checked.

Background

Currently there is no mechanism to surface which backport branches are relevant for a given PR or to track which backports have been requested. Backports are easy to forget, especially as the number of maintained branches grows.

The checklist is implemented as a two-workflow pair to safely support PRs from forks: the pull_request workflow runs in the restricted fork context (read-only, no secrets), while the workflow_run workflow runs in the base repository context (with write permissions). Fork code is never checked out or executed with write permissions.

Deliverables

dev/scripts/backport_detect_packages.sh

Maps a list of changed file paths to the package names they belong to.

Detection logic: for each changed file, find the shallowest ancestor directory under packages/ that contains a manifest.yml. Read the name field from that manifest.yml — do not use the directory name as the package name. Handles the current flat structure and any future nested packages/<tech>/<name>/ structure.

Flags: --json (emits a JSON array instead of newline-separated output)

backport-packages-detect.yml

Runs on pull_request (opened/synchronize) targeting main. Read-only — no write permissions, no secrets.

  • Permissions: none (default read-only)
  1. Gets changed files from the PR event payload
  2. Calls backport_detect_packages.sh --json
  3. Uploads artifact: { "pr_number": 1234, "sha": "abc123", "packages": ["aws", "kubernetes"] }

post-backport-checklist.yml

Runs on workflow_run completion of backport-packages-detect. Runs in the base repository context with write permissions. Fork code is never executed here.

  • Permissions: pull-requests: write
  1. Downloads the artifact from the triggering workflow run
  2. For each package, looks up active backport branches via backport_check_active.sh
  3. If no active branches found across all packages: exits silently
  4. Posts or updates the checklist comment:
<!-- backport-checklist -->
## Backport checklist

Check the branches to backport this change to. PRs will be created automatically
on merge, or when you update this checklist after merge.

**aws**
- [ ] `backport-aws-6.14` (maintained until 2027-01-15)
- [ ] `backport-aws-3.17`

---

> [!TIP]
> If a branch above is no longer required, set `archived: true` in its entry in
> `.backports.yml` to stop it appearing in future checklists.
> If the branch has a known end-of-life date, prefer `maintained_until: "YYYY-MM-DD"` —
> it will be excluded automatically once that date passes.

On update (synchronize event): adds newly affected packages while preserving all existing checkbox states (checked or unchecked).

Considerations

  • Folder name vs. package name: the directory name under packages/ is not guaranteed to match the name field in manifest.yml. The script must read the name field from manifest.yml to get the authoritative package name — this is the value stored in .backports.yml and used as the lookup key across all backport tooling.

  • No pull_request_target: the two-workflow pattern (pull_request + workflow_run) is the intentional design to avoid the security risks of pull_request_target. Do not replace it with pull_request_target even if it seems simpler.

Acceptance criteria

  • Checklist appears automatically on PRs that touch packages with active backport branches
  • No checklist appears on PRs touching only non-package files
  • Checklist updates correctly when new commits touch additional packages, preserving checked boxes
  • Works correctly for PRs from forks
  • No checklist is posted if none of the touched packages have active backport branches
  • Package name is read from manifest.yml, not inferred from the directory name

Metadata

Metadata

Assignees

Labels

Team:EcosystemPackages Ecosystem team [elastic/ecosystem]

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions