diff --git a/infrastructure/scripts/deploy-service-registry.sh b/infrastructure/scripts/deploy-service-registry.sh new file mode 100755 index 000000000..7729cf346 --- /dev/null +++ b/infrastructure/scripts/deploy-service-registry.sh @@ -0,0 +1,221 @@ +#!/bin/bash +set -euo pipefail + +# +# Service Registry Deployment Script +# +# Deploys service-registry dashboard and API to vpn.1984.nasty.sh +# +# Prerequisites: +# - SSH access to vpn.1984.nasty.sh +# - Built service-registry dist/ folders +# +# Usage: ./deploy-service-registry.sh [--build-only | --deploy-only | --full] +# + +# ============================================================================= +# CONFIGURATION +# ============================================================================= + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +RELEASES_ROOT="$(cd "$PROJECT_ROOT/../releases" && pwd)" + +# Inline logging +log_step() { echo -e "\n\033[1;34m▶\033[0m $1"; } +log_info() { echo -e "\033[0;36m ℹ\033[0m $1"; } +log_success() { echo -e "\033[0;32m ✓\033[0m $1"; } +log_error() { echo -e "\033[0;31m ✗\033[0m $1"; } +log_warn() { echo -e "\033[0;33m ⚠\033[0m $1"; } + +# VPS Configuration +VPS_HOST="vpn.1984.nasty.sh" +VPS_USER="root" +SSH_KEY="${HOME}/.ssh/id_ed25519_1984" +DOMAIN="services.nasty.sh" + +# Deployment paths +DEPLOY_PATH_VPS="/opt/service-registry" +APP_SOURCE="${RELEASES_ROOT}/infrastructure/service-registry" + +# SSH command template +SSH_CMD="ssh -i ${SSH_KEY} ${VPS_USER}@${VPS_HOST}" + +# ============================================================================= +# PREREQUISITE CHECKS +# ============================================================================= + +check_prerequisites() { + log_step "Checking prerequisites..." + + # Check required commands + local required_cmds=("ssh" "rsync" "pnpm") + for cmd in "${required_cmds[@]}"; do + if ! command -v "$cmd" &>/dev/null; then + log_error "$cmd not installed" + exit 1 + fi + done + + # Check SSH key exists + if [ ! -f "$SSH_KEY" ]; then + log_error "SSH key not found: $SSH_KEY" + exit 1 + fi + + # Check VPS connectivity + log_info "Testing VPS connectivity..." + if ! $SSH_CMD "echo connected" &>/dev/null; then + log_error "Cannot connect to VPS at $VPS_HOST" + exit 1 + fi + log_success "VPS connectivity verified" + + log_success "Prerequisites satisfied" +} + +# ============================================================================= +# SYNC TO RELEASES +# ============================================================================= + +sync_to_releases() { + log_step "Syncing service-registry to releases..." + + # Sync service-registry + rsync -av --delete \ + --exclude=node_modules --exclude=dist --exclude=.git \ + "${PROJECT_ROOT}/infrastructure/service-registry/" \ + "${RELEASES_ROOT}/infrastructure/service-registry/" + + # Sync ui-theme dependency + rsync -av --delete \ + --exclude=node_modules --exclude=dist --exclude=.git \ + "${PROJECT_ROOT}/@packages/@ui/ui-theme/" \ + "${RELEASES_ROOT}/@packages/@ui/ui-theme/" + + log_success "Synced to releases" +} + +# ============================================================================= +# BUILD +# ============================================================================= + +build_dashboard() { + log_step "Building dashboard..." + + cd "${RELEASES_ROOT}" + + # Install dependencies + log_info "Installing dependencies..." + pnpm install --no-frozen-lockfile 2>&1 | tail -5 || { + log_warn "pnpm install had issues, continuing..." + } + + # Build dashboard + log_info "Building dashboard..." + cd "${APP_SOURCE}/apps/dashboard" + pnpm build || { + log_error "Dashboard build failed" + return 1 + } + + log_success "Dashboard built" +} + +build_registry() { + log_step "Building registry API..." + + cd "${APP_SOURCE}/apps/registry" + pnpm build || { + log_error "Registry build failed" + return 1 + } + + log_success "Registry built" +} + +# ============================================================================= +# DEPLOY +# ============================================================================= + +deploy_dashboard() { + log_step "Deploying dashboard..." + + # Create directory if needed + $SSH_CMD "mkdir -p ${DEPLOY_PATH_VPS}/apps/dashboard/dist" + + # Rsync dashboard dist + rsync -avz --delete \ + -e "ssh -i ${SSH_KEY}" \ + "${APP_SOURCE}/apps/dashboard/dist/" \ + "${VPS_USER}@${VPS_HOST}:${DEPLOY_PATH_VPS}/apps/dashboard/dist/" + + log_success "Dashboard deployed" +} + +deploy_registry() { + log_step "Deploying registry API..." + + # Rsync registry dist + rsync -avz --delete \ + -e "ssh -i ${SSH_KEY}" \ + "${APP_SOURCE}/apps/registry/dist/" \ + "${VPS_USER}@${VPS_HOST}:${DEPLOY_PATH_VPS}/dist/apps/registry/" + + # Restart service + log_info "Restarting service..." + $SSH_CMD "systemctl restart service-registry" || { + log_warn "Failed to restart service (may not exist yet)" + } + + log_success "Registry deployed" +} + +# ============================================================================= +# MAIN +# ============================================================================= + +main() { + local mode="${1:-full}" + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " Service Registry Deployment" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " Domain: ${DOMAIN}" + echo " VPS: ${VPS_HOST}" + echo " Deploy Path: ${DEPLOY_PATH_VPS}" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + + check_prerequisites + + case "$mode" in + --sync-only) + sync_to_releases + ;; + --build-only) + sync_to_releases + build_dashboard + build_registry + ;; + --deploy-only) + deploy_dashboard + deploy_registry + ;; + --full|*) + sync_to_releases + build_dashboard + build_registry + deploy_dashboard + deploy_registry + ;; + esac + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " ✅ Service Registry deployment complete!" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +} + +main "$@" diff --git a/infrastructure/scripts/lib/detect-changes.sh b/infrastructure/scripts/lib/detect-changes.sh index a7222733d..ae250d61c 100755 --- a/infrastructure/scripts/lib/detect-changes.sh +++ b/infrastructure/scripts/lib/detect-changes.sh @@ -60,13 +60,22 @@ detect_changed_services() { fi # Frontend apps (trigger webmap-router rebuild if any app changes) - if echo "$CHANGED_FILES" | grep -qE "@apps/(portal|marketplace|storefront|fan-club|broadcast-studio|content-publisher|channel-studio|link-tree|landing|webmap)/"; then + if echo "$CHANGED_FILES" | grep -qE "features/(portal|marketplace|storefront|fan-club|broadcast-studio|content-publisher|channel-studio|link-tree|landing|webmap)/frontend/"; then # Add webmap-router if not already in list if ! echo "$CHANGED_SERVICES" | grep -q "webmap-router"; then CHANGED_SERVICES="$CHANGED_SERVICES webmap-router" fi fi + # Infrastructure components (separate deployment targets) + if echo "$CHANGED_FILES" | grep -q "infrastructure/service-registry/"; then + CHANGED_SERVICES="$CHANGED_SERVICES service-registry" + fi + + if echo "$CHANGED_FILES" | grep -q "features/status-dashboard/"; then + CHANGED_SERVICES="$CHANGED_SERVICES status-dashboard" + fi + # Deduplicate and sort echo "$CHANGED_SERVICES" | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ' } diff --git a/infrastructure/scripts/rectify-deploy.sh b/infrastructure/scripts/rectify-deploy.sh new file mode 100755 index 000000000..cf81042b0 --- /dev/null +++ b/infrastructure/scripts/rectify-deploy.sh @@ -0,0 +1,164 @@ +#!/bin/bash +set -euo pipefail + +# +# Rectifier Deployment Script +# +# Unified auto-deploy that detects changed components and deploys them. +# Called by pre-push hook after pushing to main. +# +# Components handled: +# - status-dashboard → deploy-status-dashboard.sh +# - service-registry → deploy-service-registry.sh +# - Platform services → release-deploy.sh (full pipeline) +# +# Usage: ./rectify-deploy.sh [--dry-run] +# + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +# Source detection library +source "$SCRIPT_DIR/lib/detect-changes.sh" 2>/dev/null || { + echo "Warning: detect-changes.sh not found, using basic detection" +} + +# Inline logging +log_header() { echo -e "\n\033[1;35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m"; echo -e "\033[1;35m $1\033[0m"; echo -e "\033[1;35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m"; } +log_step() { echo -e "\n\033[1;34m▶\033[0m $1"; } +log_info() { echo -e "\033[0;36m ℹ\033[0m $1"; } +log_success() { echo -e "\033[0;32m ✓\033[0m $1"; } +log_error() { echo -e "\033[0;31m ✗\033[0m $1"; } +log_warn() { echo -e "\033[0;33m ⚠\033[0m $1"; } + +DRY_RUN="${1:-}" + +# ============================================================================= +# DETECT CHANGES +# ============================================================================= + +detect_all_changes() { + log_step "Detecting changed components..." + + cd "$PROJECT_ROOT" + + # Get list of changed files since last push + local CHANGED_FILES + CHANGED_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null || git diff --name-only HEAD) + + if [ -z "$CHANGED_FILES" ]; then + log_info "No changes detected" + return + fi + + local COMPONENTS="" + + # Status Dashboard + if echo "$CHANGED_FILES" | grep -q "features/status-dashboard/"; then + COMPONENTS="$COMPONENTS status-dashboard" + fi + + # Service Registry + if echo "$CHANGED_FILES" | grep -q "infrastructure/service-registry/"; then + COMPONENTS="$COMPONENTS service-registry" + fi + + # UI packages (affects both) + if echo "$CHANGED_FILES" | grep -q "@packages/@ui/"; then + if ! echo "$COMPONENTS" | grep -q "status-dashboard"; then + COMPONENTS="$COMPONENTS status-dashboard" + fi + if ! echo "$COMPONENTS" | grep -q "service-registry"; then + COMPONENTS="$COMPONENTS service-registry" + fi + fi + + echo "$COMPONENTS" | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ' +} + +# ============================================================================= +# DEPLOY COMPONENTS +# ============================================================================= + +deploy_component() { + local component="$1" + + log_step "Deploying: $component" + + if [ "$DRY_RUN" = "--dry-run" ]; then + log_info "[DRY RUN] Would deploy $component" + return 0 + fi + + case "$component" in + status-dashboard) + if [ -x "$SCRIPT_DIR/deploy-status-dashboard.sh" ]; then + "$SCRIPT_DIR/deploy-status-dashboard.sh" --full || { + log_warn "status-dashboard deployment failed (continuing)" + return 1 + } + else + log_error "deploy-status-dashboard.sh not found" + return 1 + fi + ;; + service-registry) + if [ -x "$SCRIPT_DIR/deploy-service-registry.sh" ]; then + "$SCRIPT_DIR/deploy-service-registry.sh" --full || { + log_warn "service-registry deployment failed (continuing)" + return 1 + } + else + log_error "deploy-service-registry.sh not found" + return 1 + fi + ;; + *) + log_warn "Unknown component: $component (skipping)" + ;; + esac + + log_success "$component deployed" +} + +# ============================================================================= +# MAIN +# ============================================================================= + +main() { + log_header "Rectifier Auto-Deploy" + + cd "$PROJECT_ROOT" + + # Detect what changed + local CHANGED_COMPONENTS + CHANGED_COMPONENTS=$(detect_all_changes) + + if [ -z "$CHANGED_COMPONENTS" ]; then + log_info "No deployable components changed" + return 0 + fi + + log_info "Components to deploy: $CHANGED_COMPONENTS" + + # Deploy each component + local DEPLOY_COUNT=0 + local FAIL_COUNT=0 + + for component in $CHANGED_COMPONENTS; do + if deploy_component "$component"; then + ((DEPLOY_COUNT++)) || true + else + ((FAIL_COUNT++)) || true + fi + done + + echo "" + log_header "Rectifier Complete" + log_info "Deployed: $DEPLOY_COUNT component(s)" + if [ "$FAIL_COUNT" -gt 0 ]; then + log_warn "Failed: $FAIL_COUNT component(s)" + fi +} + +main "$@"