Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 45s
This commit updates the deploy-production.sh script to remove tracked public/data CSV files from the Git index and ensures that backup files are restored correctly, with size verification for integrity. Additionally, it modifies the Navigation.vue component to allow access to the gallery for users with newsletter permissions, enhancing user experience and access control.
399 lines
13 KiB
Bash
Executable File
399 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Immer im Repo-Verzeichnis arbeiten (wichtig für Backup/Restore mit relativen Pfaden)
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# Deployment Script für Harheimer TC Website
|
|
# Sichert Produktivdaten vor dem Build und stellt sie danach wieder her
|
|
|
|
echo "=== Harheimer TC Deployment ==="
|
|
echo ""
|
|
echo "Working directory: $(pwd)"
|
|
echo ""
|
|
|
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
echo "ERROR: Dieses Script muss im Git-Repository ausgeführt werden (kein .git gefunden)."
|
|
exit 1
|
|
fi
|
|
|
|
# Optional (empfohlen): Persistente Daten außerhalb des Git-Repos halten und per Symlink einbinden.
|
|
# Das verhindert zuverlässig, dass Git jemals Produktivdaten überschreibt.
|
|
DEPLOY_HOME="${DEPLOY_HOME:-${HOME:-/tmp}}"
|
|
DATA_ROOT="${DATA_ROOT:-$DEPLOY_HOME/harheimertc-data}"
|
|
BACKUP_ROOT="${BACKUP_ROOT:-$DEPLOY_HOME/harheimertc-backups}"
|
|
|
|
mkdir -p "$DATA_ROOT" "$BACKUP_ROOT"
|
|
|
|
ensure_symlink_dir() {
|
|
local src="$1" # z.B. server/data
|
|
local target="$2" # z.B. /var/lib/harheimertc/server-data
|
|
|
|
mkdir -p "$(dirname "$src")"
|
|
mkdir -p "$target"
|
|
|
|
if [ -L "$src" ]; then
|
|
return 0
|
|
fi
|
|
|
|
if [ -d "$src" ]; then
|
|
echo " Moving $src -> $target (first-time migration)"
|
|
# Merge existing content into target
|
|
cp -a "$src/." "$target/" || true
|
|
rm -rf "$src"
|
|
fi
|
|
|
|
ln -s "$target" "$src"
|
|
echo " Linked $src -> $target"
|
|
}
|
|
|
|
has_tracked_files_under() {
|
|
local prefix="$1" # e.g. public/data
|
|
# If any file is tracked under this path, symlinking the directory will break git operations
|
|
git ls-files "$prefix" | head -n 1 | grep -q .
|
|
}
|
|
|
|
echo "0. Ensuring persistent data directories (recommended)..."
|
|
# IMPORTANT: Only symlink server/data if it's not tracked by git.
|
|
if has_tracked_files_under "server/data"; then
|
|
echo " Skipping symlink for server/data (tracked files detected in git)."
|
|
echo " Recommendation: remove server/data/** from git history and keep them only as production data."
|
|
else
|
|
ensure_symlink_dir "server/data" "$DATA_ROOT/server-data"
|
|
fi
|
|
|
|
# IMPORTANT: Only symlink public/data if it's not tracked by git.
|
|
# Otherwise git will error with "path is beyond a symbolic link".
|
|
if has_tracked_files_under "public/data"; then
|
|
echo " Skipping symlink for public/data (tracked files detected in git)."
|
|
echo " Recommendation: remove public/data/*.csv from git history and keep them only as production data."
|
|
else
|
|
ensure_symlink_dir "public/data" "$DATA_ROOT/public-data"
|
|
fi
|
|
|
|
ensure_symlink_dir "public/uploads" "$DATA_ROOT/public-uploads"
|
|
echo ""
|
|
|
|
# 1. BACKUP: Laufende Produktivdaten VOR allen Git-Operationen sichern
|
|
echo "1. Backing up current production data (pre-git)..."
|
|
|
|
# Human readable timestamp (lokal)
|
|
BACKUP_TS="$(date +"%Y-%m-%d_%H-%M-%S")"
|
|
BACKUP_DIR="$BACKUP_ROOT/backup_$BACKUP_TS"
|
|
mkdir -p "$BACKUP_DIR"
|
|
echo " Backup directory: $BACKUP_DIR"
|
|
|
|
# Backup server data (JSON) und CSVs immer vom Dateisystem, nicht aus 'stash'
|
|
if [ -d server/data ]; then
|
|
cp -a server/data "$BACKUP_DIR/server-data"
|
|
echo " Backed up server/data -> $BACKUP_DIR/server-data"
|
|
else
|
|
echo "ERROR: server/data existiert nicht. Abbruch, damit wir keine Repo-Defaults ausrollen."
|
|
exit 1
|
|
fi
|
|
|
|
if ls public/data/*.csv >/dev/null 2>&1; then
|
|
mkdir -p "$BACKUP_DIR/public-data"
|
|
cp -a public/data/*.csv "$BACKUP_DIR/public-data/"
|
|
echo " Backed up public/data/*.csv -> $BACKUP_DIR/public-data/"
|
|
else
|
|
echo " No public CSVs to backup (public/data/*.csv not found)"
|
|
fi
|
|
|
|
# 2. Handle local changes and Git Pull
|
|
echo "2. Handling local changes and pulling latest from git..."
|
|
|
|
# Check if there are merge conflicts first
|
|
if [ -n "$(git status --porcelain | grep '^UU\|^AA\|^DD')" ]; then
|
|
echo " Resolving existing merge conflicts..."
|
|
git reset --hard HEAD
|
|
fi
|
|
|
|
# Ensure git operations can run even if we have untracked local artifacts (e.g. backups/)
|
|
# We avoid `git stash` (breaks with symlinked tracked paths). Instead, hard-reset and clean safely.
|
|
echo " Resetting working tree to HEAD (production data will be restored from backup)..."
|
|
git reset --hard HEAD
|
|
|
|
echo " Cleaning untracked files (excluding data dirs/backups/.env)..."
|
|
git clean -fd \
|
|
-e server/data \
|
|
-e public/data \
|
|
-e public/uploads \
|
|
-e backups \
|
|
-e .env || true
|
|
|
|
# Pull latest changes
|
|
echo " Pulling latest changes..."
|
|
git pull
|
|
|
|
# Reset any accidental changes from stash restore (should be none now)
|
|
git reset --hard HEAD >/dev/null 2>&1
|
|
|
|
# WICHTIG: Entferne public/data Dateien aus Git-Index, falls sie getrackt sind
|
|
# (Sie sollten in .gitignore sein, aber falls sie historisch getrackt wurden)
|
|
if git ls-files --error-unmatch public/data/*.csv >/dev/null 2>&1; then
|
|
echo " WARNING: public/data/*.csv Dateien sind im Git getrackt!"
|
|
echo " Entferne sie aus dem Git-Index (Dateien bleiben erhalten)..."
|
|
git rm --cached public/data/*.csv 2>/dev/null || true
|
|
fi
|
|
|
|
# 3. Install dependencies
|
|
echo ""
|
|
echo "3. Installing dependencies..."
|
|
npm install
|
|
|
|
# 4. Remove old build (but keep data!)
|
|
echo ""
|
|
echo "4. Cleaning build artifacts..."
|
|
# Sicherstellen, dass .output vollständig gelöscht wird
|
|
if [ -d ".output" ]; then
|
|
echo " Removing .output directory..."
|
|
rm -rf .output
|
|
# Prüfen, ob wirklich gelöscht wurde
|
|
if [ -d ".output" ]; then
|
|
echo "WARNING: .output konnte nicht vollständig gelöscht werden. Versuche erneut..."
|
|
sleep 2
|
|
rm -rf .output
|
|
if [ -d ".output" ]; then
|
|
echo "ERROR: .output konnte auch nach erneutem Versuch nicht gelöscht werden!"
|
|
echo "Bitte manuell prüfen und löschen: rm -rf .output"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo " ✓ .output gelöscht"
|
|
fi
|
|
|
|
# Auch .nuxt Cache löschen für sauberen Build
|
|
if [ -d ".nuxt" ]; then
|
|
echo " Removing .nuxt cache..."
|
|
rm -rf .nuxt
|
|
echo " ✓ .nuxt gelöscht"
|
|
fi
|
|
|
|
# Prüfe, ob node_modules vorhanden ist (für npm run build)
|
|
if [ ! -d "node_modules" ]; then
|
|
echo ""
|
|
echo "WARNING: node_modules fehlt. Installiere Dependencies..."
|
|
npm install
|
|
fi
|
|
|
|
# 5. Build
|
|
echo ""
|
|
echo "5. Building application..."
|
|
echo " Running: npm run build"
|
|
echo " (This may take a few minutes...)"
|
|
|
|
# Clean-Build: Stelle sicher, dass node_modules aktuell ist
|
|
echo " Checking dependencies..."
|
|
if [ ! -f "node_modules/.package-lock.json" ] && [ ! -f "package-lock.json" ]; then
|
|
echo " WARNING: package-lock.json fehlt. Führe npm install aus..."
|
|
npm install
|
|
fi
|
|
|
|
# Build mit expliziter Fehlerbehandlung und Output-Capture
|
|
BUILD_OUTPUT=$(npm run build 2>&1)
|
|
BUILD_EXIT_CODE=$?
|
|
|
|
# Zeige Build-Output
|
|
echo "$BUILD_OUTPUT"
|
|
|
|
if [ "$BUILD_EXIT_CODE" -ne 0 ]; then
|
|
echo ""
|
|
echo "ERROR: Build fehlgeschlagen mit Exit-Code $BUILD_EXIT_CODE"
|
|
echo "Bitte prüfen Sie die Build-Ausgabe oben auf Fehler."
|
|
exit 1
|
|
fi
|
|
|
|
# Prüfe auf Warnungen im Build-Output, die auf Probleme hinweisen
|
|
if echo "$BUILD_OUTPUT" | grep -qi "error\|failed\|missing"; then
|
|
echo ""
|
|
echo "WARNING: Build-Output enthält möglicherweise Fehler oder Warnungen."
|
|
echo "Bitte prüfen Sie die Ausgabe oben."
|
|
fi
|
|
|
|
# Prüfe, ob der Build erfolgreich war - mehrere Checks
|
|
echo ""
|
|
echo " Verifying build output..."
|
|
|
|
BUILD_FAILED=0
|
|
|
|
# Check 1: _nuxt Verzeichnis
|
|
if [ ! -d ".output/public/_nuxt" ]; then
|
|
echo "ERROR: .output/public/_nuxt Verzeichnis fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
NUXT_FILES=$(find .output/public/_nuxt -type f 2>/dev/null | wc -l)
|
|
echo " ✓ .output/public/_nuxt vorhanden ($NUXT_FILES Dateien)"
|
|
if [ "$NUXT_FILES" -eq 0 ]; then
|
|
echo "ERROR: .output/public/_nuxt ist leer!"
|
|
BUILD_FAILED=1
|
|
else
|
|
# Prüfe, ob wichtige Dateien vorhanden sind
|
|
JS_FILES=$(find .output/public/_nuxt -name "*.js" 2>/dev/null | wc -l)
|
|
CSS_FILES=$(find .output/public/_nuxt -name "*.css" 2>/dev/null | wc -l)
|
|
echo " ✓ JS-Dateien: $JS_FILES, CSS-Dateien: $CSS_FILES"
|
|
if [ "$JS_FILES" -eq 0 ]; then
|
|
echo "ERROR: Keine JS-Dateien in .output/public/_nuxt gefunden!"
|
|
BUILD_FAILED=1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Check 1b: _nuxt/builds Verzeichnis (für Meta-Dateien)
|
|
if [ -d ".output/public/_nuxt/builds" ]; then
|
|
BUILD_META_FILES=$(find .output/public/_nuxt/builds -type f 2>/dev/null | wc -l)
|
|
echo " ✓ .output/public/_nuxt/builds vorhanden ($BUILD_META_FILES Meta-Dateien)"
|
|
else
|
|
echo "WARNING: .output/public/_nuxt/builds fehlt (kann in manchen Nuxt-Versionen normal sein)"
|
|
fi
|
|
|
|
# Check 2: Server index.mjs
|
|
if [ ! -f ".output/server/index.mjs" ]; then
|
|
echo "ERROR: .output/server/index.mjs fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
echo " ✓ .output/server/index.mjs vorhanden"
|
|
fi
|
|
|
|
# Check 3: Public Verzeichnis
|
|
if [ ! -d ".output/public" ]; then
|
|
echo "ERROR: .output/public Verzeichnis fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
echo " ✓ .output/public vorhanden"
|
|
fi
|
|
|
|
# Check 4: Server Verzeichnis
|
|
if [ ! -d ".output/server" ]; then
|
|
echo "ERROR: .output/server Verzeichnis fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
echo " ✓ .output/server vorhanden"
|
|
fi
|
|
|
|
if [ "$BUILD_FAILED" -eq 1 ]; then
|
|
echo ""
|
|
echo "ERROR: Build-Verifikation fehlgeschlagen!"
|
|
echo "Bitte führen Sie manuell aus:"
|
|
echo " rm -rf .output .nuxt"
|
|
echo " npm run build"
|
|
exit 1
|
|
fi
|
|
|
|
echo " ✓ Build erfolgreich verifiziert"
|
|
|
|
# 6. Restore Production Data (überschreibe Repo-Defaults mit Backup)
|
|
echo ""
|
|
echo "6. Restoring production data..."
|
|
|
|
# Stelle server/data vollständig wieder her (inkl. config.json, users.json, news.json, sessions.json, members.json, membership-applications)
|
|
if [ ! -d "$BACKUP_DIR/server-data" ]; then
|
|
echo "ERROR: Backup-Verzeichnis $BACKUP_DIR/server-data fehlt. Abbruch."
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p server/data
|
|
cp -a "$BACKUP_DIR/server-data/." server/data/
|
|
echo " Restored server/data from backup ($BACKUP_DIR/server-data)."
|
|
|
|
# Stelle alle CSVs wieder her
|
|
if ls "$BACKUP_DIR/public-data"/*.csv >/dev/null 2>&1; then
|
|
mkdir -p public/data
|
|
|
|
# WICHTIG: Überschreibe auch Dateien, die aus dem Git-Repository kommen
|
|
# Verwende cp mit -f (force) um sicherzustellen, dass Backup-Dateien Vorrang haben
|
|
for csv_file in "$BACKUP_DIR/public-data"/*.csv; do
|
|
filename=$(basename "$csv_file")
|
|
# Überschreibe explizit, auch wenn Datei bereits existiert
|
|
cp -f "$csv_file" "public/data/$filename"
|
|
# Stelle sicher, dass die Datei wirklich überschrieben wurde
|
|
if [ -f "public/data/$filename" ]; then
|
|
# Prüfe, ob die Datei wirklich vom Backup kommt (Größenvergleich)
|
|
backup_size=$(stat -f%z "$csv_file" 2>/dev/null || stat -c%s "$csv_file" 2>/dev/null || echo "0")
|
|
restored_size=$(stat -f%z "public/data/$filename" 2>/dev/null || stat -c%s "public/data/$filename" 2>/dev/null || echo "0")
|
|
if [ "$backup_size" = "$restored_size" ] && [ "$backup_size" != "0" ]; then
|
|
echo " ✓ Restored public/data/$filename from backup ($backup_size bytes)"
|
|
else
|
|
echo " ⚠ WARNING: public/data/$filename Größe stimmt nicht überein (Backup: $backup_size, Restored: $restored_size)"
|
|
fi
|
|
else
|
|
echo " ❌ ERROR: Konnte public/data/$filename nicht wiederherstellen!"
|
|
fi
|
|
done
|
|
|
|
echo " ✓ All public/data/*.csv files restored from backup ($BACKUP_DIR/public-data)."
|
|
|
|
# Zusätzliche Sicherheit: Entferne public/data Dateien aus Git-Index, falls sie getrackt sind
|
|
# (nach dem Restore, damit sie nicht beim nächsten git reset überschrieben werden)
|
|
if git ls-files --error-unmatch public/data/*.csv >/dev/null 2>&1; then
|
|
echo " WARNING: public/data/*.csv Dateien sind noch im Git getrackt!"
|
|
echo " Entferne sie aus dem Git-Index (Dateien bleiben erhalten)..."
|
|
git rm --cached public/data/*.csv 2>/dev/null || true
|
|
echo " ✓ public/data/*.csv aus Git-Index entfernt"
|
|
fi
|
|
else
|
|
echo " No public CSVs to restore"
|
|
fi
|
|
|
|
# Sanity Check: users.json muss existieren und darf nicht leer sein
|
|
if [ ! -s server/data/users.json ]; then
|
|
echo "ERROR: server/data/users.json fehlt oder ist leer nach Restore. Abbruch."
|
|
exit 1
|
|
fi
|
|
|
|
# 7. Cleanup (Backups werden bewusst behalten)
|
|
echo ""
|
|
echo "7. Keeping backups in $BACKUP_ROOT (no git stash used)."
|
|
|
|
# 8. Restart PM2
|
|
echo ""
|
|
echo "8. Restarting PM2..."
|
|
|
|
# Prüfe, ob PM2 installiert ist
|
|
if ! command -v pm2 &> /dev/null; then
|
|
echo "ERROR: PM2 ist nicht installiert oder nicht im PATH!"
|
|
echo "Bitte installieren Sie PM2: npm install -g pm2"
|
|
exit 1
|
|
fi
|
|
|
|
# Prüfe, ob der Prozess existiert
|
|
if ! pm2 describe harheimertc &> /dev/null; then
|
|
echo "WARNING: PM2-Prozess 'harheimertc' existiert nicht."
|
|
echo "Versuche, den Prozess zu starten..."
|
|
pm2 start harheimertc.config.cjs --update-env || pm2 start harheimertc.simple.cjs --update-env || {
|
|
echo "ERROR: Konnte PM2-Prozess nicht starten."
|
|
echo "Bitte manuell starten: pm2 start harheimertc.config.cjs"
|
|
exit 1
|
|
}
|
|
echo " ✓ PM2-Prozess gestartet"
|
|
else
|
|
# Restart mit --update-env, um Umgebungsvariablen zu aktualisieren
|
|
echo " Restarting harheimertc with --update-env..."
|
|
if pm2 restart harheimertc --update-env; then
|
|
echo " ✓ PM2-Prozess neu gestartet"
|
|
else
|
|
echo "ERROR: PM2-Restart fehlgeschlagen!"
|
|
echo "Bitte manuell prüfen: pm2 logs harheimertc"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Prüfe, ob der Prozess läuft
|
|
sleep 2
|
|
if pm2 describe harheimertc | grep -q "online"; then
|
|
echo " ✓ PM2-Prozess läuft (online)"
|
|
else
|
|
echo "WARNING: PM2-Prozess ist nicht online. Prüfe Logs: pm2 logs harheimertc"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Deployment completed successfully! ==="
|
|
echo "The application is now running with the latest code and your production data preserved."
|
|
echo ""
|
|
echo "Useful commands:"
|
|
echo " pm2 logs harheimertc # View logs"
|
|
echo " pm2 status # View status"
|
|
echo " pm2 restart harheimertc # Restart manually"
|
|
|