#!/usr/bin/env bash # Automatisches Produktions-Deployment für TimeClock. # Dieses Script wird nach einem Push auf main im Checkout auf dem Server ausgeführt. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" REMOTE_NAME="${DEPLOY_REMOTE:-origin}" BRANCH_NAME="${DEPLOY_BRANCH:-main}" PM2_APP="${PM2_APP:-timeclock-backend}" CACHE_DIR=".deploy-cache" fail() { echo "ERROR: $*" >&2 exit 1 } install_dependencies_if_needed() { local directory="$1" local cache_key="$2" local lockfile="$directory/package-lock.json" local hash_file="$CACHE_DIR/${cache_key}-package-lock.sha256" local current_hash="" local previous_hash="" if [ ! -f "$lockfile" ]; then echo "[$directory] package-lock.json fehlt, führe npm install aus" (cd "$directory" && npm install --no-audit --no-fund) return fi current_hash="$(sha256sum "$lockfile" | awk '{print $1}')" previous_hash="$(cat "$hash_file" 2>/dev/null || true)" if [ ! -d "$directory/node_modules" ] || [ "$current_hash" != "$previous_hash" ]; then echo "[$directory] installiere Abhängigkeiten" (cd "$directory" && npm ci --no-audit --no-fund) else echo "[$directory] Abhängigkeiten unverändert" fi printf '%s\n' "$current_hash" > "$hash_file" } echo "=== TimeClock Produktions-Deployment ===" echo "Arbeitsverzeichnis: $SCRIPT_DIR" git rev-parse --is-inside-work-tree >/dev/null 2>&1 \ || fail "Das Script muss im TimeClock-Git-Checkout ausgeführt werden." if [ -n "$(git status --porcelain --untracked-files=no)" ]; then fail "Der Deployment-Checkout enthält lokale Änderungen. Deployment abgebrochen." fi mkdir -p "$CACHE_DIR" echo "Aktualisiere $REMOTE_NAME/$BRANCH_NAME …" git fetch "$REMOTE_NAME" "$BRANCH_NAME" git merge --ff-only "$REMOTE_NAME/$BRANCH_NAME" install_dependencies_if_needed "backend" "backend" install_dependencies_if_needed "frontend" "frontend" echo "Baue Frontend …" (cd frontend && npm run build) echo "Lade PM2-Prozess neu …" if pm2 describe "$PM2_APP" >/dev/null 2>&1; then pm2 reload ecosystem.config.js --only "$PM2_APP" --env production --update-env else pm2 start ecosystem.config.js --only "$PM2_APP" --env production fi pm2 save echo "Deployment erfolgreich abgeschlossen."