Fix nine defects in the push/sync path found in review

The worst was fatal: push passed --skip-prod-check to upload-prebuilt, which
forwards every argument to sign, promote and update as well, and sign rejects
unknown options. Every non-dry-run push and deploy would have uploaded and
verified its artifacts and then failed before signing. upload-prebuilt now
routes publishing flags to sync alone.

The partial-tree guard was weaker than it looked:

  - it counted archive files locally against package names in the remote
    database, and this tree keeps two versions per package, so a checkout with
    a spare version of half the repository could pass while still hiding
    hundreds of packages. It now compares package-name sets and lists what
    would be hidden.
  - it treated any unreadable remote as an empty one, so an auth failure or a
    corrupt database disabled it. Only rclone's "directory not found" now
    counts as a fresh mirror; every other failure aborts.

Also:

  - sync had no set -e, so a failed package upload fell through to publishing
    the database, advertising packages that were never uploaded. Each transfer
    is now checked before the next step.
  - --package with no names silently meant "every package", which under --yes
    could publish everything from one unset variable in a script.
  - push now refuses to run when the host has packages staged from an earlier
    failure, since publishing would sign and promote those too.
  - epoch versions contain a colon, which rsync reads as host:path, so no
    package with an epoch could be transferred. Sources are ./-prefixed.
  - remote paths are quoted for the remote shell.
  - sync spun forever on a missing option value.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-12 03:39:55 -07:00
co-authored by Claude Opus 5
parent c5f5f1c12c
commit fd9c078bf2
5 changed files with 192 additions and 33 deletions
+8 -1
View File
@@ -13,6 +13,7 @@ source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
PACKAGES=()
PACKAGE_FLAG_GIVEN=false
HOST=""
REMOTE_ROOT=""
DRY_RUN=false
@@ -38,8 +39,9 @@ while [[ $# -gt 0 ]]; do
;;
--package)
shift
PACKAGE_FLAG_GIVEN=true
while [[ $# -gt 0 && ! "$1" =~ ^-- ]]; do
PACKAGES+=("$1")
[[ -n "$1" ]] && PACKAGES+=("$1")
shift
done
;;
@@ -86,6 +88,11 @@ while [[ $# -gt 0 ]]; do
esac
done
if [[ "$PACKAGE_FLAG_GIVEN" == true && ${#PACKAGES[@]} -eq 0 ]]; then
print_error "--package requires at least one package name"
exit 1
fi
echo ""
print_info "This will:"
echo " 1. Build packages locally"