isle.pizza/scripts/deploy.sh

144 lines
5.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# ── Configuration ──────────────────────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
WRANGLER="$PROJECT_DIR/server/node_modules/.bin/wrangler"
R2_BUCKET="${R2_BUCKET:-isle}"
# ── Parse arguments ────────────────────────────────────────────
ENV=""
SKIP_BUILD=false
INCLUDE_ASSETS=false
for arg in "$@"; do
case "$arg" in
--skip-build) SKIP_BUILD=true ;;
--include-assets) INCLUDE_ASSETS=true ;;
dev|production) ENV="$arg" ;;
*) echo "Unknown argument: $arg"; echo "Usage: $0 [dev|production] [--skip-build] [--include-assets]"; exit 1 ;;
esac
done
ENV="${ENV:-dev}"
# ── Environment configuration ──────────────────────────────────
case "$ENV" in
dev)
R2_PREFIX="dev/"
DOMAIN="dev.isle.pizza"
;;
production)
R2_PREFIX=""
DOMAIN="isle.pizza"
;;
esac
# ── Check prerequisites ───────────────────────────────────────
if [ ! -f "$WRANGLER" ]; then
echo "Error: wrangler not found at $WRANGLER"
echo "Run 'npm install' in $PROJECT_DIR/server/ first."
exit 1
fi
# ── Compute versions ──────────────────────────────────────────
cd "$PROJECT_DIR"
FRONTEND_VERSION=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
WASM_VERSION=""
if [ -f "$PROJECT_DIR/isle.js" ]; then
WASM_VERSION=$(grep -oP 'wasmVersion"\]\s*=\s*"\K[^"]+' "$PROJECT_DIR/isle.js" 2>/dev/null || echo "")
fi
echo "Environment: $ENV"
echo "R2 prefix: ${R2_PREFIX:-(root)}"
echo "Domain: $DOMAIN"
echo "Frontend version: $FRONTEND_VERSION"
echo "WASM version: ${WASM_VERSION:-not found}"
echo ""
# ── Production safety gate ─────────────────────────────────────
if [ "$ENV" = "production" ]; then
echo "WARNING: You are about to deploy to PRODUCTION ($DOMAIN)"
read -r -p "Continue? [y/N] " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi
echo ""
fi
# ── Build ──────────────────────────────────────────────────────
if [ "$SKIP_BUILD" = false ]; then
echo "Building frontend..."
cd "$PROJECT_DIR"
RELAY_URL="wss://relay.isle.pizza" API_URL="https://api.isle.pizza" BUILD_VERSION="$FRONTEND_VERSION" npm run build
echo ""
fi
# ── Verify dist ────────────────────────────────────────────────
if [ ! -d "$PROJECT_DIR/dist" ] || [ ! -f "$PROJECT_DIR/dist/index.html" ]; then
echo "Error: dist/ directory not found or empty. Run without --skip-build first."
exit 1
fi
# ── Content-type mapping ──────────────────────────────────────
get_content_type() {
case "${1##*.}" in
html) echo "text/html; charset=utf-8" ;;
js) echo "application/javascript; charset=utf-8" ;;
css) echo "text/css; charset=utf-8" ;;
json) echo "application/json; charset=utf-8" ;;
wasm) echo "application/wasm" ;;
webp) echo "image/webp" ;;
png) echo "image/png" ;;
svg) echo "image/svg+xml" ;;
gif) echo "image/gif" ;;
mp3) echo "audio/mpeg" ;;
pdf) echo "application/pdf" ;;
bin) echo "application/octet-stream" ;;
map) echo "application/json" ;;
*) echo "application/octet-stream" ;;
esac
}
# ── Upload dist/ to R2 ────────────────────────────────────────
echo "Uploading to R2 (bucket: $R2_BUCKET, prefix: ${R2_PREFIX:-(root)})..."
cd "$PROJECT_DIR/dist"
find . -type f | sort | while read -r file; do
file="${file#./}"
# Skip asset directories unless --include-assets
if [ "$INCLUDE_ASSETS" = false ]; then
case "$file" in
images/*|audio/*|pdf/*|workbox/*) continue ;;
esac
fi
key="${R2_PREFIX}${file}"
ct=$(get_content_type "$file")
echo " $key ($ct)"
"$WRANGLER" r2 object put "$R2_BUCKET/$key" --file "$PROJECT_DIR/dist/$file" --content-type "$ct" --remote 2>/dev/null
done
echo ""
# ── Upload source map to symbols/ ─────────────────────────────
if [ -n "$WASM_VERSION" ] && [ -f "$PROJECT_DIR/isle.wasm.map" ]; then
SYMBOLS_KEY="symbols/${WASM_VERSION}/isle.wasm.map"
echo "Uploading source map: $SYMBOLS_KEY"
"$WRANGLER" r2 object put "$R2_BUCKET/$SYMBOLS_KEY" --file "$PROJECT_DIR/isle.wasm.map" --content-type "application/json" --remote 2>/dev/null
else
echo "Warning: Skipping source map upload (wasm version: '${WASM_VERSION:-}', map file exists: $([ -f "$PROJECT_DIR/isle.wasm.map" ] && echo yes || echo no))"
fi
echo ""
echo "Deploy complete!"
echo " Environment: $ENV ($DOMAIN)"
echo " Frontend version: $FRONTEND_VERSION"
echo " WASM version: ${WASM_VERSION:-unknown}"
echo ""
echo "Remember to purge the Cloudflare cache for $DOMAIN."