disclosure-bureau/infra/disclosure-stack/scripts/deploy-incremental.sh

126 lines
8.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# Incremental deploy — syncs only new/changed code + raw/--subagent data.
# Skips re-syncing wiki/, processing/png/, processing/ocr/ (already on VPS).
#
# Steps:
# 1. Sync infra updates (compose, embed-service Dockerfile, migration 02)
# 2. Sync web/ Next.js source (V2, search, graph, timeline, stats, command palette)
# 3. Sync scripts/ (30-33 new scripts)
# 4. Sync raw/*--subagent/ (chunks, 634MB — needed for V2 view)
# 5. Apply migration 02 (pgvector + chunks_retrieval schema)
# 6. Build & start embed-service (BGE-M3 + reranker) — runs in background
# 7. Rebuild web container
# 8. Report URLs
source "$(dirname "$0")/_lib.sh"
set -euo pipefail
STACK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
UFO_ROOT="${LAPTOP_UFO_ROOT:-/Users/guto/ufo}"
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 1 — sync infra (compose, embed-service, migration 02)"
echo "════════════════════════════════════════════════════════════════"
vps_ssh "mkdir -p ${VPS_DEPLOY_ROOT}/{migrations,embed-service}"
vps_rsync "${STACK_DIR}/docker-compose.yml" "${VPS_DEPLOY_ROOT}/docker-compose.yml"
vps_rsync "${STACK_DIR}/kong.yml" "${VPS_DEPLOY_ROOT}/kong.yml"
vps_rsync "${STACK_DIR}/.env" "${VPS_DEPLOY_ROOT}/.env"
vps_rsync "${STACK_DIR}/../supabase/migrations/0002_chunks_retrieval.sql" \
"${VPS_DEPLOY_ROOT}/migrations/02-chunks-retrieval.sql"
vps_rsync "${STACK_DIR}/../embed-service/Dockerfile" "${VPS_DEPLOY_ROOT}/embed-service/Dockerfile"
vps_rsync "${STACK_DIR}/../embed-service/app.py" "${VPS_DEPLOY_ROOT}/embed-service/app.py"
vps_rsync "${STACK_DIR}/../embed-service/requirements.txt" "${VPS_DEPLOY_ROOT}/embed-service/requirements.txt"
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 2 — sync web/ source (Next.js — V2 + retrieval features)"
echo "════════════════════════════════════════════════════════════════"
if [ "$VPS_AUTH" = "password" ]; then
SSHPASS="$VPS_PASSWORD" sshpass -e rsync -avz --delete \
--exclude node_modules --exclude .next --exclude .env.local \
-e "ssh -o StrictHostKeyChecking=accept-new -p $VPS_PORT" \
"${UFO_ROOT}/web/" "${VPS_USER}@${VPS_HOST}:${VPS_DEPLOY_ROOT}/web/"
else
rsync -avz --delete \
--exclude node_modules --exclude .next --exclude .env.local \
-e "ssh -o StrictHostKeyChecking=accept-new -p $VPS_PORT -i ${VPS_SSH_KEY/#\~/$HOME}" \
"${UFO_ROOT}/web/" "${VPS_USER}@${VPS_HOST}:${VPS_DEPLOY_ROOT}/web/"
fi
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 3 — sync scripts/ (30-33 retrieval pipeline scripts)"
echo "════════════════════════════════════════════════════════════════"
vps_ssh "mkdir -p ${VPS_DEPLOY_ROOT}/scripts"
if [ "$VPS_AUTH" = "password" ]; then
SSHPASS="$VPS_PASSWORD" sshpass -e rsync -avz \
-e "ssh -o StrictHostKeyChecking=accept-new -p $VPS_PORT" \
"${UFO_ROOT}/scripts/" "${VPS_USER}@${VPS_HOST}:${VPS_DEPLOY_ROOT}/scripts/"
else
rsync -avz \
-e "ssh -o StrictHostKeyChecking=accept-new -p $VPS_PORT -i ${VPS_SSH_KEY/#\~/$HOME}" \
"${UFO_ROOT}/scripts/" "${VPS_USER}@${VPS_HOST}:${VPS_DEPLOY_ROOT}/scripts/"
fi
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 4 — sync raw/*--subagent/ (chunks v0.2.0, ~634MB, 116 docs)"
echo "════════════════════════════════════════════════════════════════"
echo "Note: only --subagent/ archives are synced (chunks + crops + index)"
echo " Raw PDFs already on VPS — not re-synced"
if [ "$VPS_AUTH" = "password" ]; then
SSHPASS="$VPS_PASSWORD" sshpass -e rsync -avz \
--include='*--subagent/' --include='*--subagent/**' --include='*.pdf' --exclude='*' \
-e "ssh -o StrictHostKeyChecking=accept-new -p $VPS_PORT" \
"${UFO_ROOT}/raw/" "${VPS_USER}@${VPS_HOST}:${DATA_RAW:-${VPS_DEPLOY_ROOT}/raw}/"
else
rsync -avz \
--include='*--subagent/' --include='*--subagent/**' --include='*.pdf' --exclude='*' \
-e "ssh -o StrictHostKeyChecking=accept-new -p $VPS_PORT -i ${VPS_SSH_KEY/#\~/$HOME}" \
"${UFO_ROOT}/raw/" "${VPS_USER}@${VPS_HOST}:${DATA_RAW:-${VPS_DEPLOY_ROOT}/raw}/"
fi
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 5 — apply migration 02 (pgvector + chunks tables)"
echo "════════════════════════════════════════════════════════════════"
vps_ssh "cd ${VPS_DEPLOY_ROOT} && docker exec -i disclosure-db psql -U postgres < migrations/02-chunks-retrieval.sql 2>&1 | tail -10"
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 6 — build + start embed-service (BGE-M3, ~10min first build)"
echo "════════════════════════════════════════════════════════════════"
vps_ssh "cd ${VPS_DEPLOY_ROOT} && docker compose build embed 2>&1 | tail -5"
vps_ssh "cd ${VPS_DEPLOY_ROOT} && docker compose up -d embed"
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 7 — rebuild + restart web (Next.js with V2/search/graph)"
echo "════════════════════════════════════════════════════════════════"
vps_ssh "cd ${VPS_DEPLOY_ROOT} && docker compose build web 2>&1 | tail -5"
vps_ssh "cd ${VPS_DEPLOY_ROOT} && docker compose up -d --force-recreate web"
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " STAGE 8 — status"
echo "════════════════════════════════════════════════════════════════"
vps_ssh "cd ${VPS_DEPLOY_ROOT} && docker compose ps"
echo ""
echo "✓ Incremental deploy complete."
echo ""
echo "Test URLs:"
echo " https://${DOMAIN_MAIN:-disclosure.top}/ (home with filters + summaries + ✨v2 badges)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/d/doc-342-.../v2 (rich chunks view)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/search (hybrid search palette)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/timeline (decade timeline)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/graph (force-directed)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/admin/stats (corpus analytics)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/admin/batch (batch monitor)"
echo " https://${DOMAIN_MAIN:-disclosure.top}/admin/indexer (retrieval health)"
echo ""
echo "Embed-service may take ~5 minutes to download BGE-M3 weights on first /embed call."
echo "Indexer (next step, not run by this script):"
echo " ssh vps && docker exec disclosure-embed curl -s http://localhost:8000/health"
echo " # then run: scripts/30-index-chunks-to-db.py from a container with internal network"