backport: extract mage backport targets into standalone cmd/backport CLI sub-module - #20556
Conversation
Replaces all mage backport targets with a self-contained Go sub-module at cmd/backport/ that builds a `backport` binary. The sub-module has its own go.mod and cmd/backport/.go-version (pinned to main's Go version) so the tool always compiles with a modern toolchain even on backport branches that carry an older root .go-version (e.g. 1.19/1.20). Key changes: - cmd/backport/main.go: CLI binary with subcommands validate-inventory, check-active, validate-branch-name, check-owners, detect-packages, render/parse/update-checklist, sync-changelog, post-comment, apply, check-changelog-versions, add-entry - cmd/backport/go.mod: standalone sub-module; mage pinned via `tool` directive (Go 1.24+); no replace directive — fully self-contained - Library packages moved from dev/backports/ into the sub-module; dev/citools, dev/codeowners, dev/gitutil copied (originals kept for root module use); dead code pruned from the copies - Binary output: build/backport (gitignored, matching elastic-package convention); BACKPORT_BIN exported in common.sh - with_backport() builds in a subshell so the Go version switch does not leak into the caller (fixes go mod tidy in backport_branch.sh) - All Buildkite scripts and GitHub Actions workflows updated; new check-backport-tool Buildkite step runs cmd/backport tests using cmd/backport/.go-version Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- non_package_patterns.txt: replace ^dev/backports/ (deleted) with ^cmd/backport/; add check_backport_tool.sh; sort entries alphabetically - pull-requests.json: add check_backport_tool.sh to skip_ci_on_only_changed; cmd/backport/ is intentionally not skipped so tool changes run full CI Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- dev/gitutil: remove Git.RunToStderr (no callers in root module; cmd/backport/gitutil keeps its own copy used by apply and sync) - dev/citools: make parsePackageManifest private (only called internally by ReadPackageManifest in the same file) - dev/codeowners: remove ParseOwners (no callers outside tests; cmd/backport/codeowners keeps its own copy used by compare.go) - dev/codeowners test: drop TestParseOwners; replace remaining ParseOwners calls with a mustParseOwners helper that calls scanGithubOwners directly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move ReportFailedTests and RequiresUpdate (the two mage targets that import go-gh/v2 via dev/testsreporter and dev/requiresupdate) into a new magefile_main_only.go. These targets are only invoked from main-branch pipelines; backport branches never call them. Update backport_branch.sh to exclude this file and the two dev packages when creating a backport branch, so go mod tidy drops go-gh/v2. This allows backport branches to retain their original Go version — .go-version is no longer copied from main. go mod tidy now runs in a subshell that installs Go from the backport branch's own .go-version via gvm; main's Go version is restored in the parent shell afterwards. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Format (go-licenser + goimports) and Check (Build → Format → Tidy → Test) targets to the cmd/backport magefile, matching the root magefile pattern. Tool deps pinned via tools.go (//go:build tools) consistent with the root module. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Change the build output path from $GITHUB_WORKSPACE/backport to $GITHUB_WORKSPACE/build/backport in all four backport workflows and process-checked-branches.sh, consistent with the Buildkite BACKPORT_BIN path and the magefile Build target. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The run: value started with a double-quoted string, causing YAML to treat it as a quoted scalar and leave the subcommand as invalid trailing content. Convert to a block scalar (run: |) to match the surrounding steps. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Go's flag package stops parsing at the first non-flag argument, so --json must come before the positional SHA arguments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onflicts When a commit on main touches multiple packages, cherry-picking it onto a backport branch that doesn't have all the same packages previously reported a spurious conflict instead of succeeding. Add resetNonPackageChanges() which iterates git status --porcelain after the cherry-pick and resets each file outside the target package dir to HEAD: - git checkout HEAD -- file (handles clean staged changes and UU conflicts) - git rm --force -- file fallback (handles DU modify/delete conflicts where HEAD has the file deleted, e.g. packages absent from the backport branch) A note is printed to stderr when files outside the package are reset. Add three integration tests covering all three cases: - modify/delete conflict (file absent from backport branch) - regular UU conflict (file exists on both branches, different edits) - clean apply to other package (file exists, no conflict, still discarded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace `go test` with `mage check` so the CI step exercises Build, Format, Tidy, and Test together. Add check_git_diff at the end to catch any files left dirty by format or tidy. Use add_bin_path + with_mage (from common.sh) to set up Go and install mage from inside cmd/backport/, matching the version pinned in cmd/backport/.go-version. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Changes to the main-only mage targets file should not trigger package tests. Also fixes a stale test path (dev/backports/ no longer exists) replaced with the correct cmd/backport/ path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update all references in backport_branch.sh, non_package_patterns.txt, and test_non_package_patterns.sh. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
It is dev tooling (duplicate-name checker), not package content. Consistent with dev/codeowners, dev/gitutil, and similar patterns. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backport branches must use the backport implementation from cmd/backport.
| echo "--- Removing dev/testsreporter and dev/requiresupdate (go-gh/v2 not needed on backport branches)..." | ||
| rm -rf "${DEV_FOLDER}/testsreporter" "${DEV_FOLDER}/requiresupdate" |
There was a problem hiding this comment.
These packages are just used in daily jobs. That why they are removed, and therefore they will be considered when running go mod tidy in backport branches.
| echo "--- Removing dev/backports (in favor of cmd/backport)..." | ||
| # Remove the previous backport code from dev/backport, it should be used from cmd/backport instead. | ||
| rm -rf "${DEV_FOLDER}/backports" |
There was a problem hiding this comment.
Removing this as a safety , in case there could be backport branches that include now this folder.
With this PR, all this logic should be taken from cmd/backport folder.
| ( | ||
| echo "--- Installing Go $(cat "${WORKSPACE}/.go-version") (from backport branch .go-version) for go mod tidy..." | ||
| eval "$("${BIN_FOLDER}/gvm" "$(cat "${WORKSPACE}/.go-version")")" | ||
| go version | ||
| # go-gh/v2 is intentionally absent so this works with the backport branch's | ||
| # original Go toolchain version. | ||
| echo "--- Running go mod tidy to update dependencies related to magefile and dev scripts..." | ||
| go mod tidy | ||
| ) |
There was a problem hiding this comment.
This go mod tidy is going to be executed in the context of the backport branch.
That's why it uses the same go version from that branch to avoid changing dependencies unexpectedly.
|
|
||
| echo "--- Validating custom backport branch name" | ||
| if ! mage ValidateBackportBranchName "${PACKAGE_NAME}" "${BACKPORT_BRANCH_NAME}"; then | ||
| if ! backport validate-branch-name "${PACKAGE_NAME}" "${BACKPORT_BRANCH_NAME}"; then |
There was a problem hiding this comment.
Example of use of this new tool.
In Buildkite first, it needs to be built using with_backpotr.
There was a problem hiding this comment.
Under dev/ folder all the logic related to backports has been removed.
It is just kept code related to or used by the CI
There was a problem hiding this comment.
This new magefile is just to be used in the daily CI jobs.
Splitting this file allows us to not copy these targets to backport branches.
One drawback of copying these targets to backport branches is that they require go-gh/v2 that requires a newer go version that some of our backport branches.
🚀 Benchmarks reportTo see the full report comment with |
| paths[i] = p.Path | ||
| } | ||
| slices.Sort(paths) | ||
| sort.Strings(paths) |
There was a problem hiding this comment.
This is changed to avoid errors in backport branches where slices cannot be used. For instances branches like backport-kubernetes-1.39 that sets Golang 1.19.1
|
Tested to apply these changes in different backport branches:
|
There was a problem hiding this comment.
i was thinking on how to solve this "file duplication" in a better way... claude suggested to use the replace directive on the go.mod of cmd/backport so it point into /dev/citools (for this file example) . not sure is worth the change... in any case a comment on the file perhaps can give the context that this are originated on /dev/ and where copied into the tool?
There was a problem hiding this comment.
Added some comments in those files in this commit: c021e4a
Explains that citools, codeowners, and gitutil are local copies of their dev/ counterparts, and why a replace directive is not used. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Tick the box to add this pull request to the merge queue (same as
|
|
/test |
💔 Build Failed
Failed CI StepsHistory
cc @mrodm |
|
CI failure related to qualys_vmdr package is unrelated to this change. |
Proposed commit message
Extract all mage backport targets from the root
magefile.gointo a standalone CLI binary atcmd/backport/with its owngo.modsub-module.WHAT:
github.com/elastic/integrations/cmd/backportwith a self-contained CLI binary (cmd/backport/main.go) exposing all former mage backport targets as subcommands:validate-inventory,validate-branch-name,add-entry,check-active,detect-packages,check-owners,render-checklist,parse-checklist,update-checklist-status,sync-changelog,post-comment,apply,check-changelog-versionsdev/intocmd/backport/(backports/,citools/,codeowners/,gitutil/). Dead code removed from all copied packages.cmd/backport/.go-versionpins the tool's Go version independently from the root.go-versionso the tool always builds with a modern toolchain even when synced onto older backport branches.magefile_daily_jobs.gosplits main-branch-only mage targets (ReportFailedTests,RequiresUpdate) that importgo-gh/v2from the rest ofmagefile.go;backport_branch.shremoves this file when creating backport branches sogo mod tidyworks with older Go toolchains.cmd/backport/magefile.goaddsBuild,Install,Test,Format,Check,Tidy,Cleantargets for the sub-module.backport <subcommand>instead ofmage <Target>.common.sh: newwith_backport()function builds the binary fromcmd/backport/.go-version;BACKPORT_BINexported for reuse across steps.check_backport_tool.sh: new Buildkite step runsmage check+check_git_difffor the sub-module.non_package_patterns.txt: added^cmd/backport/,^magefile_daily_jobs.go,^dev/packagenames/so changes to tooling files do not trigger full package test runs.apply: after cherry-picking onto a backport branch that only has a subset of packages, files outside the target package are now reset to HEAD (usinggit checkout HEADwith agit rm --forcefallback for modify/delete conflicts), preventing spuriousstatus: conflictresults.WHY:
Using
mageas the entry-point for backport automation required contributors and CI agents to install mage and always run with the root module's Go version. Backport branches frequently carry older Go toolchains (1.19–1.21) that are incompatible with newer dependencies (go-gh/v2,dev/testsreporter, etc.) pulled from main. A standalone binary resolves this: it has its own pinned Go version, its owngo.mod, and is copied verbatim onto backport branches bybackport_branch.sh, so every branch runs the same tool regardless of its own Go version.Author's Checklist
backport <subcommand>equivalentsgo build -C cmd/backport ./...andgo test -C cmd/backport ./...passgo build ./...andgo build ./dev/...still pass (root module unchanged)backport_branch.shtested with dry-run mode on a real backport branch https://buildkite.com/elastic/integrations-backport/builds/322mage checkpasses insidecmd/backport/(format, tidy, test all green)How to test this PR locally
Related issues