#!/usr/bin/env bash # TOASTSIM — deploy to partly.party/toastsim (games VPS, forum-nginx pattern). # ./scripts/deploy.sh # Build with subpath base → rsync to VPS staging → docker cp into web root → curl verify. set -euo pipefail VPS="humanjing@100.71.119.27" CONTAINER="forum-nginx" REMOTE_WEB_ROOT="/usr/share/nginx/html/toastsim" STAGING="/tmp/toastsim_deploy" REPO="$(cd "$(dirname "$0")/.." && pwd)" echo "[1/4] Building (base=/toastsim/)..." cd "$REPO" ./node_modules/.bin/tsc --noEmit ./node_modules/.bin/vite build --base=/toastsim/ echo "[2/4] Rsync dist → $VPS:$STAGING ..." ssh "$VPS" "rm -rf '$STAGING' && mkdir -p '$STAGING'" rsync -az dist/ "$VPS:$STAGING/" echo "[3/4] Merge into $CONTAINER:$REMOTE_WEB_ROOT ..." # ADDITIVE on purpose — no rm, no gap. The old flow (rm -rf, then docker cp) # had a downtime window, and worse: any browser/CDN holding yesterday's # index.html pointed at hashed bundles the rm had just deleted → the classic # "module script served as text/html" outage. Hashed assets never collide, so # merging keeps every old build's bundles alive for stale HTML while the new # index.html takes over for everyone else. Disk cost is a few MB per deploy; # prune assets/ older than ~30 days by hand if it ever matters. ssh "$VPS" "docker exec '$CONTAINER' mkdir -p '$REMOTE_WEB_ROOT' \ && docker cp '$STAGING/.' '$CONTAINER:$REMOTE_WEB_ROOT/'" echo "[4/4] Verify the page AND the bundle it references..." page=$(curl -s "https://partly.party/toastsim/?cb=$(date +%s)") src=$(printf '%s' "$page" | grep -oE 'src="[^"]*\.js"' | sed 's/src="//;s/"//' | head -1) [ -n "$src" ] || { echo "NOT DEPLOYED (no script tag in live index.html)"; exit 1; } ctype=$(curl -so /dev/null -w '%{content_type}' "https://partly.party$src") echo "https://partly.party/toastsim/ → script $src → $ctype" case "$ctype" in application/javascript*|text/javascript*) echo "done." ;; *) echo "NOT DEPLOYED (bundle served as $ctype — stale index or missing asset)"; exit 1 ;; esac