VisionApp/scripts/deploy_runner.sh

95 lines
3.7 KiB
Bash
Raw Normal View History

#!/bin/bash
# ══════════════════════════════════════════════════════════════════════════════
# Vision Studio — Script de deploiement via Forgejo Actions (hote .117)
#
# Calque du deploy_runner.sh de Kuby.
# Tourne sur l'HOTE .117 (utilisateur discord), livre par rsync depuis
# .forgejo/workflows/deploy.yml puis execute a distance en SSH.
#
# Architecture prod .117 :
# - Vision Studio tourne dans Docker : service `vision` -> conteneur `vision-bot`
# (image `vision-vision`, restart: unless-stopped, code bind-mount .:/app).
# - Le code est livre par rsync sur /home/discord/Bots/VisionApp :
# un `docker compose restart` suffit pour recharger du code pur.
# - Si requirements.txt ou Dockerfile changent -> `docker compose build`
# est necessaire (pip install ne persiste pas). Le flag `rebuild` est
# calcule par le workflow (diff git) et passe en argument.
#
# Usage : deploy_runner.sh <branch> <commit> <rebuild>
# ══════════════════════════════════════════════════════════════════════════════
set -uo pipefail
ROOT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)"
BRANCH="${1:-main}"
COMMIT="${2:-inconnu}"
REBUILD="${3:-false}"
LOCK_FILE="/tmp/vision_deploy_runner.lock"
DEPLOY_LOG="${ROOT_DIR}/data/deploy.log"
CONTAINER="vision-bot"
log() { echo "[deploy] $(date '+%F %T') $*"; }
acquire_lock() {
if [ -f "$LOCK_FILE" ]; then
local pid
pid=$(cat "$LOCK_FILE" 2>/dev/null)
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
log "ERROR: deploy deja en cours (PID $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
log "Deploy demarre — branch=$BRANCH commit=$COMMIT rebuild=$REBUILD"
if ! command -v docker &>/dev/null; then
log "ERROR: docker introuvable sur l'hote"
exit 1
fi
# Transition systemd -> Docker (une seule fois) : arreter l'ancien service pour
# eviter deux instances du bot avec le meme token Discord.
if command -v systemctl &>/dev/null && systemctl list-unit-files 2>/dev/null | grep -q '^vision-studio\.service'; then
if systemctl is-active --quiet vision-studio 2>/dev/null; then
log "Transition: arret du service systemd vision-studio..."
if ! sudo -n systemctl stop vision-studio 2>/dev/null; then
log "WARN: arret systemd refuse (sudo sans mot de passe). A faire une fois manuellement:"
log " sudo systemctl stop vision-studio && sudo systemctl disable vision-studio"
fi
fi
fi
if [ "$REBUILD" = "true" ]; then
log "requirements/Dockerfile modifies -> rebuild image Docker..."
if ! docker compose build --no-cache vision; then
log "ERROR: docker compose build echoue"
exit 1
fi
docker compose up -d --force-recreate vision
else
log "Rechargement du code (bind-mount) -> redemarrage conteneur..."
docker compose up -d vision
docker compose restart vision
fi
sleep 5
if ! docker ps --filter "name=${CONTAINER}" --filter "status=running" --format '{{.Names}}' | grep -q "${CONTAINER}"; then
log "ERROR: conteneur ${CONTAINER} non demarre"
docker logs --tail 40 "${CONTAINER}" 2>&1 || true
exit 1
fi
mkdir -p "$(dirname "$DEPLOY_LOG")"
echo "$(date '+%F %T') | $BRANCH | $COMMIT | rebuild=$REBUILD | auto" >> "$DEPLOY_LOG"
log "Deploy termine — conteneur ${CONTAINER} en marche"