platform-codebase/infrastructure/scripts/rectify-deploy.sh
Quinn Ftw 327cacd035 fix(reconciliation): run all services from dev machine via SSH
Reconciliation now runs entirely from the dev machine, targeting remote
hosts via SSH instead of syncing scripts and running remotely. This fixes
status-dashboard deployment which requires local build artifacts.

Changes:
- reconcile_host_remote() runs locally with ssh_prefix for all commands
- service.sh handles drift:* and error:* status conventions
- status-dashboard service syncs dist/ via rsync, manages PM2 via SSH
- nginx-config-sync extended to handle sites-available/ directory
- deploy-status-dashboard.sh and rectify-deploy.sh delegate to reconciliation
- Deprecated 7-domain-routing.conf (uses undefined log format)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 05:49:18 -08:00

193 lines
6.3 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 dependency graph library (dynamic detection from package.json files)
source "$SCRIPT_DIR/lib/dependency-graph.sh" 2>/dev/null || {
echo "Warning: dependency-graph.sh not found, using fallback detection"
FALLBACK_DETECTION=true
}
# 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() {
# All logging in this function goes to stderr since stdout is captured
log_step "Detecting changed components..." >&2
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" >&2
return
fi
local file_count
file_count=$(echo "$CHANGED_FILES" | wc -l)
log_info "Changed files: $file_count" >&2
# Use dynamic dependency detection from package.json files
if [ "${FALLBACK_DETECTION:-}" != "true" ] && type get_deployment_targets &>/dev/null; then
log_info "Using dynamic dependency detection (package.json)" >&2
local COMPONENTS
COMPONENTS=$(get_deployment_targets "$CHANGED_FILES")
# Log what was detected
for comp in $COMPONENTS; do
log_info " Deploy target: $comp" >&2
done
echo "$COMPONENTS"
else
# Fallback: pattern-based detection
log_warn "Using fallback pattern detection" >&2
local COMPONENTS=""
# Direct target changes
if echo "$CHANGED_FILES" | grep -q "^features/status-dashboard/"; then
COMPONENTS="$COMPONENTS status-dashboard"
log_info " Direct: status-dashboard" >&2
fi
if echo "$CHANGED_FILES" | grep -q "^infrastructure/service-registry/"; then
COMPONENTS="$COMPONENTS service-registry"
log_info " Direct: service-registry" >&2
fi
# UI packages affect all UI consumers
if echo "$CHANGED_FILES" | grep -q "^@packages/@ui/"; then
COMPONENTS="$COMPONENTS status-dashboard service-registry"
log_info " Package: @packages/@ui/* -> all targets" >&2
fi
# Core packages affect all consumers
if echo "$CHANGED_FILES" | grep -q "^@packages/@core/"; then
COMPONENTS="$COMPONENTS status-dashboard service-registry"
log_info " Package: @packages/@core/* -> all targets" >&2
fi
# Deduplicate and return
echo "$COMPONENTS" | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' '
fi
}
# =============================================================================
# DEPLOY COMPONENTS
# =============================================================================
deploy_component() {
local component="$1"
log_step "Deploying: $component"
if [ "$DRY_RUN" = "--dry-run" ]; then
log_info "[DRY RUN] Would reconcile $component via reconciliation system"
return 0
fi
# All deployments now go through reconciliation system
local reconcile_dir="${PROJECT_ROOT}/codebase/infrastructure/reconciliation"
if [[ ! -x "$reconcile_dir/reconcile" ]]; then
log_error "Reconciliation system not found at: $reconcile_dir"
return 1
fi
case "$component" in
status-dashboard)
log_info "Running reconciliation for status-dashboard..."
"$reconcile_dir/reconcile" --host vps --service status-dashboard || {
log_warn "status-dashboard reconciliation failed (continuing)"
return 1
}
;;
service-registry)
log_info "Running reconciliation for service-registry..."
"$reconcile_dir/reconcile" --host vps --service service-registry || {
log_warn "service-registry reconciliation failed (continuing)"
return 1
}
;;
*)
log_warn "Unknown component: $component (no reconciliation handler)"
return 1
;;
esac
log_success "$component deployed via reconciliation"
}
# =============================================================================
# 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 "$@"