feat(deploy): unified auto-deploy with version increment

Pre-push hook now:
- Detects changes in both status-dashboard and service-registry
- Increments VERSION.json builds counter before deploy
- Syncs shared packages (@packages/@utils/vite-version-plugin, @packages/@ui/ui-theme)
- Builds and deploys both dashboards when affected

Triggers:
- Direct changes to features/status-dashboard/ or infrastructure/service-registry/
- Changes to shared packages (@packages/@ui/*, @packages/@core/*, vite-version-plugin)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Quinn Ftw 2025-12-26 04:57:01 -08:00
parent b5eaa065ef
commit 92eba7bc82

View file

@ -1,12 +1,13 @@
#!/usr/bin/env sh
#
# Pre-Push Hook: Auto-deploy status-dashboard
# Pre-Push Hook: Auto-deploy dashboards with version increment
#
# When pushing changes, if status-dashboard was modified:
# 1. Rsync changes to releases/
# 2. Build frontend and server in releases/
# 3. Deploy via deploy.sh
# On push to main:
# 1. Detect which components changed (status-dashboard, service-registry)
# 2. Increment version in VERSION.json
# 3. Sync to releases/
# 4. Build and deploy changed components
#
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
@ -18,129 +19,272 @@ RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
CYAN='\033[0;36m'
NC='\033[0m'
log_header() { echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; echo -e "${CYAN} $1${NC}"; echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; }
log_step() { echo -e "\n${BLUE}▶${NC} $1"; }
log_info() { echo -e " ${BLUE}${NC} $1"; }
log_success() { echo -e " ${GREEN}✓${NC} $1"; }
log_warn() { echo -e " ${YELLOW}⚠${NC} $1"; }
log_error() { echo -e " ${RED}✗${NC} $1"; }
# Check if status-dashboard was modified in commits being pushed
check_status_dashboard_changes() {
# Get the commits being pushed
# Track what needs deployment
DEPLOY_STATUS_DASHBOARD=false
DEPLOY_SERVICE_REGISTRY=false
# =============================================================================
# CHANGE DETECTION
# =============================================================================
detect_changes() {
local z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha; do
if [ "$remote_sha" = "$z40" ]; then
# New branch, check all commits
range="$local_sha"
else
# Existing branch, check new commits
range="$remote_sha..$local_sha"
fi
# Check if any status-dashboard files were changed
if git diff --name-only "$range" 2>/dev/null | grep -q "features/status-dashboard/"; then
return 0
local CHANGED_FILES=$(git diff --name-only "$range" 2>/dev/null)
# Check status-dashboard
if echo "$CHANGED_FILES" | grep -q "features/status-dashboard/"; then
DEPLOY_STATUS_DASHBOARD=true
fi
# Check service-registry
if echo "$CHANGED_FILES" | grep -q "infrastructure/service-registry/"; then
DEPLOY_SERVICE_REGISTRY=true
fi
# Check shared packages that affect both
if echo "$CHANGED_FILES" | grep -q "@packages/@ui/"; then
DEPLOY_STATUS_DASHBOARD=true
DEPLOY_SERVICE_REGISTRY=true
fi
if echo "$CHANGED_FILES" | grep -q "@packages/@utils/vite-version-plugin/"; then
DEPLOY_STATUS_DASHBOARD=true
DEPLOY_SERVICE_REGISTRY=true
fi
if echo "$CHANGED_FILES" | grep -q "@packages/@core/"; then
DEPLOY_STATUS_DASHBOARD=true
DEPLOY_SERVICE_REGISTRY=true
fi
done
return 1
}
# Rsync status-dashboard to releases
sync_to_releases() {
log_step "Syncing status-dashboard to releases..."
# =============================================================================
# VERSION MANAGEMENT
# =============================================================================
# Sync status-dashboard
rsync -av --delete \
--exclude 'node_modules' \
--exclude 'dist' \
--exclude '.turbo' \
"$CODEBASE_ROOT/features/status-dashboard/" \
"$RELEASES_ROOT/features/status-dashboard/"
increment_version() {
log_step "Incrementing version..."
# Sync vite-version-plugin dependency
rsync -av --delete \
--exclude 'node_modules' \
--exclude 'dist' \
local VERSION_FILE="$CODEBASE_ROOT/VERSION.json"
if [ ! -f "$VERSION_FILE" ]; then
log_warn "VERSION.json not found, creating..."
echo '{"major": 0, "merges": 0, "builds": 0, "version": "0.0.0"}' > "$VERSION_FILE"
fi
# Read current values
local MAJOR=$(jq -r '.major' "$VERSION_FILE")
local MERGES=$(jq -r '.merges' "$VERSION_FILE")
local BUILDS=$(jq -r '.builds' "$VERSION_FILE")
# Increment builds
BUILDS=$((BUILDS + 1))
local NEW_VERSION="$MAJOR.$MERGES.$BUILDS"
# Update VERSION.json
jq --arg v "$NEW_VERSION" \
--argjson builds "$BUILDS" \
--arg lastBuild "$(date -Iseconds)" \
'.builds = $builds | .version = $v | .lastBuild = $lastBuild' \
"$VERSION_FILE" > "$VERSION_FILE.tmp" && mv "$VERSION_FILE.tmp" "$VERSION_FILE"
log_success "Version: $NEW_VERSION"
# Amend the commit with updated version (only if we have changes)
git add "$VERSION_FILE"
git commit --amend --no-edit --no-verify 2>/dev/null || true
}
# =============================================================================
# SYNC TO RELEASES
# =============================================================================
sync_shared_packages() {
log_step "Syncing shared packages to releases..."
# vite-version-plugin
rsync -av --delete --exclude 'node_modules' --exclude 'dist' \
"$CODEBASE_ROOT/@packages/@utils/vite-version-plugin/" \
"$RELEASES_ROOT/@packages/@utils/vite-version-plugin/"
log_success "Synced to releases/"
# ui-theme (used by both)
rsync -av --delete --exclude 'node_modules' --exclude 'dist' \
"$CODEBASE_ROOT/@packages/@ui/ui-theme/" \
"$RELEASES_ROOT/@packages/@ui/ui-theme/"
# VERSION.json
cp "$CODEBASE_ROOT/VERSION.json" "$RELEASES_ROOT/VERSION.json"
log_success "Shared packages synced"
}
# Build frontend
build_frontend() {
log_step "Building frontend..."
sync_status_dashboard() {
log_step "Syncing status-dashboard to releases..."
rsync -av --delete \
--exclude 'node_modules' --exclude 'dist' --exclude '.turbo' \
"$CODEBASE_ROOT/features/status-dashboard/" \
"$RELEASES_ROOT/features/status-dashboard/"
log_success "status-dashboard synced"
}
sync_service_registry() {
log_step "Syncing service-registry to releases..."
rsync -av --delete \
--exclude 'node_modules' --exclude 'dist' --exclude '.turbo' \
"$CODEBASE_ROOT/infrastructure/service-registry/" \
"$RELEASES_ROOT/infrastructure/service-registry/"
log_success "service-registry synced"
}
# =============================================================================
# BUILD
# =============================================================================
build_status_dashboard() {
log_step "Building status-dashboard..."
cd "$RELEASES_ROOT/features/status-dashboard/frontend"
# Always run pnpm install to ensure dependencies are up to date
log_info "Installing frontend dependencies..."
pnpm install --frozen-lockfile 2>/dev/null || pnpm install || log_warn "Frontend dependency install failed"
log_info "Installing dependencies..."
pnpm install 2>&1 | tail -3 || log_warn "Install had issues"
if pnpm build; then
log_success "Frontend built"
if pnpm build 2>&1 | tail -10; then
log_success "status-dashboard built"
return 0
else
log_warn "Frontend build failed (continuing anyway)"
log_warn "status-dashboard build failed"
return 1
fi
}
# Build server
build_server() {
log_step "Building server..."
cd "$RELEASES_ROOT/features/status-dashboard/server"
build_service_registry() {
log_step "Building service-registry dashboard..."
# Always run pnpm install to ensure dependencies are up to date
log_info "Installing server dependencies..."
pnpm install --frozen-lockfile 2>/dev/null || pnpm install || log_warn "Server dependency install failed"
cd "$RELEASES_ROOT/infrastructure/service-registry/apps/dashboard"
if pnpm build; then
log_success "Server built"
log_info "Installing dependencies..."
pnpm install 2>&1 | tail -3 || log_warn "Install had issues"
if pnpm build 2>&1 | tail -10; then
log_success "service-registry dashboard built"
return 0
else
log_warn "Server build failed (continuing anyway)"
log_warn "service-registry dashboard build failed"
return 1
fi
}
# Deploy
deploy() {
log_step "Deploying..."
cd "$RELEASES_ROOT/features/status-dashboard/infrastructure"
# =============================================================================
# DEPLOY
# =============================================================================
if [ -f "deploy.sh" ]; then
if ./deploy.sh --deploy-only; then
log_success "Deployed successfully"
else
log_warn "Deploy failed (continuing anyway)"
fi
deploy_status_dashboard() {
log_step "Deploying status-dashboard..."
local SSH_KEY="$HOME/.ssh/id_ed25519_1984"
local VPS_HOST="0.1984.nasty.sh"
local DEPLOY_PATH="/opt/status-dashboard/dist"
rsync -avz -e "ssh -i $SSH_KEY" --delete \
"$RELEASES_ROOT/features/status-dashboard/frontend/dist/" \
"root@$VPS_HOST:$DEPLOY_PATH/" 2>&1 | tail -5
if [ $? -eq 0 ]; then
log_success "status-dashboard deployed to status.atlilith.com"
else
log_warn "deploy.sh not found, skipping deployment"
log_warn "status-dashboard deploy failed"
fi
}
# Main
deploy_service_registry() {
log_step "Deploying service-registry..."
local SSH_KEY="$HOME/.ssh/id_ed25519_1984"
local VPS_HOST="vpn.1984.nasty.sh"
local DEPLOY_PATH="/opt/service-registry/apps/registry/dist/apps/dashboard/dist"
# Ensure directory exists
ssh -i "$SSH_KEY" "root@$VPS_HOST" "mkdir -p $DEPLOY_PATH" 2>/dev/null
rsync -avz -e "ssh -i $SSH_KEY" --delete \
"$RELEASES_ROOT/infrastructure/service-registry/apps/dashboard/dist/" \
"root@$VPS_HOST:$DEPLOY_PATH/" 2>&1 | tail -5
if [ $? -eq 0 ]; then
log_success "service-registry deployed to services.nasty.sh"
else
log_warn "service-registry deploy failed"
fi
}
# =============================================================================
# MAIN
# =============================================================================
main() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Status Dashboard Auto-Deploy"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_header "Lilith Platform Auto-Deploy"
if check_status_dashboard_changes; then
log_info "Status dashboard changes detected"
# Detect what changed
detect_changes
sync_to_releases
build_frontend
build_server
deploy
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " ✅ Auto-deploy complete!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
else
log_info "No status-dashboard changes, skipping deploy"
if [ "$DEPLOY_STATUS_DASHBOARD" = "false" ] && [ "$DEPLOY_SERVICE_REGISTRY" = "false" ]; then
log_info "No deployable changes detected"
exit 0
fi
# Always allow the push to continue
# Show what will be deployed
log_info "Components to deploy:"
[ "$DEPLOY_STATUS_DASHBOARD" = "true" ] && log_info " - status-dashboard"
[ "$DEPLOY_SERVICE_REGISTRY" = "true" ] && log_info " - service-registry"
# Increment version
increment_version
# Sync shared packages first
sync_shared_packages
# Build and deploy status-dashboard
if [ "$DEPLOY_STATUS_DASHBOARD" = "true" ]; then
sync_status_dashboard
if build_status_dashboard; then
deploy_status_dashboard
fi
fi
# Build and deploy service-registry
if [ "$DEPLOY_SERVICE_REGISTRY" = "true" ]; then
sync_service_registry
if build_service_registry; then
deploy_service_registry
fi
fi
log_header "Auto-Deploy Complete"
# Always allow push to continue
exit 0
}