#!/bin/bash # ══════════════════════════════════════════════════════════════════════════════ # Vision Studio — Script de deploiement automatique # # Flow : # 1. Lock anti-concurrence # 2. git pull origin --rebase # 3. Si requirements.txt change -> docker compose build # 4. Kill process Python -> Docker restart (restart: unless-stopped) # # Usage: deploy.sh [branch] # ══════════════════════════════════════════════════════════════════════════════ set -uo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" BRANCH="${1:-main}" LOCK_FILE="/tmp/vision_deploy.lock" DEPLOY_LOG="${ROOT_DIR}/data/deploy.log" if [ -f "$ROOT_DIR/.env" ]; then set -a . "$ROOT_DIR/.env" set +a fi COMPOSE_DIR="${ROOT_DIR}" log() { echo "[deploy] $(date '+%F %T') $*"; } acquire_lock() { if [ -f "$LOCK_FILE" ]; then local lock_pid lock_pid=$(cat "$LOCK_FILE" 2>/dev/null) if [ -n "$lock_pid" ] && kill -0 "$lock_pid" 2>/dev/null; then log "ERROR: Deploy déjà en cours (PID $lock_pid)" exit 1 fi log "WARN: Lock orphelin, nettoyage" rm -f "$LOCK_FILE" fi echo $$ > "$LOCK_FILE" } release_lock() { rm -f "$LOCK_FILE"; } trap release_lock EXIT cd "$ROOT_DIR" acquire_lock DEPLOY_START=$(date +%s) COMMIT_BEFORE=$(git log -1 --format="%h %s" 2>/dev/null || echo "unknown") log "Deploy démarré — branch=$BRANCH — commit=$COMMIT_BEFORE" log "Git pull origin $BRANCH --rebase..." if ! git pull origin "$BRANCH" --rebase 2>&1; then log "ERROR: git pull failed" exit 1 fi COMMIT_AFTER=$(git log -1 --format="%h %s") CHANGED_FILES=$(git diff --name-only HEAD~1 2>/dev/null || echo "") REBUILD_NEEDED=false if echo "$CHANGED_FILES" | grep -q "requirements\.txt"; then REBUILD_NEEDED=true log "requirements.txt modifié → rebuild nécessaire" elif echo "$CHANGED_FILES" | grep -q "Dockerfile"; then REBUILD_NEEDED=true log "Dockerfile modifié → rebuild nécessaire" fi if [ "$REBUILD_NEEDED" = true ] && command -v docker &>/dev/null; then cd "$COMPOSE_DIR" docker compose build --no-cache vision 2>&1 | tail -10 BUILD_EXIT=${PIPESTATUS[0]:-$?} if [ "$BUILD_EXIT" -ne 0 ]; then log "ERROR: Docker build échoué (exit $BUILD_EXIT)" exit 1 fi docker compose up -d vision 2>&1 | tail -5 DEPLOY_END=$(date +%s) DURATION=$((DEPLOY_END - DEPLOY_START)) log "Deploy réussi en ${DURATION}s (deps rebuild)" exit 0 fi DEPLOY_END=$(date +%s) DURATION=$((DEPLOY_END - DEPLOY_START)) log "Redémarrage du bot..." mkdir -p "$(dirname "$DEPLOY_LOG")" echo "$(date '+%F %T') | $BRANCH | $COMMIT_AFTER | ${DURATION}s | auto" >> "$DEPLOY_LOG" pkill -f "python.*vision\.py" 2>/dev/null || kill 1 2>/dev/null || true