← back to Coming Soon Template

scripts/deploy_workers.sh

63 lines

#!/usr/bin/env bash
# Deploy the project-cap-casualty domains as static-asset Cloudflare Workers.
# Pages is capped at 20 projects/account; Workers are not. These two domains
# (bhbutler.com, boulevardbutler.com) get their coming-soon page served by a
# tiny assets-only Worker instead of a Pages project.
#
#   ./scripts/deploy_workers.sh
#
# Two steps per domain:
#   1. wrangler deploy  — uploads the assets-only Worker. On a brand-new
#      Worker with no route yet, wrangler exits non-zero ("register a
#      workers.dev subdomain or specify routes") AFTER the upload succeeds;
#      that exit is tolerated because step 2 supplies the destination.
#   2. PUT /accounts/{acct}/workers/domains — binds the apex hostname to the
#      Worker (account-level API; needs only Workers Scripts:Edit, not the
#      zone-level Workers Routes scope). This also creates the zone DNS
#      record. Idempotent: re-binding an existing domain returns success.
set -uo pipefail
cd "$(dirname "$0")/.."

[ -f .env ] || { echo "✗ missing .env"; exit 1; }
set -a; source .env; set +a
export CLOUDFLARE_API_TOKEN="${CLOUDFLARE_PAGES_TOKEN:?CLOUDFLARE_PAGES_TOKEN not set}"
ACCT="${CLOUDFLARE_ACCOUNT_ID:?CLOUDFLARE_ACCOUNT_ID not set}"

DOMAINS=(bhbutler.com boulevardbutler.com)

for domain in "${DOMAINS[@]}"; do
  project="${domain%.com}"
  [ -f "out/$domain/index.html" ] || { echo "✗ no artifact: out/$domain"; exit 1; }

  workdir="workers/$project"
  mkdir -p "$workdir"
  cat > "$workdir/wrangler.toml" <<EOF
name = "$project"
account_id = "$ACCT"
compatibility_date = "2026-05-18"

[assets]
directory = "../../out/$domain"
EOF

  echo "→ [1/2] uploading Worker: $project"
  ( cd "$workdir" && npx --yes wrangler deploy ) || \
    echo "   (wrangler exited non-zero — expected on a routeless Worker; upload still succeeded)"

  zid=$(node -e "const z=require('./data/zone-setup.json').find(x=>x.domain==='$domain');process.stdout.write(z?z.zone_id:'')")
  [ -n "$zid" ] || { echo "   ✗ no zone_id for $domain in data/zone-setup.json"; continue; }

  echo "→ [2/2] binding $domain -> Worker '$project'"
  resp=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCT/workers/domains" \
    -H "Authorization: Bearer $CLOUDFLARE_PAGES_TOKEN" -H "Content-Type: application/json" \
    --data "{\"zone_id\":\"$zid\",\"hostname\":\"$domain\",\"service\":\"$project\",\"environment\":\"production\"}")
  if echo "$resp" | grep -q '"success":true'; then
    echo "   ✓ $domain bound to $project"
  else
    echo "   ✗ bind failed: $resp"
  fi
  echo
done

echo "✓ worker deploys done"