From ca90a19d734214918c54452f7955e3ec9d1c2652 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 12 Aug 2026 04:24:38 -0700 Subject: [PATCH] Push every output of a selected pkgbase --package meant a pkgbase to bin/build and a literal package name to bin/push-build, so deploy --package nvidia-580xx-utils built three packages and published one, leaving nvidia-580xx-dkms and opencl-nvidia-580xx behind with no indication anything was missing. Hit while deploying exactly that package. Selection now matches on the pkgbase recorded in .PKGINFO as well as on the package name, so a pkgbase ships all of its outputs and an individual name still selects just that one. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 8 +++++--- bin/push-build | 26 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d63b0eb..f6433b6 100644 --- a/README.md +++ b/README.md @@ -228,9 +228,11 @@ setting is named for the repository rather than for building, which happens wherever you like. The same setting tells `bin/omarchy-pkgs release` which host to poke after a release push. -Split packages are selected by their own names, not their pkgbase — pushing -`nvidia-580xx-utils` does not carry `nvidia-580xx-dkms` along. Omit `--package` to -push everything built. +`--package` means the same thing as it does to `build`: a pkgbase, whose every +output ships together. Pushing `nvidia-580xx-utils` carries `nvidia-580xx-dkms` +and `opencl-nvidia-580xx` with it, because that is what the build produced. An +output's own name still selects just that one, for publishing a single package +on purpose. Omit `--package` to push everything built. Publishing signs and promotes everything staged on the host, not just what this push uploaded, so `push` stops when it finds packages already staged there — diff --git a/bin/push-build b/bin/push-build index 21523e8..bbb7d67 100755 --- a/bin/push-build +++ b/bin/push-build @@ -143,29 +143,41 @@ if [[ -z "$PACKAGES" && "$ASSUME_YES" == true ]] && ! on_repo_host; then exit 1 fi +# --package means the same thing here as it does to bin/build: a pkgbase, whose +# every output ships together. Selecting only the artifact whose filename matched +# would publish one third of a split package like nvidia-580xx-utils and silently +# leave nvidia-580xx-dkms and opencl-nvidia-580xx behind. An output's own name +# still matches, for pushing just one of them on purpose. +# +# pkgbase comes from .PKGINFO rather than the PKGBUILD: it is what makepkg +# actually recorded, and it needs no guessing about which directory built what. +pkgbase_of() { + bsdtar -xOf "$1" .PKGINFO 2>/dev/null | + awk -F ' = ' '$1 == "pkgbase" { print $2; exit }' +} + FILES=() if [[ -z "$PACKAGES" ]]; then FILES=("${ALL_FILES[@]}") else + declare -A MATCHED=() for file in "${ALL_FILES[@]}"; do # name-version-release-arch.pkg.tar.zst -> name pkgname="${file%-*-*-*.pkg.tar.*}" + pkgbase=$(pkgbase_of "$BUILD_OUTPUT_DIR/$file") for wanted in $PACKAGES; do - if [[ "$pkgname" == "$wanted" ]]; then + if [[ "$pkgname" == "$wanted" || "$pkgbase" == "$wanted" ]]; then FILES+=("$file") + MATCHED["$wanted"]=1 break fi done done for wanted in $PACKAGES; do - found=false - for file in "${FILES[@]}"; do - [[ "${file%-*-*-*.pkg.tar.*}" == "$wanted" ]] && found=true && break - done - if [[ "$found" != true ]]; then + if [[ -z "${MATCHED[$wanted]:-}" ]]; then print_error "No built artifact for '$wanted' in $BUILD_OUTPUT_DIR" - print_warning "Split packages are named after their outputs, not their pkgbase" + print_warning "Name a package or the pkgbase it was built from" exit 1 fi done