Deploy script: rsync the build across instead of re-sending it whole

Transferring with tar meant pushing the full 16 MB on every deploy, most of it
unchanged source maps, over the link to Accra. rsync sends only what differs —
on a no-op deploy that is now zero bytes.

--delete matters as much as the speed. A staging directory without it quietly
accumulates every asset ever built, which is precisely how the stale chunks kept
reappearing: the existing staging area at /home/sema_gopa/pwa/dist holds 226
files against a build of 47, so copying from it restored everything that had
been pruned. The trailing slash on the source copies contents including
dotfiles, so .htaccess comes along; dist/* would skip it. tar remains as a
fallback where rsync is not installed, and the AppleDouble sweep stays for both.

The final hop still has to be docker cp. rsync is not installed in the
container, the live src directory is owned by root so sema_gopa cannot create or
delete entries in it, and there is no passwordless sudo — docker exec is the
only route that has root where the bind mount lands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ekke 2026-10-21 16:29:41 +02:00
parent 9e62344471
commit e3e30ad709

View File

@ -90,13 +90,30 @@ if [ "$DRY_RUN" -eq 1 ]; then
fi
# ------------------------------------------------------------- 3. transfer
# rsync, not tar: most of a build is unchanged source maps, and over the link to
# Accra re-sending 16 MB every time is wasteful. --delete keeps the staging
# directory honest — without it a staging area quietly accumulates every asset
# ever built, which is exactly how stale chunks kept coming back. A trailing
# slash on the source copies the contents, dotfiles included, so .htaccess comes
# along; `dist/*` would skip it.
say "Transferring to $SSH_HOST:~/$STAGING"
if command -v rsync >/dev/null 2>&1; then
rsync -a --delete --no-perms --no-owner --no-group --info=stats2 \
-e "ssh -o BatchMode=yes" \
"$DIST"/ "$SSH_HOST:~/$STAGING/" 2>/dev/null \
| grep -E "Number of .*(transferred|deleted)|Total transferred" \
| sed 's/^/ /' || die "rsync failed"
else
item "rsync not found locally — falling back to tar"
COPYFILE_DISABLE=1 tar -C "$DIST" -cf - . 2>/dev/null \
| ssh -o BatchMode=yes "$SSH_HOST" "
rm -rf ~/$STAGING && mkdir -p ~/$STAGING &&
tar -C ~/$STAGING -xf - 2>/dev/null
find ~/$STAGING -name '._*' -delete
" || die "the transfer failed"
fi
# macOS tar writes AppleDouble companions when extended attributes are present;
# .htaccess arrived as ._.htaccess once. rsync does not, but sweep either way.
ssh -o BatchMode=yes "$SSH_HOST" "find ~/$STAGING -name '._*' -delete" || true
REMOTE_FILES=$(ssh -o BatchMode=yes "$SSH_HOST" "find ~/$STAGING -type f | wc -l" | tr -d ' ')
item "staged $REMOTE_FILES files"