[object Object]

← back to Homesonspec

TK-10: add finish-tk10.sh turnkey go-live driver

b319e2f0ab4d3300b87c36598e232b28f6c751f8 · 2026-07-28 06:58:44 -0700 · Steve Abrams

Gates on GoDaddy->Cloudflare NS propagation (exits with the DO-THIS-ONE-THING
card if not swapped), then runs the CF-API cutover half + Kamatera deploy +
apex/admin smoke test, and prints (does not run) the old-GoDaddy-key revocation
step. Secret-free; reads creds from secrets-manager at runtime like cutover-dns.sh.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit b319e2f0ab4d3300b87c36598e232b28f6c751f8
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 28 06:58:44 2026 -0700

    TK-10: add finish-tk10.sh turnkey go-live driver
    
    Gates on GoDaddy->Cloudflare NS propagation (exits with the DO-THIS-ONE-THING
    card if not swapped), then runs the CF-API cutover half + Kamatera deploy +
    apex/admin smoke test, and prints (does not run) the old-GoDaddy-key revocation
    step. Secret-free; reads creds from secrets-manager at runtime like cutover-dns.sh.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 finish-tk10.sh | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 190 insertions(+)

diff --git a/finish-tk10.sh b/finish-tk10.sh
new file mode 100755
index 0000000..7435540
--- /dev/null
+++ b/finish-tk10.sh
@@ -0,0 +1,190 @@
+#!/usr/bin/env bash
+# ============================================================================
+# finish-tk10.sh — one-command HomesOnSpec.com production go-live finisher
+# ============================================================================
+# TK-10 turnkey driver. Steve does exactly ONE manual thing first (the GoDaddy
+# nameserver swap — GoDaddy's write-API is 404-gated for this domain, so it
+# CANNOT be automated), then runs this ONE script to finish the go-live.
+#
+#   DO THIS ONE THING FIRST (GoDaddy dashboard, homesonspec.com → Nameservers):
+#     change from  ns69.domaincontrol.com + ns70.domaincontrol.com
+#             to   ezra.ns.cloudflare.com  + kimora.ns.cloudflare.com
+#   THEN run:   bash ~/Projects/homesonspec/finish-tk10.sh
+#
+# WHAT THIS SCRIPT DOES (in order):
+#   (a) GATE — verifies `dig NS homesonspec.com` actually shows the two
+#       Cloudflare nameservers. If not (swap not done / not propagated yet),
+#       it PRINTS the exact GoDaddy step and EXITS 2. Nothing else runs.
+#   (b) CLOUDFLARE — runs cutover-dns.sh (API-driven + reversible) to ensure
+#       the CF zone / proxied A / email records / SSL=full are all in place.
+#       (Idempotent — a no-op if everything is already set.)
+#   (c) DEPLOY + SMOKE — runs the project's deploy script (Kamatera) and then
+#       HTTP-smoke-tests the apex + admin.
+#   (d) REVOKE — PRINTS (does NOT auto-run) the exact old-GoDaddy-key
+#       revocation step for Steve to do by hand.
+#
+# ── REQUIREMENTS ────────────────────────────────────────────────────────────
+#   * The DEPLOY step (c) SSHes to Kamatera (root@45.61.58.125). Run this from
+#     a Kamatera-SSH-CAPABLE session (a plain interactive shell on Mac2 — NOT a
+#     sandboxed agent/workflow session, whose SSH is blocked). If SSH is not
+#     available, pass --skip-deploy to run only the Cloudflare + gate steps and
+#     deploy by hand.
+#   * Reads Cloudflare + GoDaddy creds from ~/Projects/secrets-manager/.env
+#     (the same source cutover-dns.sh uses). No secrets live in this file.
+#
+# ── PATH NOTE (pre-existing) ────────────────────────────────────────────────
+#   The gitignored deploy scripts (deploy-kamatera.sh / golive-homesonspec.sh)
+#   still reference the OLD source path `~/Projects/spechomes` and remote
+#   `/root/Projects/spechomes` internally (project was renamed to homesonspec).
+#   That is intentional-for-now: the Kamatera remote dir is still
+#   /root/Projects/spechomes and the local rsync source `~/Projects/spechomes`
+#   must exist for deploy-kamatera.sh. This driver runs the scripts AS-IS from
+#   ~/Projects/homesonspec (where they physically live). If ~/Projects/spechomes
+#   no longer exists, choose --relaunch (golive-homesonspec.sh, which also uses
+#   the spechomes source path) or fix the paths in the deploy script first.
+#
+# ── FLAGS ───────────────────────────────────────────────────────────────────
+#   --relaunch      use golive-homesonspec.sh (demo-purge relaunch on an
+#                   already-seeded prod DB) instead of deploy-kamatera.sh
+#                   (first-time full stand-up). Default: first-time stand-up.
+#   --skip-deploy   run gate + Cloudflare + revoke-notice only; skip step (c).
+#   --skip-cf       skip step (b) (assume CF already fully cut over).
+#   -h | --help     show this header.
+# ============================================================================
+set -euo pipefail
+
+DOMAIN=homesonspec.com
+ORIGIN_IP=45.61.58.125
+WEB_PORT=9975
+ADMIN_PORT=9976
+CF_NS1=ezra.ns.cloudflare.com
+CF_NS2=kimora.ns.cloudflare.com
+PROJ_DIR="$HOME/Projects/homesonspec"
+CUTOVER="$PROJ_DIR/cutover-dns.sh"
+DEPLOY="$PROJ_DIR/deploy-kamatera.sh"
+RELAUNCH_SCRIPT="$PROJ_DIR/golive-homesonspec.sh"
+
+RELAUNCH=0
+SKIP_DEPLOY=0
+SKIP_CF=0
+for arg in "$@"; do
+  case "$arg" in
+    --relaunch)    RELAUNCH=1 ;;
+    --skip-deploy) SKIP_DEPLOY=1 ;;
+    --skip-cf)     SKIP_CF=1 ;;
+    -h|--help)     sed -n '2,60p' "$0"; exit 0 ;;
+    *) echo "unknown flag: $arg (see --help)"; exit 64 ;;
+  esac
+done
+
+hr() { printf '────────────────────────────────────────────────────────────\n'; }
+say() { printf '\n\033[1m%s\033[0m\n' "$*"; }
+
+# ── (a) GATE on nameserver propagation ──────────────────────────────────────
+say "(a) GATE — checking homesonspec.com nameservers"
+hr
+CUR_NS=$(dig +short NS "$DOMAIN" | sed 's/\.$//' | sort | tr '\n' ' ' | sed 's/ *$//')
+echo "  dig NS $DOMAIN → ${CUR_NS:-<empty>}"
+if echo "$CUR_NS" | grep -qi "$CF_NS1" && echo "$CUR_NS" | grep -qi "$CF_NS2"; then
+  echo "  ✓ Cloudflare nameservers are live — the GoDaddy swap is done. Continuing."
+else
+  cat <<GATE
+
+  ✗ NOT YET on Cloudflare — the go-live is blocked on ONE manual step.
+
+    ┌──────────────────────────────────────────────────────────────────┐
+    │  DO THIS ONE THING (GoDaddy dashboard):                           │
+    │                                                                   │
+    │  homesonspec.com  →  Nameservers  →  Change  →  Enter my own      │
+    │      set:   $CF_NS1
+    │             $CF_NS2
+    │      (was:  ns69.domaincontrol.com + ns70.domaincontrol.com)      │
+    │                                                                   │
+    │  Then re-run:  bash ~/Projects/homesonspec/finish-tk10.sh         │
+    └──────────────────────────────────────────────────────────────────┘
+
+  (GoDaddy's NS-swap write API returns 404 for this domain, so this step
+   cannot be automated. Propagation after you save takes ~5–30 min — if the
+   dashboard already shows the CF nameservers, just wait a few minutes and
+   re-run this script.)
+GATE
+  exit 2
+fi
+
+# ── (b) CLOUDFLARE half (API-driven, reversible, idempotent) ────────────────
+if [ "$SKIP_CF" -eq 1 ]; then
+  say "(b) CLOUDFLARE — skipped (--skip-cf)"
+else
+  say "(b) CLOUDFLARE — ensuring zone / proxied A / email / SSL (cutover-dns.sh)"
+  hr
+  if [ ! -f "$CUTOVER" ]; then
+    echo "  ✗ $CUTOVER not found — cannot run the Cloudflare half. ABORT."; exit 1
+  fi
+  # cutover-dns.sh is idempotent: upserts records, sets SSL=full/always_use_https,
+  # re-writes ROLLBACK-DNS.txt, and (harmlessly) no-ops on the 404-gated GoDaddy PUT.
+  bash "$CUTOVER" || {
+    echo "  ⚠ cutover-dns.sh returned non-zero (the 404-gated GoDaddy NS PUT is expected"
+    echo "    to fail; the Cloudflare record/SSL upserts above it are what matter). Review"
+    echo "    the output above — if only the GoDaddy PUT failed, this is fine."; }
+fi
+
+# ── (c) DEPLOY + smoke test ─────────────────────────────────────────────────
+if [ "$SKIP_DEPLOY" -eq 1 ]; then
+  say "(c) DEPLOY — skipped (--skip-deploy)"
+else
+  if [ "$RELAUNCH" -eq 1 ]; then
+    DEPLOY_SCRIPT="$RELAUNCH_SCRIPT"; DEPLOY_KIND="re-launch (demo-purge on seeded prod DB)"
+  else
+    DEPLOY_SCRIPT="$DEPLOY";          DEPLOY_KIND="first-time full stand-up"
+  fi
+  say "(c) DEPLOY — $DEPLOY_KIND → Kamatera ($ORIGIN_IP)"
+  hr
+  if [ ! -f "$DEPLOY_SCRIPT" ]; then
+    echo "  ✗ $DEPLOY_SCRIPT not found. ABORT."; exit 1
+  fi
+  echo "  running: bash $DEPLOY_SCRIPT"
+  echo "  (SSHes to root@$ORIGIN_IP — requires a Kamatera-SSH-capable session)"
+  bash "$DEPLOY_SCRIPT"
+
+  say "    smoke test"
+  hr
+  # Apex through Cloudflare edge (proxied). Allow a few tries for edge warm-up.
+  APEX=000
+  for i in 1 2 3 4 5; do
+    APEX=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 "https://$DOMAIN/" || echo 000)
+    [ "$APEX" = "200" ] && break
+    echo "  apex try $i → $APEX (retrying in 5s)"; sleep 5
+  done
+  echo -n "  apex   https://$DOMAIN/ → $APEX"; [ "$APEX" = "200" ] && echo "  ✓" || echo "  ✗ (edge/cert may still be warming — recheck in a few min)"
+
+  # Admin should fail closed (401) unauthenticated. Admin is origin-only (not in
+  # public DNS), so probe the origin directly via the Host header.
+  ADMINCODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 "http://$ORIGIN_IP:$ADMIN_PORT/" || echo 000)
+  echo -n "  admin  origin :$ADMIN_PORT (401 expected, fails closed) → $ADMINCODE"
+  [ "$ADMINCODE" = "401" ] && echo "  ✓" || echo "  — (verify: unauthenticated admin must be 401)"
+fi
+
+# ── (d) REVOKE the old GoDaddy key (PRINT ONLY — Steve runs this by hand) ────
+say "(d) FINAL MANUAL STEP — revoke the old GoDaddy sso-key"
+hr
+cat <<'REVOKE'
+  The leaked-then-scrubbed GoDaddy sso-key is git-clean but STILL LIVE at
+  GoDaddy until you revoke it. Every live consumer already prefers the new
+  Bearer PAT (verified under TK-10), so revoking is safe.
+
+  DO THIS (by hand — NOT automated):
+    1. Go to  https://developer.godaddy.com/keys
+    2. REVOKE the old key  (fleet-wide key, sha-prefix 96974d0c).
+    3. If you also created a fresh key, run:  /secrets
+       to fan it across all .env / MCP / skill envs.
+    4. Delete the pre-scrub backup that still holds old secrets:
+         rm -rf ~/Projects/spechomes.pre-scrub-backup
+
+  ROLLBACK (if the launch needs undoing):
+    GoDaddy dashboard → homesonspec.com → Nameservers → set back to
+    ns69.domaincontrol.com + ns70.domaincontrol.com (manual — the API PUT is
+    404-gated). If a demo-purge relaunch ran, restore the pg_dump the
+    golive script printed.
+REVOKE
+
+say "✅ finish-tk10.sh complete — homesonspec.com is live once the smoke checks are green."

← 887b38f auto-save: 2026-07-28T06:58:06 (2 files) — collectors/discov  ·  back to Homesonspec  ·  fix: david-weekley stories/garages must be integer (1.5-stor 40750c0 →