[Backport pipeline] Add PR-driven backport branch creation#19636
[Backport pipeline] Add PR-driven backport branch creation#19636mrodm wants to merge 31 commits into
Conversation
Gate the integrations-backport pipeline so that UI-triggered builds are only allowed for members of the `ecosystem` team, using BUILDKITE_BUILD_CREATOR_TEAMS. Trigger-job builds from the integrations pipeline remain unrestricted. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add trigger-backport-create step to pipeline.yml and its companion script trigger_backport_create.sh. On every push to main that touches .backports.yml, the script detects new entries (vs HEAD^), resolves the merged PR number via the GitHub API, and uploads trigger steps that fire the integrations-backport pipeline with DRY_RUN=false, passing PR_NUMBER so the triggered build can post a result comment. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add notify_backport_pr.sh to post a success or failure comment on the merged PR after backport branch creation. Add the notify-pr step to pipeline.backport.yml, gated on PR_NUMBER being set, using buildkite-agent step get "outcome" to distinguish pass from failure. Also add GH_CLI_VERSION to the backport pipeline env. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch trigger_backport_create.sh and trigger_backport_dryrun.sh to pass values via meta_data instead of env in their trigger steps, so that backport_branch.sh receives them through buildkite-agent meta-data get, consistent with the input-variables step. Update notify_backport_pr.sh to read BACKPORT_BRANCH_NAME, PACKAGE_NAME, PACKAGE_VERSION, and PR_NUMBER from metadata with env var fallbacks. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract the pipeline-generation loop from trigger_backport_dryrun.sh and trigger_backport_create.sh into a shared trigger_backport_lib.sh. Both scripts now source the lib, wrap their context-specific setup in main(), and guard execution with a BASH_SOURCE check to allow sourcing for tests. Add test_trigger_backport.sh with 18 assertions covering dry-run and create modes, PR_NUMBER inclusion, existing/inactive entry skipping, mage error propagation, multiple entries, and invalid inventory handling. Add assert_file_contains/assert_file_not_contains helpers to test_helpers.sh and register the new suite in run_buildkite_scripts_tests.sh. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add notify_backport_pr.sh, trigger_backport_create.sh, trigger_backport_lib.sh, and test_trigger_backport.sh to non_package_patterns in common.sh so CI recognises changes to these files as non-package modifications. Add notify_backport_pr.sh to skip_ci_on_only_changed in pull-requests.json — PRs touching only this script (no unit tests) do not need a full CI run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…b.sh Move three inline snippets from trigger_backport_dryrun.sh and trigger_backport_create.sh into dedicated functions in the shared lib: - backports_yml_changed(from, to): git diff check for .backports.yml - load_old_backports_inventory(ref, file): git show at a given ref - resolve_pr_number(commit): GitHub API lookup, logs to stderr, echoes the number to stdout for capture Both trigger scripts are leaner; the logic is now testable in isolation. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ort.sh Replace trigger_backport_dryrun.sh and trigger_backport_create.sh with a single trigger_backport.sh. The script detects its mode from BUILDKITE_PULL_REQUEST: PR builds run in dry-run mode against the base branch; post-merge builds on main create the branches. Both pipeline.yml steps continue to express their own guards and dependencies — the shared script handles the rest via the extracted lib functions. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
… review Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent helper Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…old_backports_inventory and resolve_pr_number Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Given a package name and base version, resolves the base commit via `dev/scripts/get_release_commit.sh`, inserts a new entry into `.backports.yml` in sorted order (package ascending, version descending), and prints the derived branch name. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
💔 Build Failed
Failed CI StepsHistory
cc @mrodm |
TL;DRThe Remediation
Investigation detailsRoot CauseThis is a test dependency/setup issue, not a backport inventory fixture issue. The PR adds Relevant code paths:
Evidence
Those repeated failures happen before any trigger YAML is written, which is why every downstream assertion looking for Verification
Follow-upIf the Buildkite image happens to contain some other What is this? | From workflow: PR Buildkite Detective Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not. |
…anch name validation Fixes: NOTIFY_STATUS unbound variable, redundant temp file cleanup, backports_yml_changed pathspec simplification, and branch name regex divergence between shell and Go (stricter regex, legacy exceptions, mage ValidateBackportsInventory replaces shell function). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…arget mage mock in tests Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…in CI Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
5b262b4 to
a813501
Compare
…prefix assignment Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- notify_backport_pr: post distinct message when branch already existed vs. freshly created - test_trigger_backport: assert exit code 0 in run_generate instead of silently swallowing errors - trigger_backport: resolve PR number only after confirming .backports.yml changed Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
🔍 Preview links for changed docs |
| if: | | ||
| !( | ||
| build.source == 'ui' || | ||
| (build.source == 'ui' && build.creator.teams includes "ecosystem") || |
There was a problem hiding this comment.
If this condition change is merged as it is, developers will need to use the new method to create backport branches instead of the triggering the Buildkite pipeline.
@elastic/ecosystem WDYT ? Would this be to disruptive?
Before doing this it will be needed to do a sync of any backport branch created that is not part of the .backpotrs.yml file.
| if branchExist "$BACKPORT_BRANCH_NAME"; then | ||
| MSG="The backport branch: **$BACKPORT_BRANCH_NAME** is already created. Not updating contents of the branch." | ||
| buildkite-agent annotate "$MSG" --style "warning" | ||
| buildkite-agent meta-data set BRANCH_ALREADY_EXISTED true |
There was a problem hiding this comment.
This script could finish successfully in one of these two conditions:
- branch already exists
- branch is created successfully
Added this metadata to allow distinguish the scenario when this step finishes successfully. This metadata is going to be used by the notify step.
| if: | | ||
| build.branch == "nonexisting" |
There was a problem hiding this comment.
To be reverted before merging
| // branchRE matches a valid backport branch name: | ||
| // | ||
| // backport-<package>-<version> | ||
| // backport-<package>-<major>.<minor|x> |
There was a problem hiding this comment.
Even the regex allows branches like backport-aws-6.x, the automation will not create it.
I thought to accept those branches in the .backpotrs.yml since probably there could be some of there created , and they should be considered valid. However, automation (for now) will not create those.
| local PACKAGENAMES_SCRIPTS_FOLDER="dev/packagenames" | ||
| local BACKPORTS_SCRIPTS_FOLDER="dev/backports" | ||
| local DEV_SCRIPTS_FOLDER="dev/scripts" | ||
| local BACKPORTS_FOLDER="dev/backports" |
There was a problem hiding this comment.
Duplicated. BACKPORTS_SCRIPTS_FOLDER references the same folder.
There was a problem hiding this comment.
This PR also updates the documentation to remove the references of triggering the Buildkite pipeline in favor of using the PR-driven approach updating .backports.yml file
There was a problem hiding this comment.
Changes in this file are just removing empty lines or whitespaces.
There was a problem hiding this comment.
Created .buildkite/scripts/trigger_backport.sh to trigger in just one script the dry-run and create modes
💚 Build Succeeded
History
cc @mrodm |
Proposed commit message
WHAT:
Adds an automated, PR-driven workflow to create backport branches from
.backports.yml.When a PR that adds new entries to
.backports.ymlis merged intomain, the CI pipelinedetects the new entries and triggers the
integrations-backportpipeline to create thecorresponding branches automatically. A comment is then posted back to the originating PR
reporting success or failure.
Key components:
.backports.ymlinventory — source of truth listing backport branches with theirpackage, base version, base commit, and lifecycle metadata (
archived,maintained_until).trigger_backport.sh/trigger_backport_lib.sh— diff the old and new inventory on eachpush to
main, validate the new inventory viamage ValidateBackportsInventory, andemit Buildkite trigger steps for any newly-added active entries.
pipeline.yml— addscheck-backports-inventory(schema validation on PRs),trigger-backport-dryrun(dry-run on PRs), andtrigger-backport-create(real creationon merge to main) steps.
pipeline.backport.yml— updated to acceptBACKPORT_BRANCH_NAMEviaget(passed by the trigger step), restricts UI access to the
ecosystemteam, adds anotify-prstep that posts a success/failure comment back to the originating PR.notify_backport_pr.sh— posts a per-run comment on the PR.AddBackportEntrymage target — developer tool to add a new entry to.backports.yml,resolving the base commit via
dev/scripts/get_release_commit.shand inserting the entryin sorted order (package ascending, version descending).
AddEntryindev/backports/inventory.go— validates the package name against theknown packages set before writing, preventing branches that would fail
branchRE.test_trigger_backport.sh— unit-testsgenerate_trigger_pipelinewitha per-target mage mock (
MOCK_MAGE_VALIDATE_EXIT/MOCK_MAGE_CHECK_EXIT).WHY:
Previously, backport branches had to be created manually by running
backport_branch.shby hand. This automation eliminates that toil: once a developer adds an entry to
.backports.ymlin a PR, the branch is created automatically on merge, and the PR authoris notified of the outcome without needing to monitor CI separately.
Author's Checklist
test_trigger_backport.shmage ValidateBackportsInventorypasses on.backports.ymlmage AddBackportEntry <package_name> <base_version>adds a new backport entry with the right values and in the right positionpipeline.backport.ymldry-run mode tested end-to-end in a Buildkite builddocs/extend/developer-workflow-support-old-package.mdanddocs/ci_pipelines.md)How to test this PR locally
go test ./dev/backports/...bash .buildkite/scripts/test_trigger_backport.shmage ValidateBackportsInventoryAddBackportEntrymage target:.backports.ymland verify thattrigger-backport-dryrunemits the correct trigger steps.Related issues