#!/usr/bin/env bash # Sync the built static site to the live root in an order that avoids deploy-race # blank screens. rsync isn't atomic, so a naïve `rsync --delete` can briefly serve # a NEW index.html that points at chunks not synced yet (→ failed load), or delete # old chunks an in-flight client still needs. Instead: # 1. new hashed chunks first, and DON'T prune old ones (grace window) # 2. other static assets (version.json, env.js, icons…), pruning removed files # 3. the shell HTML — only once its chunks already exist # 4. the service worker last — a returning client adopts it only after the rest # Old immutable chunks are pruned after a grace window to bound disk growth. set -euo pipefail src="$1"; site="$2" rsync -a "$src/_app/immutable/" "$site/_app/immutable/" rsync -a --delete \ --exclude='_app/immutable/***' --exclude='index.html' --exclude='service-worker.js' \ "$src/" "$site/" rsync -a "$src/index.html" "$site/index.html" rsync -a "$src/service-worker.js" "$site/service-worker.js" find "$site/_app/immutable" -type f -mtime +14 -delete 2>/dev/null || true # Warm the Cloudflare edge cache: fetch every immutable asset through the public # domain so the FIRST real visitor after a deploy gets cache HITs instead of slow # cold fetches from the (residential) origin — the post-deploy blank/slow-load cause. echo " warming edge cache…" base="https://upbeatbytes.com" { # every immutable chunk/asset (a superset of what index.html boots from) find "$site/_app/immutable" -type f \( -name '*.js' -o -name '*.css' \) -printf '/_app/immutable/%P\n' # shell + key routes + SW + version + static assets (primes CF↔origin even where # no-cache; caches the cacheable ones) printf '%s\n' / /play /account /admin /service-worker.js /_app/version.json \ /manifest.webmanifest /words-5.json /words-6.json /logo.svg /favicon.svg \ /icon-192.png /icon-512.png /fonts/inter-latin-wght-normal.woff2 } | xargs -P 8 -I{} curl -fsS -o /dev/null --max-time 20 "$base{}" 2>/dev/null || true