#!/usr/bin/env bash # Ship dist/ to cloud-2. # # Run from a machine on the tailnet (cloud-2's :22 is tailnet-only, which is # also why a GitHub-hosted runner cannot do this). # # bash deploy/deploy.sh # # Keeps the last 10 releases as hard-linked snapshots, so a rollback is a # directory rename rather than a rebuild. set -euo pipefail HOST="${PIG_DEMO_HOST:-ubuntu@100.92.185.76}" ROOT="/var/www/demo.primeintellectgrowth.com" SNAPS="${ROOT}-rollbacks" URL="https://demo.primeintellectgrowth.com" cd "$(dirname "$0")/.." [ -d dist ] || { echo "no dist/ — run 'pnpm build' first"; exit 1; } [ -f dist/index.html ] || { echo "dist/index.html missing"; exit 1; } # The prerender pass is what makes shared links preview correctly. A dist # without it builds and serves fine, which is exactly why it needs asserting. [ -f dist/404.html ] || { echo "dist/404.html missing — did prerender run?"; exit 1; } echo "==> preflight on ${HOST}" ssh "$HOST" "set -e free=\$(df --output=avail -BG / | tail -1 | tr -dc 0-9) [ \"\$free\" -ge 3 ] || { echo \"only \${free}G free on /\"; exit 1; } mkdir -p '$SNAPS' if [ -d '$ROOT' ] && [ -n \"\$(ls -A '$ROOT' 2>/dev/null)\" ]; then # Double quotes, not single. Inside single quotes the remote shell never # expands the command substitution, so every deploy wrote into a single # directory named after the un-expanded literal, and the SECOND deploy died # on 'File exists'. It looked like it worked for exactly as long as there # had only ever been one deploy. Note this comment is inside a # double-quoted ssh payload: anything it names gets expanded too. cp -al '$ROOT' \"$SNAPS/\$(date +%Y%m%d-%H%M%S)\" fi ls -1dt '$SNAPS'/*/ 2>/dev/null | tail -n +11 | xargs -r rm -rf" echo "==> rsync" rsync -az --delete --checksum dist/ "$HOST:$ROOT/" echo "==> smoke test against the public hostname" # Against the real name from THIS machine, never --resolve from cloud-2: a # missing `bind 10.0.0.2` in the Caddy block serves an empty 200 to the # internet while a local --resolve check still passes. code=$(curl -sS -o /tmp/pigdemo-smoke.html -w '%{http_code}' --max-time 30 "$URL/") size=$(wc -c < /tmp/pigdemo-smoke.html) echo " / -> $code, ${size}b" [ "$code" = "200" ] || { echo "FAILED: / returned $code"; exit 1; } [ "$size" -gt 1000 ] || { echo "FAILED: / is ${size}b — almost certainly the empty-200 bind bug"; exit 1; } grep -q '