- Python 3.12 + discord.py - Docker + docker-compose - Forgejo Actions CI (lint + test) - Cog system with /hello example - deploy.sh for auto-deployment
95 lines
3.1 KiB
Bash
Executable file
95 lines
3.1 KiB
Bash
Executable file
#!/bin/bash
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# Vision Studio — Script de deploiement automatique
|
|
#
|
|
# Flow :
|
|
# 1. Lock anti-concurrence
|
|
# 2. git pull origin <branch> --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
|