Update deploy-all.sh to pull shared base images before building, ensuring all repos use the latest common package versions. Changes: - Add base image pull step (backend and web) - Use local cache if pull fails - Apply to all repos in deployment list Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
201 lines
8.4 KiB
Bash
Executable File
201 lines
8.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
# ByteLyst Production Deployment - All Repos
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
# Usage: ./deploy-all.sh [--force] [--skip-health-check] [repo1 repo2 ...]
|
|
#
|
|
# Deploys all production repos or specific repos:
|
|
# - learning_ai_invt_trdg (Trading)
|
|
# - learning_ai_common_plat (Platform Services)
|
|
# - learning_ai_clock (ChronoMind)
|
|
# - learning_ai_notes (NoteLett)
|
|
#
|
|
# Options:
|
|
# --force Skip dirty checks and force deployment
|
|
# --skip-health-check Skip endpoint health verification
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
|
|
|
log() { echo -e "${CYAN}[$(date +%H:%M:%S)]${NC} $*"; }
|
|
ok() { echo -e "${GREEN}[$(date +%H:%M:%S)] ✓${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[$(date +%H:%M:%S)] ⚠${NC} $*"; }
|
|
fail() { echo -e "${RED}[$(date +%H:%M:%S)] ✗${NC} $*"; exit 1; }
|
|
|
|
# ── Configuration ────────────────────────────────────────────────────
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
REPOS_BASE_DIR="${SCRIPT_DIR}/.."
|
|
cd "$SCRIPT_DIR"
|
|
|
|
PRODUCTION_REPOS=(
|
|
"learning_ai_invt_trdg"
|
|
"learning_ai_common_plat"
|
|
"learning_ai_clock"
|
|
"learning_ai_notes"
|
|
)
|
|
|
|
FORCE=false
|
|
SKIP_HEALTH_CHECK=false
|
|
SPECIFIC_REPOS=()
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--force) FORCE=true; shift ;;
|
|
--skip-health-check) SKIP_HEALTH_CHECK=true; shift ;;
|
|
-*) fail "Unknown option: $1" ;;
|
|
*) SPECIFIC_REPOS+=("$1"); shift ;;
|
|
esac
|
|
done
|
|
|
|
# If specific repos provided, validate them
|
|
if [ ${#SPECIFIC_REPOS[@]} -gt 0 ]; then
|
|
for repo in "${SPECIFIC_REPOS[@]}"; do
|
|
valid=false
|
|
for valid_repo in "${PRODUCTION_REPOS[@]}"; do
|
|
if [ "$repo" = "$valid_repo" ]; then
|
|
valid=true
|
|
break
|
|
fi
|
|
done
|
|
if [ "$valid" = false ]; then
|
|
fail "Unknown repo: $repo. Valid repos: ${PRODUCTION_REPOS[*]}"
|
|
fi
|
|
done
|
|
REPOS_TO_DEPLOY=("${SPECIFIC_REPOS[@]}")
|
|
else
|
|
REPOS_TO_DEPLOY=("${PRODUCTION_REPOS[@]}")
|
|
fi
|
|
|
|
# ── Deploy Function ───────────────────────────────────────────────────
|
|
deploy_repo() {
|
|
local repo="$1"
|
|
local repo_dir="${REPOS_BASE_DIR}/${repo}"
|
|
|
|
log "══════════════════════════════════════════════════════════════════════"
|
|
log "Deploying: $repo"
|
|
log "══════════════════════════════════════════════════════════════════════"
|
|
|
|
if [ ! -d "$repo_dir" ]; then
|
|
fail "Repo directory not found: $repo_dir"
|
|
fi
|
|
|
|
cd "$repo_dir"
|
|
|
|
# ── Dirty Check ───────────────────────────────────────────────────
|
|
if [ "$FORCE" = false ]; then
|
|
log "Running dirty checks for $repo..."
|
|
|
|
if ! git diff-index --quiet HEAD --; then
|
|
fail "Uncommitted changes in $repo. Commit or stash first, or use --force"
|
|
fi
|
|
|
|
if [ -n "$(git ls-files --others --exclude-standard)" ]; then
|
|
fail "Untracked files in $repo. Commit or remove them, or use --force"
|
|
fi
|
|
|
|
LOCAL_COMMIT=$(git rev-parse @)
|
|
REMOTE_COMMIT=$(git rev-parse '@{u}' 2>/dev/null || echo "")
|
|
|
|
if [ -n "$REMOTE_COMMIT" ] && [ "$LOCAL_COMMIT" != "$REMOTE_COMMIT" ]; then
|
|
fail "Unpushed commits in $repo. Push first or use --force"
|
|
fi
|
|
|
|
ok "Dirty checks passed for $repo"
|
|
else
|
|
warn "Skipping dirty checks for $repo (--force enabled)"
|
|
fi
|
|
|
|
# ── Pull and Rebase ───────────────────────────────────────────────
|
|
log "Pulling latest changes for $repo..."
|
|
git fetch origin
|
|
|
|
LOCAL_MAIN=$(git rev-parse main)
|
|
REMOTE_MAIN=$(git rev-parse origin/main)
|
|
|
|
if [ "$LOCAL_MAIN" != "$REMOTE_MAIN" ]; then
|
|
log "Local main is behind origin/main, rebasing $repo..."
|
|
git rebase origin/main || {
|
|
fail "Rebase failed for $repo. Resolve conflicts and run: git rebase --continue"
|
|
}
|
|
ok "Rebase completed for $repo"
|
|
else
|
|
ok "$repo is already up to date"
|
|
fi
|
|
|
|
# ── Build and Deploy ───────────────────────────────────────────────
|
|
if [ -f "docker-compose.yml" ]; then
|
|
log "Building and deploying $repo..."
|
|
|
|
# Pull latest base images
|
|
log "Pulling latest base images for $repo..."
|
|
docker pull bytelyst-common-base-backend:latest || warn "Failed to pull backend base image for $repo, using local cache"
|
|
docker pull bytelyst-common-base-web:latest || warn "Failed to pull web base image for $repo, using local cache"
|
|
|
|
docker compose build || fail "Docker build failed for $repo"
|
|
docker compose up -d || fail "Docker compose up failed for $repo"
|
|
ok "Deployment completed for $repo"
|
|
else
|
|
warn "No docker-compose.yml found in $repo, skipping Docker deployment"
|
|
fi
|
|
|
|
cd "$REPOS_BASE_DIR"
|
|
}
|
|
|
|
# ── Deploy All Repos ───────────────────────────────────────────────────
|
|
FAILED_REPOS=()
|
|
SUCCESSFUL_REPOS=()
|
|
|
|
for repo in "${REPOS_TO_DEPLOY[@]}"; do
|
|
if deploy_repo "$repo"; then
|
|
SUCCESSFUL_REPOS+=("$repo")
|
|
else
|
|
FAILED_REPOS+=("$repo")
|
|
fi
|
|
done
|
|
|
|
# ── Summary ─────────────────────────────────────────────────────────────
|
|
log "══════════════════════════════════════════════════════════════════════"
|
|
log "Deployment Summary"
|
|
log "══════════════════════════════════════════════════════════════════════"
|
|
|
|
if [ ${#SUCCESSFUL_REPOS[@]} -gt 0 ]; then
|
|
ok "Successfully deployed: ${SUCCESSFUL_REPOS[*]}"
|
|
fi
|
|
|
|
if [ ${#FAILED_REPOS[@]} -gt 0 ]; then
|
|
fail "Failed to deploy: ${FAILED_REPOS[*]}"
|
|
fi
|
|
|
|
# ── Health Checks (if not skipped) ───────────────────────────────────────
|
|
if [ "$SKIP_HEALTH_CHECK" = false ]; then
|
|
log "Running health checks..."
|
|
|
|
# Define health endpoints for each service
|
|
declare -A HEALTH_ENDPOINTS=(
|
|
["learning_ai_invt_trdg"]="http://localhost:4025/health/live"
|
|
["learning_ai_common_plat"]="http://localhost:4003/health"
|
|
["learning_ai_clock"]="http://localhost:4011/health"
|
|
["learning_ai_notes"]="http://localhost:4016/health"
|
|
)
|
|
|
|
for repo in "${SUCCESSFUL_REPOS[@]}"; do
|
|
endpoint="${HEALTH_ENDPOINTS[$repo]:-}"
|
|
if [ -n "$endpoint" ]; then
|
|
log "Checking $repo at $endpoint"
|
|
if curl -sf "$endpoint" > /dev/null 2>&1; then
|
|
ok "$repo is healthy"
|
|
else
|
|
warn "$repo health check failed (may still be starting)"
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
warn "Skipping health checks (--skip-health-check enabled)"
|
|
fi
|
|
|
|
log "══════════════════════════════════════════════════════════════════════"
|
|
ok "All deployments completed successfully!"
|
|
log "══════════════════════════════════════════════════════════════════════"
|