Problem
When creating a backport branch, the script removes all packages except the target package and any packages it declares under requires.input / requires.content in its manifest.yml (handled by get_required_package_names in backport_branch_lib.sh).
However, packages can contain .link files — plain-text files with a .link extension managed by elastic-package. Each .link file contains a path (relative to the link file itself) pointing to a source file whose content it mirrors, plus a SHA-256 checksum. That relative path can traverse ../ boundaries and reference a file that lives inside a different package.
When a linked file's source package is not the target package and is not listed under requires.*, remove_other_packages will delete it, leaving the .link file pointing at a non-existent file and breaking the backport branch.
This was raised during review of elastic/package-spec#1209.
Expected behaviour
backport_branch.sh should detect all *.link files inside the target package, resolve their source paths, identify which package each source file belongs to (by finding the nearest manifest.yml ancestor), and add those packages to packages_to_keep — the same list that already preserves requires.* dependencies.
.github/CODEOWNERS entries for those extra packages must also be retained, which is already handled generically by remove_other_packages for packages in packages_to_keep, so no extra logic is needed there once the package list is correct.
Implementation hints
backport_branch_lib.sh already has the pattern to follow in get_required_package_names. A new function — e.g. get_linked_source_package_names — should:
- Walk all
*.link files under the given package path (find "$package_path" -name "*.link").
- Read the first whitespace-delimited field from each file (the relative path to the source).
- Resolve the absolute path:
dirname(<link_file>)/<relative_path>.
- Walk up from that resolved path to find the nearest directory containing a
manifest.yml — that directory is the source package root.
- If the source package root differs from the target package root, emit its path so the caller can add it to
packages_to_keep.
For reference, elastic-package implements the equivalent logic in Go at internal/files/linkedfiles.go — specifically listLinkedFiles + newLinkedFile (which populates IncludedPackageName).
Files to change
.buildkite/scripts/backport_branch_lib.sh — add get_linked_source_package_names
.buildkite/scripts/backport_branch.sh — call it alongside get_required_package_names when building packages_to_keep
Problem
When creating a backport branch, the script removes all packages except the target package and any packages it declares under
requires.input/requires.contentin itsmanifest.yml(handled byget_required_package_namesinbackport_branch_lib.sh).However, packages can contain
.linkfiles — plain-text files with a.linkextension managed byelastic-package. Each.linkfile contains a path (relative to the link file itself) pointing to a source file whose content it mirrors, plus a SHA-256 checksum. That relative path can traverse../boundaries and reference a file that lives inside a different package.When a linked file's source package is not the target package and is not listed under
requires.*,remove_other_packageswill delete it, leaving the.linkfile pointing at a non-existent file and breaking the backport branch.This was raised during review of elastic/package-spec#1209.
Expected behaviour
backport_branch.shshould detect all*.linkfiles inside the target package, resolve their source paths, identify which package each source file belongs to (by finding the nearestmanifest.ymlancestor), and add those packages topackages_to_keep— the same list that already preservesrequires.*dependencies..github/CODEOWNERSentries for those extra packages must also be retained, which is already handled generically byremove_other_packagesfor packages inpackages_to_keep, so no extra logic is needed there once the package list is correct.Implementation hints
backport_branch_lib.shalready has the pattern to follow inget_required_package_names. A new function — e.g.get_linked_source_package_names— should:*.linkfiles under the given package path (find "$package_path" -name "*.link").dirname(<link_file>)/<relative_path>.manifest.yml— that directory is the source package root.packages_to_keep.For reference,
elastic-packageimplements the equivalent logic in Go atinternal/files/linkedfiles.go— specificallylistLinkedFiles+newLinkedFile(which populatesIncludedPackageName).Files to change
.buildkite/scripts/backport_branch_lib.sh— addget_linked_source_package_names.buildkite/scripts/backport_branch.sh— call it alongsideget_required_package_nameswhen buildingpackages_to_keep