← back to Coming Soon Template
deploy.sh
58 lines
#!/usr/bin/env bash
# Deploy a coming-soon page to Cloudflare Pages.
#
# ./deploy.sh abramsindex.com # deploy one domain
# ./deploy.sh all # deploy every domain under out/
#
# HARD RULE (debate-team verdict, 2026-05-18): only ever publish the
# per-domain artifact dir `out/<domain>/` — never the project root.
# Deploying the project root is what leaked .credentials.local /
# users.json on the prior laptop session. This script makes that
# mistake structurally impossible.
set -euo pipefail
cd "$(dirname "$0")"
[ -f .env ] || { echo "✗ missing .env (CLOUDFLARE_PAGES_TOKEN + CLOUDFLARE_ACCOUNT_ID)"; exit 1; }
set -a; source .env; set +a
# wrangler reads CLOUDFLARE_API_TOKEN; our master .env stores the
# Pages-scoped token separately so it never clobbers the DNS token.
export CLOUDFLARE_API_TOKEN="${CLOUDFLARE_PAGES_TOKEN:?CLOUDFLARE_PAGES_TOKEN not set}"
ensure_project() {
local project="$1"
# grep -wx so "abrams" doesn't match "abramsindex"
if ! npx --yes wrangler pages project list 2>/dev/null | awk -F'│' '{print $2}' | tr -d ' ' | grep -qx "$project"; then
echo " + creating Pages project: $project"
npx --yes wrangler pages project create "$project" --production-branch=main >/dev/null
fi
}
deploy_one() {
local dir="$1"
[ -d "out/$dir" ] || { echo "✗ no artifact: out/$dir"; return 1; }
local project="${dir%.com}" # abramsindex.com -> abramsindex
echo "→ deploying $dir (project: $project)"
ensure_project "$project"
npx --yes wrangler pages deploy "out/$dir" \
--project-name="$project" --branch=main --commit-dirty=true
}
target="${1:?usage: deploy.sh <domain-dir under out/> | all}"
if [ "$target" = "all" ]; then
fail=0
for d in out/*/; do
d="${d#out/}"; d="${d%/}"
[ -f "out/$d/index.html" ] || continue
if ! deploy_one "$d"; then
echo " ✗ FAILED: $d"
fail=$((fail+1))
fi
# Throttle: 21 back-to-back project-creates trip CF rate limit (code 10429).
sleep 8
done
echo
if [ "$fail" -eq 0 ]; then echo "✓ all deploys succeeded"; else echo "⚠ $fail deploy(s) failed"; fi
else
deploy_one "$target"
fi