diff --git a/scripts/update.sh b/scripts/update.sh index 3d92338..da78ef5 100644 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -1,20 +1,33 @@ #!/usr/bin/env bash set -euo pipefail -# -------- Konfiguration -------- +# -------- Konfiguration ------------------------------------------------------- APP_USER="${APP_USER:-mailwolt}" +APP_GROUP="${APP_GROUP:-www-data}" # Fallback; setz das in deiner Umgebung falls anders APP_DIR="${APP_DIR:-/var/www/mailwolt}" -BRANCH="${BRANCH:-main}" # nur relevant bei UPDATE_MODE=branch -MODE="${UPDATE_MODE:-tags}" # tags | branch -ALLOW_DIRTY="${ALLOW_DIRTY:-0}" # 1 = Dirty-Working-Tree zulassen +BRANCH="${BRANCH:-main}" # nur relevant bei UPDATE_MODE=branch +MODE="${UPDATE_MODE:-tags}" # tags | branch +ALLOW_DIRTY="${ALLOW_DIRTY:-0}" # 1 = Dirty-Working-Tree zulassen + +# npm / CI Defaults für weniger Lärm export CI=1 export NPM_CONFIG_FUND=false export NPM_CONFIG_AUDIT=false +export npm_config_loglevel=warn -# -------- Helper -------- +# -------- Helper -------------------------------------------------------------- as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } -restart_if_exists(){ local u="$1"; systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true; } -reload_if_active(){ local u="$1"; systemctl is-active --quiet "$u" && systemctl reload "$u" || true; } + +restart_if_exists(){ + local u="$1" + systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true +} + +reload_if_active(){ + local u="$1" + systemctl is-active --quiet "$u" && systemctl reload "$u" || true +} + restart_php_fpm(){ for u in php8.3-fpm php8.2-fpm php8.1-fpm php-fpm; do if systemctl list-unit-files | grep -q "^${u}\.service"; then @@ -25,7 +38,7 @@ restart_php_fpm(){ } git_safe(){ - # Falls nötig: Repo als safe markieren (manche Root-Umgebungen meckern sonst) + # Falls nötig: Repo als safe markieren (z.B. wenn Root den Wrapper aufruft) as_app "git -C ${APP_DIR} config --global --add safe.directory ${APP_DIR} >/dev/null 2>&1 || true" } @@ -46,16 +59,64 @@ get_version(){ write_build_info(){ local ver="$1" rev="$2" + install -d -m 0755 /etc/mailwolt || true printf "version=%s\nrev=%s\nupdated=%s\n" "$ver" "$rev" "$(date -Is)" > /etc/mailwolt/build.info || true } -# -------- Guards -------- +# --- Frontend build (quiet & robust) ------------------------------------------ +frontend_build_quiet() { + local LOG="/var/log/mailwolt-frontend-build.log" + local NPM_ENV="CI=1 NPM_CONFIG_FUND=false NPM_CONFIG_AUDIT=false npm_config_loglevel=warn" + + # Logfile vorbereiten + install -d -m 0755 "$(dirname "$LOG")" + : > "$LOG" || true + chmod 0644 "$LOG" + + echo "[i] Frontend: vorbereiten …" + # Build-Ziele & Temp besitzbar machen + as_app "mkdir -p '${APP_DIR}/public/build' '${APP_DIR}/node_modules' '${APP_DIR}/.vite' '${APP_DIR}/.npm-cache'" + chown -R "$APP_USER":"$APP_GROUP" "${APP_DIR}/public/build" "${APP_DIR}/node_modules" "${APP_DIR}/.vite" "${APP_DIR}/.npm-cache" || true + chmod -R g+rwX "${APP_DIR}/public/build" "${APP_DIR}/node_modules" "${APP_DIR}/.vite" || true + + # evtl. störrische Reste entfernen (vermeidet EACCES beim Unlink/Rimraf) + rm -rf "${APP_DIR}/node_modules/.vite" "${APP_DIR}/public/build/"* 2>/dev/null || true + + # npm Config (kein Fund/Audit, eigener Cache unter App-User) + as_app "printf 'fund=false\naudit=false\ncache=${APP_DIR}/.npm-cache\n' > ~/.npmrc" >>"$LOG" 2>&1 || true + + echo "[i] Frontend: Dependencies … (Details: $LOG)" + if ! as_app "cd '${APP_DIR}' && ${NPM_ENV} npm ci --no-audit --no-fund --no-progress" >>"$LOG" 2>&1; then + if ! as_app "cd '${APP_DIR}' && ${NPM_ENV} npm install --no-audit --no-fund --no-progress" >>"$LOG" 2>&1; then + echo "[!] npm install fehlgeschlagen. Letzte 60 Zeilen:" + tail -n 60 "$LOG" || true + return 1 + fi + fi + + echo "[i] Frontend: Build … (Details: $LOG)" + if ! as_app "cd '${APP_DIR}' && ${NPM_ENV} npm run build --silent --loglevel=warn" >>"$LOG" 2>&1; then + echo "[!] Build fehlgeschlagen. Letzte 80 Zeilen:" + tail -n 80 "$LOG" || true + return 1 + fi + + # Nach dem Build noch einmal Rechte begradigen + chown -R "$APP_USER":"$APP_GROUP" "${APP_DIR}/public/build" || true + find "${APP_DIR}/public/build" -type d -exec chmod 2775 {} \; 2>/dev/null || true + find "${APP_DIR}/public/build" -type f -exec chmod 0664 {} \; 2>/dev/null || true + + echo "[✓] Frontend gebaut." +} + +# -------- Guards -------------------------------------------------------------- [[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } [[ -d "$APP_DIR/.git" ]] || { echo "[!] $APP_DIR scheint kein Git-Repo zu sein"; exit 1; } git_safe git_dirty_check +# -------- Git: neuen Stand holen --------------------------------------------- echo "[i] Prüfe Repository …" OLD_REV="$(as_app "git -C ${APP_DIR} rev-parse HEAD")" OLD_VER="$(get_version)" @@ -64,7 +125,6 @@ NEW_REV="$OLD_REV" if [[ "$MODE" = "tags" ]]; then # → Neueste Tags holen as_app "git -C ${APP_DIR} fetch --quiet origin && git -C ${APP_DIR} fetch --tags --quiet origin || true" - LATEST_TAG="$(as_app "git -C ${APP_DIR} tag --list | sort -V | tail -n1")" if [[ -z "$LATEST_TAG" ]]; then echo "[!] Keine Tags gefunden – falle auf origin/${BRANCH} zurück" @@ -94,7 +154,7 @@ else NEW_REV="$(as_app "git -C ${APP_DIR} rev-parse HEAD")" fi -# -------- Änderungstypen ermitteln -------- +# -------- Änderungstypen ermitteln ------------------------------------------- CHANGED_FILES="$(as_app "git -C ${APP_DIR} diff --name-only ${OLD_REV}..${NEW_REV}")" NEED_COMPOSER=0 @@ -122,7 +182,7 @@ if [[ $NEED_COMPOSER -eq 0 && $NEED_MIGRATIONS -eq 0 && $NEED_FRONTEND -eq 0 && exit 0 fi -# -------- Gezielter Build/Deploy -------- +# -------- Gezielter Build/Deploy --------------------------------------------- if [[ $NEED_COMPOSER -eq 1 ]]; then echo "[i] Composer …" as_app "cd ${APP_DIR} && composer install --no-interaction --prefer-dist --optimize-autoloader" @@ -140,33 +200,16 @@ if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 as_app "cd ${APP_DIR} && php artisan optimize:clear || true" fi -#if [[ $NEED_FRONTEND -eq 1 ]]; then -# echo "[i] Frontend build …" -# as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" -# as_app "cd ${APP_DIR} && npm run build" -#fi - -# -------- Frontend build (hardened) -------- +# -------- Frontend: nur wenn nötig ------------------------------------------- if [[ $NEED_FRONTEND -eq 1 ]]; then - echo "[i] Frontend build (vite) …" - - # Preflight: Schreibrechte sicherstellen - as_app "mkdir -p ${APP_DIR}/public/build ${APP_DIR}/node_modules ${APP_DIR}/.vite" - chown -R "$APP_USER":"$APP_GROUP" "${APP_DIR}/public/build" "${APP_DIR}/node_modules" "${APP_DIR}/.vite" || true - chmod -R g+rwX "${APP_DIR}/public/build" "${APP_DIR}/node_modules" "${APP_DIR}/.vite" || true - - # Nicht-interaktive / leise npm-Runs - NPM_ENV="CI=1 NPM_CONFIG_FUND=false NPM_CONFIG_AUDIT=false npm_config_loglevel=warn" - - echo "[i] npm ci …" - as_app "cd ${APP_DIR} && ${NPM_ENV} npm ci --no-audit --no-fund --loglevel=warn --no-progress || \ - ${NPM_ENV} npm install --no-audit --no-fund --loglevel=warn --no-progress" - - echo "[i] npm run build …" - as_app "cd ${APP_DIR} && ${NPM_ENV} npm run build --silent --loglevel=warn" + echo "[i] Frontend-Änderungen erkannt – baue Assets …" + if ! frontend_build_quiet; then + echo "[!] Frontend-Build ist fehlgeschlagen (siehe /var/log/mailwolt-frontend-build.log)." + exit 1 + fi fi -# -------- Dienste nur wenn nötig -------- +# -------- Dienste nur wenn nötig --------------------------------------------- echo "[i] Dienste neu laden/neustarten (gezielt) …" if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then restart_php_fpm @@ -178,7 +221,7 @@ if [[ $NEED_FRONTEND -eq 1 || $NEED_PHP_RESTART -eq 1 ]]; then reload_if_active nginx fi -# -------- Build-Info ablegen -------- +# -------- Build-Info ablegen -------------------------------------------------- NEW_VER="$(get_version)" write_build_info "$NEW_VER" "$NEW_REV" @@ -188,10 +231,14 @@ echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${ #set -euo pipefail # ## -------- Konfiguration -------- -#APP_USER="mailwolt" -#APP_DIR="/var/www/mailwolt" +#APP_USER="${APP_USER:-mailwolt}" +#APP_DIR="${APP_DIR:-/var/www/mailwolt}" #BRANCH="${BRANCH:-main}" # nur relevant bei UPDATE_MODE=branch #MODE="${UPDATE_MODE:-tags}" # tags | branch +#ALLOW_DIRTY="${ALLOW_DIRTY:-0}" # 1 = Dirty-Working-Tree zulassen +#export CI=1 +#export NPM_CONFIG_FUND=false +#export NPM_CONFIG_AUDIT=false # ## -------- Helper -------- #as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } @@ -206,55 +253,88 @@ echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${ # done #} # +#git_safe(){ +# # Falls nötig: Repo als safe markieren (manche Root-Umgebungen meckern sonst) +# as_app "git -C ${APP_DIR} config --global --add safe.directory ${APP_DIR} >/dev/null 2>&1 || true" +#} +# +#git_dirty_check(){ +# if [[ "$ALLOW_DIRTY" != "1" ]]; then +# local dirty +# dirty="$(as_app "git -C ${APP_DIR} status --porcelain")" +# if [[ -n "$dirty" ]]; then +# echo "[!] Arbeitsbaum hat uncommitted Änderungen. Abbruch (ALLOW_DIRTY=1 zum Überschreiben)." +# exit 2 +# fi +# fi +#} +# +#get_version(){ +# as_app "cd ${APP_DIR} && (git describe --tags --always 2>/dev/null || git rev-parse --short=7 HEAD)" +#} +# +#write_build_info(){ +# local ver="$1" rev="$2" +# printf "version=%s\nrev=%s\nupdated=%s\n" "$ver" "$rev" "$(date -Is)" > /etc/mailwolt/build.info || true +#} +# ## -------- Guards -------- #[[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } #[[ -d "$APP_DIR/.git" ]] || { echo "[!] $APP_DIR scheint kein Git-Repo zu sein"; exit 1; } # +#git_safe +#git_dirty_check +# #echo "[i] Prüfe Repository …" -#OLD_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +#OLD_REV="$(as_app "git -C ${APP_DIR} rev-parse HEAD")" +#OLD_VER="$(get_version)" #NEW_REV="$OLD_REV" # #if [[ "$MODE" = "tags" ]]; then -# # Auf neuesten Release-Tag wechseln (semantisch sortiert) -# LATEST_TAG="$(as_app "cd ${APP_DIR} && git fetch --tags --quiet origin && git tag --list | sort -V | tail -n1")" +# # → Neueste Tags holen +# as_app "git -C ${APP_DIR} fetch --quiet origin && git -C ${APP_DIR} fetch --tags --quiet origin || true" +# +# LATEST_TAG="$(as_app "git -C ${APP_DIR} tag --list | sort -V | tail -n1")" # if [[ -z "$LATEST_TAG" ]]; then # echo "[!] Keine Tags gefunden – falle auf origin/${BRANCH} zurück" -# as_app "cd ${APP_DIR} && git fetch --quiet origin ${BRANCH} && git checkout -q ${BRANCH} && git pull --ff-only origin ${BRANCH}" +# as_app "git -C ${APP_DIR} checkout -q ${BRANCH} && git -C ${APP_DIR} pull --ff-only origin ${BRANCH}" # else -# TARGET_REV="$(as_app "cd ${APP_DIR} && git rev-list -n1 ${LATEST_TAG}")" +# TARGET_REV="$(as_app "git -C ${APP_DIR} rev-list -n1 ${LATEST_TAG}")" # if [[ "$TARGET_REV" = "$OLD_REV" ]]; then # echo "[✓] Bereits auf neuestem Release (${LATEST_TAG}) – nichts zu tun." +# write_build_info "$(get_version)" "$OLD_REV" # exit 0 # fi # echo "[i] Checkout auf Release ${LATEST_TAG} (${TARGET_REV:0:7}) …" -# as_app "cd ${APP_DIR} && git checkout -q ${LATEST_TAG}" +# as_app "git -C ${APP_DIR} checkout -q ${LATEST_TAG}" # fi -# NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +# NEW_REV="$(as_app "git -C ${APP_DIR} rev-parse HEAD")" #else # # Rolling: branch folgen -# as_app "cd ${APP_DIR} && git fetch --quiet origin ${BRANCH}" -# BEHIND="$(as_app "cd ${APP_DIR} && git rev-list --count HEAD..origin/${BRANCH} || echo 0")" +# as_app "git -C ${APP_DIR} fetch --quiet origin ${BRANCH}" +# BEHIND="$(as_app "git -C ${APP_DIR} rev-list --count HEAD..origin/${BRANCH} || echo 0")" # if [[ "$BEHIND" -eq 0 ]]; then # echo "[✓] Branch origin/${BRANCH} ist bereits aktuell – nichts zu tun." +# write_build_info "$(get_version)" "$OLD_REV" # exit 0 # fi # echo "[i] Es gibt ${BEHIND} neue Commit(s) – ziehe Änderungen …" -# as_app "cd ${APP_DIR} && git checkout -q ${BRANCH} && git pull --ff-only origin ${BRANCH}" -# NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +# as_app "git -C ${APP_DIR} checkout -q ${BRANCH} && git -C ${APP_DIR} pull --ff-only origin ${BRANCH}" +# NEW_REV="$(as_app "git -C ${APP_DIR} rev-parse HEAD")" #fi # ## -------- Änderungstypen ermitteln -------- -#CHANGED_FILES="$(as_app "cd ${APP_DIR} && git diff --name-only ${OLD_REV}..${NEW_REV}")" +#CHANGED_FILES="$(as_app "git -C ${APP_DIR} diff --name-only ${OLD_REV}..${NEW_REV}")" # #NEED_COMPOSER=0 #NEED_MIGRATIONS=0 #NEED_FRONTEND=0 #NEED_PHP_RESTART=0 # -#echo "$CHANGED_FILES" | grep -qE '(^|/)composer\.(json|lock)$' && NEED_COMPOSER=1 -#echo "$CHANGED_FILES" | grep -qE '^database/migrations/' && NEED_MIGRATIONS=1 -#echo "$CHANGED_FILES" | grep -qE '^(package(-lock)?\.json|vite\.config|resources/|public/.*\.(js|css))' && NEED_FRONTEND=1 -#echo "$CHANGED_FILES" | grep -qE '^(app/|routes/|config/|resources/views/)' && NEED_PHP_RESTART=1 +#echo "$CHANGED_FILES" | grep -qE '(^|/)composer\.(json|lock)$' && NEED_COMPOSER=1 +#echo "$CHANGED_FILES" | grep -qE '^database/migrations/' && NEED_MIGRATIONS=1 +#echo "$CHANGED_FILES" | grep -qE '^(package(-lock)?\.json|vite\.config(\.ts|\.js)?|resources/|public/.*\.(js|css))' && NEED_FRONTEND=1 +#echo "$CHANGED_FILES" | grep -qE '^(app/|routes/|config/|resources/views/)' && NEED_PHP_RESTART=1 # #echo "[i] Zusammenfassung:" #echo " Composer : $([[ $NEED_COMPOSER -eq 1 ]] && echo JA || echo nein)" @@ -265,9 +345,9 @@ echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${ ## Wenn gar nichts relevantes geändert wurde → sauber beenden #if [[ $NEED_COMPOSER -eq 0 && $NEED_MIGRATIONS -eq 0 && $NEED_FRONTEND -eq 0 && $NEED_PHP_RESTART -eq 0 ]]; then # echo "[✓] Code-Stand aktualisiert, aber keine Build/Runtime-Änderungen – keine Neustarts nötig." -# # Build-Info trotzdem aktualisieren -# INST_VER="$(as_app "cd ${APP_DIR} && (cat VERSION 2>/dev/null || echo dev)")" -# printf "version=%s\nrev=%s\nupdated=%s\n" "$INST_VER" "$NEW_REV" "$(date -Is)" > /etc/mailwolt/build.info || true +# NEW_VER="$(get_version)" +# write_build_info "$NEW_VER" "$NEW_REV" +# echo "[i] Version: ${OLD_VER} → ${NEW_VER}" # exit 0 #fi # @@ -289,10 +369,30 @@ echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${ # as_app "cd ${APP_DIR} && php artisan optimize:clear || true" #fi # +##if [[ $NEED_FRONTEND -eq 1 ]]; then +## echo "[i] Frontend build …" +## as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" +## as_app "cd ${APP_DIR} && npm run build" +##fi +# +## -------- Frontend build (hardened) -------- #if [[ $NEED_FRONTEND -eq 1 ]]; then -# echo "[i] Frontend build …" -# as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" -# as_app "cd ${APP_DIR} && npm run build" +# echo "[i] Frontend build (vite) …" +# +# # Preflight: Schreibrechte sicherstellen +# as_app "mkdir -p ${APP_DIR}/public/build ${APP_DIR}/node_modules ${APP_DIR}/.vite" +# chown -R "$APP_USER":"$APP_GROUP" "${APP_DIR}/public/build" "${APP_DIR}/node_modules" "${APP_DIR}/.vite" || true +# chmod -R g+rwX "${APP_DIR}/public/build" "${APP_DIR}/node_modules" "${APP_DIR}/.vite" || true +# +# # Nicht-interaktive / leise npm-Runs +# NPM_ENV="CI=1 NPM_CONFIG_FUND=false NPM_CONFIG_AUDIT=false npm_config_loglevel=warn" +# +# echo "[i] npm ci …" +# as_app "cd ${APP_DIR} && ${NPM_ENV} npm ci --no-audit --no-fund --loglevel=warn --no-progress || \ +# ${NPM_ENV} npm install --no-audit --no-fund --loglevel=warn --no-progress" +# +# echo "[i] npm run build …" +# as_app "cd ${APP_DIR} && ${NPM_ENV} npm run build --silent --loglevel=warn" #fi # ## -------- Dienste nur wenn nötig -------- @@ -308,179 +408,308 @@ echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${ #fi # ## -------- Build-Info ablegen -------- -#INST_VER="$(as_app "cd ${APP_DIR} && (cat VERSION 2>/dev/null || echo dev)")" -#printf "version=%s\nrev=%s\nupdated=%s\n" "$INST_VER" "$NEW_REV" "$(date -Is)" > /etc/mailwolt/build.info || true +#NEW_VER="$(get_version)" +#write_build_info "$NEW_VER" "$NEW_REV" # -#echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${INST_VER})" - -##!/usr/bin/env bash -#set -euo pipefail +#echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${NEW_VER})" # -#APP_USER="mailwolt" -#APP_DIR="/var/www/mailwolt" -#BRANCH="${BRANCH:-main}" # bei Bedarf anpassen +###!/usr/bin/env bash +##set -euo pipefail +## +### -------- Konfiguration -------- +##APP_USER="mailwolt" +##APP_DIR="/var/www/mailwolt" +##BRANCH="${BRANCH:-main}" # nur relevant bei UPDATE_MODE=branch +##MODE="${UPDATE_MODE:-tags}" # tags | branch +## +### -------- Helper -------- +##as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } +##restart_if_exists(){ local u="$1"; systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true; } +##reload_if_active(){ local u="$1"; systemctl is-active --quiet "$u" && systemctl reload "$u" || true; } +##restart_php_fpm(){ +## for u in php8.3-fpm php8.2-fpm php8.1-fpm php-fpm; do +## if systemctl list-unit-files | grep -q "^${u}\.service"; then +## systemctl restart "$u" +## return 0 +## fi +## done +##} +## +### -------- Guards -------- +##[[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } +##[[ -d "$APP_DIR/.git" ]] || { echo "[!] $APP_DIR scheint kein Git-Repo zu sein"; exit 1; } +## +##echo "[i] Prüfe Repository …" +##OLD_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +##NEW_REV="$OLD_REV" +## +##if [[ "$MODE" = "tags" ]]; then +## # Auf neuesten Release-Tag wechseln (semantisch sortiert) +## LATEST_TAG="$(as_app "cd ${APP_DIR} && git fetch --tags --quiet origin && git tag --list | sort -V | tail -n1")" +## if [[ -z "$LATEST_TAG" ]]; then +## echo "[!] Keine Tags gefunden – falle auf origin/${BRANCH} zurück" +## as_app "cd ${APP_DIR} && git fetch --quiet origin ${BRANCH} && git checkout -q ${BRANCH} && git pull --ff-only origin ${BRANCH}" +## else +## TARGET_REV="$(as_app "cd ${APP_DIR} && git rev-list -n1 ${LATEST_TAG}")" +## if [[ "$TARGET_REV" = "$OLD_REV" ]]; then +## echo "[✓] Bereits auf neuestem Release (${LATEST_TAG}) – nichts zu tun." +## exit 0 +## fi +## echo "[i] Checkout auf Release ${LATEST_TAG} (${TARGET_REV:0:7}) …" +## as_app "cd ${APP_DIR} && git checkout -q ${LATEST_TAG}" +## fi +## NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +##else +## # Rolling: branch folgen +## as_app "cd ${APP_DIR} && git fetch --quiet origin ${BRANCH}" +## BEHIND="$(as_app "cd ${APP_DIR} && git rev-list --count HEAD..origin/${BRANCH} || echo 0")" +## if [[ "$BEHIND" -eq 0 ]]; then +## echo "[✓] Branch origin/${BRANCH} ist bereits aktuell – nichts zu tun." +## exit 0 +## fi +## echo "[i] Es gibt ${BEHIND} neue Commit(s) – ziehe Änderungen …" +## as_app "cd ${APP_DIR} && git checkout -q ${BRANCH} && git pull --ff-only origin ${BRANCH}" +## NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +##fi +## +### -------- Änderungstypen ermitteln -------- +##CHANGED_FILES="$(as_app "cd ${APP_DIR} && git diff --name-only ${OLD_REV}..${NEW_REV}")" +## +##NEED_COMPOSER=0 +##NEED_MIGRATIONS=0 +##NEED_FRONTEND=0 +##NEED_PHP_RESTART=0 +## +##echo "$CHANGED_FILES" | grep -qE '(^|/)composer\.(json|lock)$' && NEED_COMPOSER=1 +##echo "$CHANGED_FILES" | grep -qE '^database/migrations/' && NEED_MIGRATIONS=1 +##echo "$CHANGED_FILES" | grep -qE '^(package(-lock)?\.json|vite\.config|resources/|public/.*\.(js|css))' && NEED_FRONTEND=1 +##echo "$CHANGED_FILES" | grep -qE '^(app/|routes/|config/|resources/views/)' && NEED_PHP_RESTART=1 +## +##echo "[i] Zusammenfassung:" +##echo " Composer : $([[ $NEED_COMPOSER -eq 1 ]] && echo JA || echo nein)" +##echo " Migrations : $([[ $NEED_MIGRATIONS -eq 1 ]] && echo JA || echo nein)" +##echo " Frontend : $([[ $NEED_FRONTEND -eq 1 ]] && echo JA || echo nein)" +##echo " PHP restart : $([[ $NEED_PHP_RESTART -eq 1 ]] && echo JA || echo nein)" +## +### Wenn gar nichts relevantes geändert wurde → sauber beenden +##if [[ $NEED_COMPOSER -eq 0 && $NEED_MIGRATIONS -eq 0 && $NEED_FRONTEND -eq 0 && $NEED_PHP_RESTART -eq 0 ]]; then +## echo "[✓] Code-Stand aktualisiert, aber keine Build/Runtime-Änderungen – keine Neustarts nötig." +## # Build-Info trotzdem aktualisieren +## INST_VER="$(as_app "cd ${APP_DIR} && (cat VERSION 2>/dev/null || echo dev)")" +## printf "version=%s\nrev=%s\nupdated=%s\n" "$INST_VER" "$NEW_REV" "$(date -Is)" > /etc/mailwolt/build.info || true +## exit 0 +##fi +## +### -------- Gezielter Build/Deploy -------- +##if [[ $NEED_COMPOSER -eq 1 ]]; then +## echo "[i] Composer …" +## as_app "cd ${APP_DIR} && composer install --no-interaction --prefer-dist --optimize-autoloader" +##fi +## +##if [[ $NEED_MIGRATIONS -eq 1 ]]; then +## echo "[i] DB-Migrationen …" +## as_app "cd ${APP_DIR} && php artisan migrate --force" +##fi +## +##if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then +## echo "[i] Cache/Optimierungen …" +## as_app "cd ${APP_DIR} && php artisan config:cache && php artisan route:cache || true" +## as_app "cd ${APP_DIR} && php artisan queue:restart || true" +## as_app "cd ${APP_DIR} && php artisan optimize:clear || true" +##fi +## +##if [[ $NEED_FRONTEND -eq 1 ]]; then +## echo "[i] Frontend build …" +## as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" +## as_app "cd ${APP_DIR} && npm run build" +##fi +## +### -------- Dienste nur wenn nötig -------- +##echo "[i] Dienste neu laden/neustarten (gezielt) …" +##if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then +## restart_php_fpm +## restart_if_exists "${APP_USER}-queue" +## restart_if_exists "${APP_USER}-schedule" +## restart_if_exists "${APP_USER}-ws" +##fi +##if [[ $NEED_FRONTEND -eq 1 || $NEED_PHP_RESTART -eq 1 ]]; then +## reload_if_active nginx +##fi +## +### -------- Build-Info ablegen -------- +##INST_VER="$(as_app "cd ${APP_DIR} && (cat VERSION 2>/dev/null || echo dev)")" +##printf "version=%s\nrev=%s\nupdated=%s\n" "$INST_VER" "$NEW_REV" "$(date -Is)" > /etc/mailwolt/build.info || true +## +##echo "[✓] Update abgeschlossen: ${OLD_REV:0:7} → ${NEW_REV:0:7} (Version: ${INST_VER})" # -#as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } +###!/usr/bin/env bash +##set -euo pipefail +## +##APP_USER="mailwolt" +##APP_DIR="/var/www/mailwolt" +##BRANCH="${BRANCH:-main}" # bei Bedarf anpassen +## +##as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } +## +##restart_if_exists(){ local u="$1"; systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true; } +##reload_if_active(){ local u="$1"; systemctl is-active --quiet "$u" && systemctl reload "$u" || true; } +## +##restart_php_fpm(){ +## for u in php8.3-fpm php8.2-fpm php8.1-fpm php-fpm; do +## systemctl list-unit-files | grep -q "^${u}\.service" && { systemctl restart "$u"; return 0; } +## done +## return 0 +##} +## +##[[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } +## +###!/usr/bin/env bash +##set -euo pipefail +##APP_USER="mailwolt" +##APP_DIR="/var/www/mailwolt" +##MODE="${UPDATE_MODE:-tags}" +## +##as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } +## +### --- Ab hier wie gehabt --- +##echo "[i] Prüfe Repository …" +##if [[ "$MODE" = "tags" ]]; then +## LATEST_TAG="$(as_app "cd ${APP_DIR} && git fetch --tags --quiet origin && git tag --list | sort -V | tail -n1")" +## if [[ -n "$LATEST_TAG" ]]; then +## OLD_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +## echo "[i] Checkout auf neuesten Release: ${LATEST_TAG}" +## as_app "cd ${APP_DIR} && git checkout -q ${LATEST_TAG}" +## NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +## else +## echo "[!] Keine Tags gefunden, falle auf origin/main zurück" +## as_app "cd ${APP_DIR} && git pull --ff-only origin main" +## fi +##else +## as_app "cd ${APP_DIR} && git fetch --quiet origin main && git pull --ff-only origin main" +##fi +## +##echo "[i] Prüfe Repository …" +##OLD_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +##as_app "cd ${APP_DIR} && git fetch --tags --quiet origin ${BRANCH}" +##BEHIND="$(as_app "cd ${APP_DIR} && git rev-list --count HEAD..origin/${BRANCH} || echo 0")" +## +##if [[ "${BEHIND}" -eq 0 ]]; then +## echo "[✓] Bereits aktuell – nichts zu tun." +## exit 0 +##fi +## +##echo "[i] Es gibt ${BEHIND} neue Commit(s) – ziehe Änderungen …" +##as_app "cd ${APP_DIR} && git pull --ff-only origin ${BRANCH}" +##NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" +## +### Welche Bereiche haben sich geändert? +##CHANGED_FILES="$(as_app "cd ${APP_DIR} && git diff --name-only ${OLD_REV}..${NEW_REV}")" +## +##NEED_COMPOSER=0 +##NEED_MIGRATIONS=0 +##NEED_FRONTEND=0 +##NEED_PHP_RESTART=0 +## +##if echo "$CHANGED_FILES" | grep -qE '^(composer\.json|composer\.lock)'; then +## NEED_COMPOSER=1 +##fi +##if echo "$CHANGED_FILES" | grep -qE '^database/migrations/'; then +## NEED_MIGRATIONS=1 +##fi +##if echo "$CHANGED_FILES" | grep -qE '^(package(-lock)?\.json|vite\.config\.|resources/|public/.*\.(js|css))'; then +## NEED_FRONTEND=1 +##fi +### PHP-Code/Views/Config geändert? +##if echo "$CHANGED_FILES" | grep -qE '^(app/|routes/|config/|resources/views/)'; then +## NEED_PHP_RESTART=1 +##fi +## +##echo "[i] Zusammenfassung:" +##echo " Composer : $([[ $NEED_COMPOSER -eq 1 ]] && echo JA || echo nein)" +##echo " Migrations : $([[ $NEED_MIGRATIONS -eq 1 ]] && echo JA || echo nein)" +##echo " Frontend : $([[ $NEED_FRONTEND -eq 1 ]] && echo JA || echo nein)" +##echo " PHP restart : $([[ $NEED_PHP_RESTART -eq 1 ]] && echo JA || echo nein)" +## +##echo "[i] Führe Build/Deploy (gezielt) aus …" +##if [[ $NEED_COMPOSER -eq 1 ]]; then +## as_app "cd ${APP_DIR} && composer install --no-interaction --prefer-dist --optimize-autoloader" +##fi +## +##if [[ $NEED_MIGRATIONS -eq 1 ]]; then +## as_app "cd ${APP_DIR} && php artisan migrate --force" +##fi +## +### Cache & Queue nur wenn relevant +##if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then +## as_app "cd ${APP_DIR} && php artisan config:cache && php artisan route:cache || true" +## as_app "cd ${APP_DIR} && php artisan queue:restart || true" +## as_app "cd ${APP_DIR} && php artisan optimize:clear || true" +##fi +## +##if [[ $NEED_FRONTEND -eq 1 ]]; then +## as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" +## as_app "cd ${APP_DIR} && npm run build" +##fi +## +### Dienste nur neu laden/starten wenn nötig +##ANY_RUNTIME_CHANGE=0 +##[[ $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 || $NEED_FRONTEND -eq 1 || $NEED_PHP_RESTART -eq 1 ]] && ANY_RUNTIME_CHANGE=1 +## +##if [[ $ANY_RUNTIME_CHANGE -eq 1 ]]; then +## echo "[i] Dienste neu laden/neustarten (gezielt) …" +## if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then +## restart_php_fpm +## restart_if_exists "${APP_USER}-queue" +## restart_if_exists "${APP_USER}-schedule" +## restart_if_exists "${APP_USER}-ws" +## fi +## # Webserver nur bei Assets/Views/Config +## if [[ $NEED_FRONTEND -eq 1 || $NEED_PHP_RESTART -eq 1 ]]; then +## reload_if_active nginx +## fi +##else +## echo "[i] Nichts zum Updaten." +##fi +## +##echo "[✓] Update auf ${NEW_REV:0:7} abgeschlossen." # -#restart_if_exists(){ local u="$1"; systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true; } -#reload_if_active(){ local u="$1"; systemctl is-active --quiet "$u" && systemctl reload "$u" || true; } -# -#restart_php_fpm(){ -# for u in php8.3-fpm php8.2-fpm php8.1-fpm php-fpm; do -# systemctl list-unit-files | grep -q "^${u}\.service" && { systemctl restart "$u"; return 0; } -# done -# return 0 -#} -# -#[[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } -# -##!/usr/bin/env bash -#set -euo pipefail -#APP_USER="mailwolt" -#APP_DIR="/var/www/mailwolt" -#MODE="${UPDATE_MODE:-tags}" -# -#as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } -# -## --- Ab hier wie gehabt --- -#echo "[i] Prüfe Repository …" -#if [[ "$MODE" = "tags" ]]; then -# LATEST_TAG="$(as_app "cd ${APP_DIR} && git fetch --tags --quiet origin && git tag --list | sort -V | tail -n1")" -# if [[ -n "$LATEST_TAG" ]]; then -# OLD_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" -# echo "[i] Checkout auf neuesten Release: ${LATEST_TAG}" -# as_app "cd ${APP_DIR} && git checkout -q ${LATEST_TAG}" -# NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" -# else -# echo "[!] Keine Tags gefunden, falle auf origin/main zurück" -# as_app "cd ${APP_DIR} && git pull --ff-only origin main" -# fi -#else -# as_app "cd ${APP_DIR} && git fetch --quiet origin main && git pull --ff-only origin main" -#fi -# -#echo "[i] Prüfe Repository …" -#OLD_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" -#as_app "cd ${APP_DIR} && git fetch --tags --quiet origin ${BRANCH}" -#BEHIND="$(as_app "cd ${APP_DIR} && git rev-list --count HEAD..origin/${BRANCH} || echo 0")" -# -#if [[ "${BEHIND}" -eq 0 ]]; then -# echo "[✓] Bereits aktuell – nichts zu tun." -# exit 0 -#fi -# -#echo "[i] Es gibt ${BEHIND} neue Commit(s) – ziehe Änderungen …" -#as_app "cd ${APP_DIR} && git pull --ff-only origin ${BRANCH}" -#NEW_REV="$(as_app "cd ${APP_DIR} && git rev-parse HEAD")" -# -## Welche Bereiche haben sich geändert? -#CHANGED_FILES="$(as_app "cd ${APP_DIR} && git diff --name-only ${OLD_REV}..${NEW_REV}")" -# -#NEED_COMPOSER=0 -#NEED_MIGRATIONS=0 -#NEED_FRONTEND=0 -#NEED_PHP_RESTART=0 -# -#if echo "$CHANGED_FILES" | grep -qE '^(composer\.json|composer\.lock)'; then -# NEED_COMPOSER=1 -#fi -#if echo "$CHANGED_FILES" | grep -qE '^database/migrations/'; then -# NEED_MIGRATIONS=1 -#fi -#if echo "$CHANGED_FILES" | grep -qE '^(package(-lock)?\.json|vite\.config\.|resources/|public/.*\.(js|css))'; then -# NEED_FRONTEND=1 -#fi -## PHP-Code/Views/Config geändert? -#if echo "$CHANGED_FILES" | grep -qE '^(app/|routes/|config/|resources/views/)'; then -# NEED_PHP_RESTART=1 -#fi -# -#echo "[i] Zusammenfassung:" -#echo " Composer : $([[ $NEED_COMPOSER -eq 1 ]] && echo JA || echo nein)" -#echo " Migrations : $([[ $NEED_MIGRATIONS -eq 1 ]] && echo JA || echo nein)" -#echo " Frontend : $([[ $NEED_FRONTEND -eq 1 ]] && echo JA || echo nein)" -#echo " PHP restart : $([[ $NEED_PHP_RESTART -eq 1 ]] && echo JA || echo nein)" -# -#echo "[i] Führe Build/Deploy (gezielt) aus …" -#if [[ $NEED_COMPOSER -eq 1 ]]; then -# as_app "cd ${APP_DIR} && composer install --no-interaction --prefer-dist --optimize-autoloader" -#fi -# -#if [[ $NEED_MIGRATIONS -eq 1 ]]; then -# as_app "cd ${APP_DIR} && php artisan migrate --force" -#fi -# -## Cache & Queue nur wenn relevant -#if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then -# as_app "cd ${APP_DIR} && php artisan config:cache && php artisan route:cache || true" -# as_app "cd ${APP_DIR} && php artisan queue:restart || true" -# as_app "cd ${APP_DIR} && php artisan optimize:clear || true" -#fi -# -#if [[ $NEED_FRONTEND -eq 1 ]]; then -# as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" -# as_app "cd ${APP_DIR} && npm run build" -#fi -# -## Dienste nur neu laden/starten wenn nötig -#ANY_RUNTIME_CHANGE=0 -#[[ $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 || $NEED_FRONTEND -eq 1 || $NEED_PHP_RESTART -eq 1 ]] && ANY_RUNTIME_CHANGE=1 -# -#if [[ $ANY_RUNTIME_CHANGE -eq 1 ]]; then -# echo "[i] Dienste neu laden/neustarten (gezielt) …" -# if [[ $NEED_PHP_RESTART -eq 1 || $NEED_COMPOSER -eq 1 || $NEED_MIGRATIONS -eq 1 ]]; then -# restart_php_fpm -# restart_if_exists "${APP_USER}-queue" -# restart_if_exists "${APP_USER}-schedule" -# restart_if_exists "${APP_USER}-ws" -# fi -# # Webserver nur bei Assets/Views/Config -# if [[ $NEED_FRONTEND -eq 1 || $NEED_PHP_RESTART -eq 1 ]]; then -# reload_if_active nginx -# fi -#else -# echo "[i] Nichts zum Updaten." -#fi -# -#echo "[✓] Update auf ${NEW_REV:0:7} abgeschlossen." - -##!/usr/bin/env bash -#set -euo pipefail -# -#APP_USER="mailwolt" -#APP_DIR="/var/www/mailwolt" -# -#as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } -# -#restart_if_exists(){ local u="$1"; systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true; } -#reload_if_active(){ local u="$1"; systemctl is-active --quiet "$u" && systemctl reload "$u" || true; } -# -#restart_php_fpm(){ -# for u in php8.3-fpm php8.2-fpm php8.1-fpm php-fpm; do -# systemctl list-unit-files | grep -q "^${u}\.service" && { systemctl restart "$u"; return 0; } -# done -# return 0 -#} -# -#[[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } -# -#echo "[i] Code-Update & Build als ${APP_USER} …" -#as_app "cd ${APP_DIR} && git pull --ff-only" -#as_app "cd ${APP_DIR} && composer install --no-interaction --prefer-dist --optimize-autoloader" -#as_app "cd ${APP_DIR} && php artisan migrate --force" -#as_app "cd ${APP_DIR} && php artisan config:cache && php artisan route:cache || true && php artisan queue:restart || true && php artisan optimize:clear" -#as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" -#as_app "cd ${APP_DIR} && npm run build" -# -#echo "[i] Dienste neu laden/neustarten …" -#restart_php_fpm -#restart_if_exists "${APP_USER}-queue" -#restart_if_exists "${APP_USER}-schedule" -#restart_if_exists "${APP_USER}-ws" -#reload_if_active nginx -#reload_if_active opendkim -#reload_if_active postfix -#reload_if_active dovecot -#reload_if_active rspamd -# -#echo "[✓] Update abgeschlossen." \ No newline at end of file +###!/usr/bin/env bash +##set -euo pipefail +## +##APP_USER="mailwolt" +##APP_DIR="/var/www/mailwolt" +## +##as_app(){ sudo -u "$APP_USER" -H bash -lc "$*"; } +## +##restart_if_exists(){ local u="$1"; systemctl list-unit-files | grep -q "^${u}\.service" && systemctl restart "$u" || true; } +##reload_if_active(){ local u="$1"; systemctl is-active --quiet "$u" && systemctl reload "$u" || true; } +## +##restart_php_fpm(){ +## for u in php8.3-fpm php8.2-fpm php8.1-fpm php-fpm; do +## systemctl list-unit-files | grep -q "^${u}\.service" && { systemctl restart "$u"; return 0; } +## done +## return 0 +##} +## +##[[ "$(id -u)" -eq 0 ]] || { echo "[!] Bitte als root ausführen"; exit 1; } +## +##echo "[i] Code-Update & Build als ${APP_USER} …" +##as_app "cd ${APP_DIR} && git pull --ff-only" +##as_app "cd ${APP_DIR} && composer install --no-interaction --prefer-dist --optimize-autoloader" +##as_app "cd ${APP_DIR} && php artisan migrate --force" +##as_app "cd ${APP_DIR} && php artisan config:cache && php artisan route:cache || true && php artisan queue:restart || true && php artisan optimize:clear" +##as_app "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)" +##as_app "cd ${APP_DIR} && npm run build" +## +##echo "[i] Dienste neu laden/neustarten …" +##restart_php_fpm +##restart_if_exists "${APP_USER}-queue" +##restart_if_exists "${APP_USER}-schedule" +##restart_if_exists "${APP_USER}-ws" +##reload_if_active nginx +##reload_if_active opendkim +##reload_if_active postfix +##reload_if_active dovecot +##reload_if_active rspamd +## +##echo "[✓] Update abgeschlossen." \ No newline at end of file