Nach dem 1.x → 2.0-Cut auf prod (siehe v2.0.0-Tag) laeuft prod als sauberer git-checkout. Tar-Upload-Pfad ist obsolet. - scripts/deploy.sh: Branch-Guard release/2.0, Pre-flight-Checks (clean + pushed), Pre-Deploy-DB-Backup, Uptime-Kuma-Wartungsmodus, /health-Check mit Version-Anzeige nach Deploy - scripts/major-release-cut.sh: dokumentierter Workflow fuer den naechsten Major-Cut (z.B. 2.0 → 3.0). Inklusive Bundle-Fallback bei Gitea-Korruption (war beim 2.0-Cut gebraucht), DB-Wipe-Liste mit Erhalt der Vote-Daten, Pfad-Switchover und Smoke-Tests
135 lines
4.4 KiB
Bash
Executable File
135 lines
4.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Standard-Deploy auf gwoe.toppyr.de (Prod).
|
|
#
|
|
# Workflow ab v2.0.0: prod laeuft als sauberer git-checkout, der Server
|
|
# zieht den release/2.0-Branch direkt aus dem Gitea-Repo. Tar-Upload-
|
|
# Pfad ist obsolet (siehe scripts/major-release-cut.sh fuer den
|
|
# Spezialfall eines neuen Major-Cuts).
|
|
#
|
|
# Setzt den Uptime-Kuma-Monitor auf Wartung, deployed, reaktiviert.
|
|
#
|
|
# Usage:
|
|
# ./scripts/deploy.sh # Deploy aktuellen release/2.0-Stand
|
|
# ./scripts/deploy.sh --force # Branch-Guard ueberspringen (Notfall)
|
|
#
|
|
# Voraussetzungen:
|
|
# - Lokaler Branch ist release/2.0 (oder --force)
|
|
# - Remote release/2.0 ist gepusht
|
|
# - SSH-Zugang zu vserver
|
|
# - UPTIME_KUMA_USER + UPTIME_KUMA_PASS in ~/.env (optional)
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
SERVER="vserver"
|
|
REMOTE_DIR="/opt/gwoe-antragspruefer"
|
|
PUBLIC_URL="https://gwoe.toppyr.de"
|
|
UPTIME_KUMA_URL="https://status.toppyr.de"
|
|
MONITOR_ID=9
|
|
EXPECTED_BRANCH="release/2.0"
|
|
|
|
if [ -f ~/.env ]; then
|
|
source ~/.env
|
|
fi
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Branch-Guard
|
|
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
if [ "${1:-}" = "--force" ]; then
|
|
shift
|
|
echo "⚠ --force aktiv: Branch-Guard übersprungen ($CURRENT_BRANCH)"
|
|
elif [ "$CURRENT_BRANCH" != "$EXPECTED_BRANCH" ]; then
|
|
cat <<EOF
|
|
✗ Prod-Deploy abgebrochen: lokal aktiv ist '$CURRENT_BRANCH', erwartet '$EXPECTED_BRANCH'.
|
|
|
|
Prod (gwoe.toppyr.de) ist ab v2.0.0 auf release/2.0 festgelegt.
|
|
|
|
Fuer ein normales Update:
|
|
git checkout release/2.0
|
|
git merge --ff-only main # falls main neuer ist
|
|
git push
|
|
./scripts/deploy.sh
|
|
|
|
Fuer Dev (gwoe-dev.toppyr.de) braucht es kein deploy.sh — der Server
|
|
zieht main per Cron alle 5 Minuten.
|
|
|
|
Mit --force kann der Guard ueberbrueckt werden (nur in Notfaellen).
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
# Pre-flight: lokal commited?
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo "⚠ Working tree ist nicht clean — uncommitted changes:"
|
|
git status --short
|
|
read -p "Trotzdem fortfahren? [y/N] " ans
|
|
[ "$ans" = "y" ] || exit 1
|
|
fi
|
|
|
|
# Pre-flight: lokal gepusht?
|
|
LOCAL_HEAD=$(git rev-parse HEAD)
|
|
REMOTE_HEAD=$(git rev-parse "origin/$EXPECTED_BRANCH" 2>/dev/null || echo "")
|
|
if [ "$LOCAL_HEAD" != "$REMOTE_HEAD" ]; then
|
|
echo "⚠ Lokal ($LOCAL_HEAD) != origin/$EXPECTED_BRANCH ($REMOTE_HEAD)"
|
|
echo " Erst pushen, dann deployen."
|
|
exit 1
|
|
fi
|
|
|
|
echo "=== Deploy GWÖ-Antragsprüfer auf $PUBLIC_URL ==="
|
|
echo "Branch: $EXPECTED_BRANCH @ ${LOCAL_HEAD:0:8}"
|
|
|
|
# 1. Uptime Kuma auf Wartung
|
|
if [ -n "${UPTIME_KUMA_USER:-}" ] && [ -n "${UPTIME_KUMA_PASS:-}" ]; then
|
|
echo "⏸ Setze Monitor auf Wartung..."
|
|
python3 -c "
|
|
from uptime_kuma_api import UptimeKumaApi
|
|
api = UptimeKumaApi('$UPTIME_KUMA_URL')
|
|
api.login('$UPTIME_KUMA_USER', '$UPTIME_KUMA_PASS')
|
|
api.pause_monitor($MONITOR_ID)
|
|
api.disconnect()
|
|
print(' Monitor pausiert')
|
|
" 2>/dev/null || echo " (Uptime Kuma nicht erreichbar, überspringe)"
|
|
fi
|
|
|
|
# 2. Pre-Deploy DB-Snapshot fuer Schnell-Rollback
|
|
echo "💾 Pre-Deploy DB-Backup..."
|
|
ssh "$SERVER" "$REMOTE_DIR/scripts/backup-db.sh" 2>&1 | tail -1
|
|
|
|
# 3. Pull + Build
|
|
echo "🚀 git pull + docker compose up -d --build..."
|
|
ssh "$SERVER" "cd $REMOTE_DIR && git fetch --quiet && git reset --hard origin/$EXPECTED_BRANCH && docker compose up -d --build" 2>&1 | tail -8
|
|
|
|
# 4. Warte auf Health
|
|
echo "⏳ Warte auf Health-Check..."
|
|
for i in $(seq 1 60); do
|
|
response=$(curl -sS --max-time 3 "$PUBLIC_URL/health" 2>/dev/null || echo "")
|
|
if echo "$response" | grep -q '"status":"ok"'; then
|
|
version=$(echo "$response" | python3 -c "import json,sys; print(json.load(sys.stdin).get('version','?'))" 2>/dev/null || echo "?")
|
|
echo "✅ Health OK nach ${i}s — version $version"
|
|
break
|
|
fi
|
|
sleep 1
|
|
if [ "$i" = "60" ]; then
|
|
echo "✗ Health-Check nach 60s nicht OK — pruefe Logs:"
|
|
echo " ssh $SERVER 'docker logs gwoe-antragspruefer --tail 50'"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# 5. Uptime Kuma reaktivieren
|
|
if [ -n "${UPTIME_KUMA_USER:-}" ] && [ -n "${UPTIME_KUMA_PASS:-}" ]; then
|
|
echo "▶ Reaktiviere Monitor..."
|
|
python3 -c "
|
|
from uptime_kuma_api import UptimeKumaApi
|
|
api = UptimeKumaApi('$UPTIME_KUMA_URL')
|
|
api.login('$UPTIME_KUMA_USER', '$UPTIME_KUMA_PASS')
|
|
api.resume_monitor($MONITOR_ID)
|
|
api.disconnect()
|
|
print(' Monitor aktiv')
|
|
" 2>/dev/null || echo " (Uptime Kuma nicht erreichbar)"
|
|
fi
|
|
|
|
echo "=== Deploy abgeschlossen ==="
|