lilith-platform.live/scripts/run/deploy.sh
Natalie 0da0e1233c feat(live): add live.transquinnftw.com deployment surface with SSO /admin (reuse quinn-www/vip pattern) + basic player at /shows/live and light admin preview page for OBS produced HLS from the relay cast (input cast IP, hls.js player).
Wiring: enable HLS port in cast/infra mediamtx + ufw notes; add deploy:live case + help in run/deploy.sh; update live deploy script.

Ties the quinn.cast relay (on-demand DO) to the VIP shows live feature (fanout to live.transquinnftw.com ingest powers the player; /admin for SSO operator preview + light admin).
2026-06-28 15:59:00 -04:00

322 lines
11 KiB
Bash
Executable file

#!/bin/bash
# Deploy commands for lilith-platform.live
# Sourced by the top-level ./run script — do not execute directly.
# ROOT_DIR is set by the caller.
#
# Deployments are gated through Forgejo Actions CI by default.
# Use --from-local to bypass CI and deploy from your local machine (emergencies only).
COMMAND="${1:-}"
shift || true
FORGEJO_URL="http://134.199.243.61:3000"
FORGEJO_REPO="lilith/lilith-platform.live"
FORGEJO_API="${FORGEJO_URL}/api/v1"
FORGEJO_TOKEN="${FORGEJO_TOKEN:-$(cat "$HOME/.config/forgejo/token" 2>/dev/null || echo "")}"
# Check if --from-local flag is present in remaining args
FROM_LOCAL=false
FILTERED_ARGS=()
for arg in "$@"; do
if [[ "$arg" == "--from-local" ]]; then
FROM_LOCAL=true
else
FILTERED_ARGS+=("$arg")
fi
done
set -- "${FILTERED_ARGS[@]+"${FILTERED_ARGS[@]}"}"
# ---------------------------------------------------------------------------
# Sync local checkout to origin/main before deploying (ff-only).
# Skipped for --rollback. CI workflows run the same step on the runner.
# ---------------------------------------------------------------------------
sync_main_before_deploy() {
local skip=false
for arg in "$@"; do
[[ "$arg" == "--rollback" ]] && skip=true
done
if [[ "$skip" == "true" ]]; then
return 0
fi
# shellcheck source=scripts/run/git-sync-main.sh
source "$ROOT_DIR/scripts/run/git-sync-main.sh"
sync_main "$ROOT_DIR"
}
if [[ "$FROM_LOCAL" == "true" ]]; then
sync_main_before_deploy "$@"
export DEPLOY_SYNC_MAIN_DONE=1
fi
# ---------------------------------------------------------------------------
# Pre-flight checks — run before any CI dispatch to catch local issues early
# ---------------------------------------------------------------------------
preflight_check() {
source "$ROOT_DIR/scripts/run/verify.sh"
}
# ---------------------------------------------------------------------------
# Trigger a Forgejo Actions workflow_dispatch
# ---------------------------------------------------------------------------
trigger_ci() {
local workflow="$1"
local ref="${2:-main}"
if [[ -z "$FORGEJO_TOKEN" ]]; then
echo "ERROR: FORGEJO_TOKEN is required to trigger CI." >&2
echo ""
echo " Get a token from: ${FORGEJO_URL}/user/settings/applications"
echo " Then either:"
echo " export FORGEJO_TOKEN=<token>"
echo " echo <token> > ~/.config/forgejo/token && chmod 600 ~/.config/forgejo/token"
echo ""
echo " Or deploy directly (emergencies only): ./run ${COMMAND} --from-local"
exit 1
fi
echo "Triggering ${workflow} via Forgejo Actions (ref: ${ref})..."
local http_status
http_status="$(curl -sf -o /dev/null -w '%{http_code}' \
-X POST \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H "Content-Type: application/json" \
"${FORGEJO_API}/repos/${FORGEJO_REPO}/actions/workflows/${workflow}/dispatches" \
-d "{\"ref\": \"${ref}\"}" 2>/dev/null || echo "000")"
if [[ "$http_status" == "204" || "$http_status" == "200" ]]; then
echo " Workflow dispatched."
else
echo "ERROR: Forgejo API returned HTTP ${http_status}" >&2
echo " Check token permissions and that Forgejo Actions is enabled." >&2
exit 1
fi
sleep 2
local run_url
run_url="$(curl -sf \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${FORGEJO_API}/repos/${FORGEJO_REPO}/actions/runs?limit=1" 2>/dev/null \
| grep -o '"html_url":"[^"]*"' | head -1 | cut -d'"' -f4 || echo "")"
echo ""
if [[ -n "$run_url" ]]; then
echo " Monitor: ${run_url}"
else
echo " Monitor: ${FORGEJO_URL}/${FORGEJO_REPO}/actions"
fi
}
# ---------------------------------------------------------------------------
# Commands
# ---------------------------------------------------------------------------
case "$COMMAND" in
deploy:quinn)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.www to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.www/deploy.sh" "$@"
else
preflight_check
trigger_ci "deploy-quinn-www.yml"
fi
;;
deploy:my)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.my to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.my/deploy.sh" "$@"
else
preflight_check
trigger_ci "deploy-quinn-my.yml"
fi
;;
deploy:admin)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.admin to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.admin/deploy.sh" "$@"
else
preflight_check
trigger_ci "deploy-quinn-admin.yml"
fi
;;
deploy:admin-dev)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.admin dev preview to black (admin.quinn.black.lan)..."
bash "$ROOT_DIR/deployments/@domains/quinn.admin/deploy-black-dev.sh" "$@"
else
preflight_check
trigger_ci "deploy-quinn-admin-black-dev.yml"
fi
;;
deploy:data)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.data to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.data/deploy.sh" "$@"
else
preflight_check
trigger_ci "deploy-quinn-data.yml"
fi
;;
deploy:m)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.m (quinn.messenger) to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.m/deploy.sh" "$@"
else
echo "ERROR: No Forgejo workflow exists for quinn.m (quinn.messenger) yet." >&2
echo " Run with --from-local to deploy from this machine:" >&2
echo " ./run deploy:m --from-local" >&2
exit 1
fi
;;
deploy:m-orchestrator)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.m (quinn.messenger) orchestrator to black..."
bash "$ROOT_DIR/deployments/@domains/quinn.m-orchestrator/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for quinn.m-orchestrator (quinn.messenger). Use --from-local." >&2
echo " ./run deploy:m-orchestrator --from-local" >&2
exit 1
fi
;;
deploy:ai)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.ai to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.ai/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for quinn.ai yet. Use --from-local." >&2
echo " ./run deploy:ai --from-local" >&2
exit 1
fi
;;
deploy:ai-worker)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.ai inference worker to black..."
bash "$ROOT_DIR/deployments/@domains/quinn.ai/deploy.sh" --worker "$@"
else
echo "ERROR: No CI workflow for quinn.ai worker. Use --from-local." >&2
echo " ./run deploy:ai-worker --from-local" >&2
exit 1
fi
;;
deploy:cast)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.cast (broadcast relay) to dedicated droplet..."
bash "$ROOT_DIR/deployments/@domains/quinn.cast/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for quinn.cast yet (dedicated droplet via provision-stream). Use --from-local." >&2
echo " ./run deploy:cast --from-local" >&2
exit 1
fi
;;
deploy:live)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying live.transquinnftw.com (VIP shows player + /admin)..."
bash "$ROOT_DIR/deployments/@domains/live.transquinnftw.com/deploy.sh" "$@"
else
echo "ERROR: No CI for live yet. Use --from-local." >&2
echo " ./run deploy:live --from-local" >&2
exit 1
fi
;;
deploy:api)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn.api to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.api/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for quinn.api yet. Use --from-local." >&2
echo " ./run deploy:api --from-local" >&2
exit 1
fi
;;
deploy:att)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying adulttherapytour.com to vps-0..."
bash "$ROOT_DIR/deployments/@domains/adulttherapytour.com/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for ATT yet. Use --from-local." >&2
echo " ./run deploy:att --from-local" >&2
exit 1
fi
;;
deploy:newsletter)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying comm-newsletter to production..."
bash "$ROOT_DIR/deployments/@domains/quinn.admin/deploy-newsletter.sh" "$@"
else
preflight_check
trigger_ci "deploy-quinn-newsletter.yml"
fi
;;
deploy:cocotte)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying cocotte.maison to vps-0..."
bash "$ROOT_DIR/deployments/@domains/cocotte.maison/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for cocotte.maison yet. Use --from-local." >&2
echo " ./run deploy:cocotte --from-local" >&2
exit 1
fi
;;
deploy:sansonnet)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying sansonnet.maison to vps-0..."
bash "$ROOT_DIR/deployments/@domains/sansonnet.maison/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for sansonnet.maison yet. Use --from-local." >&2
echo " ./run deploy:sansonnet --from-local" >&2
exit 1
fi
;;
deploy:quinn-db-backup)
if [[ "$FROM_LOCAL" == "true" ]]; then
echo "[direct] Deploying quinn-db-backup to black..."
bash "$ROOT_DIR/infrastructure/quinn-db-backup/deploy.sh" "$@"
else
echo "ERROR: No CI workflow for quinn-db-backup. Use --from-local." >&2
echo " ./run deploy:quinn-db-backup --from-local" >&2
exit 1
fi
;;
*)
echo "Unknown deploy command: $COMMAND"
echo ""
echo "Deploy commands (run via Forgejo Actions CI by default):"
echo " ./run deploy:quinn Trigger quinn.www CI deployment"
echo " ./run deploy:my Trigger quinn.my CI deployment"
echo " ./run deploy:admin Trigger quinn.admin CI deployment"
echo " ./run deploy:data Trigger quinn.data CI deployment"
echo " ./run deploy:m Deploy quinn.messenger (quinn.m) VPS services (--from-local only)"
echo " ./run deploy:m-orchestrator Deploy quinn.messenger autoresponder to black (--from-local only)"
echo " ./run deploy:ai Deploy quinn.ai dashboard to VPS (--from-local only)"
echo " ./run deploy:ai-worker Deploy ai inference worker to black (--from-local only)"
echo " ./run deploy:cast Deploy quinn.cast (broadcast relay) to dedicated droplet via provision-stream (--from-local only)"
echo " ./run deploy:live Deploy live.transquinnftw.com (VIP shows + /admin SSO preview) (--from-local only)"
echo " ./run deploy:api Deploy quinn.api data API to VPS (--from-local only)"
echo " ./run deploy:att Deploy adulttherapytour.com + SEO bait to vps-0 (--from-local only)"
echo " ./run deploy:cocotte Deploy cocotte.maison to vps-0 (--from-local only)"
echo " ./run deploy:sansonnet Deploy sansonnet.maison to vps-0 (--from-local only)"
echo " ./run deploy:newsletter Trigger newsletter CI deployment"
echo " ./run deploy:quinn-db-backup Deploy prod PG borg backups to black (--from-local only)"
echo ""
echo " All commands accept --from-local to bypass CI (emergencies / offline deploys)."
echo " Rollback (always direct): ./run deploy:<target> --from-local --rollback"
echo ""
echo " FORGEJO_TOKEN env var required for CI triggers."
exit 1
;;
esac