From 6851e7d4b3e2c631aa896e33c61574f35aeea259 Mon Sep 17 00:00:00 2001 From: fds2610-bot Date: Thu, 23 Jul 2026 19:16:19 +0200 Subject: [PATCH] =?UTF-8?q?update.sh:=20Selbstmodifikation=20w=C3=A4hrend?= =?UTF-8?q?=20der=20Ausf=C3=BChrung=20verhindern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git pull innerhalb des laufenden Skripts konnte die Datei auf der Platte verändern, während Bash sie noch zeilenweise nachlädt - das führte auf einem Zielserver zu einer inkonsistenten Mischung aus alter und neuer Ablauflogik (Tests liefen nach statt vor dem Kopieren, Fehlermeldungen wichen vom tatsächlichen Skriptinhalt ab). Fix: gesamte Logik in main() gekapselt, das erst nach vollständigem Einlesen der Datei aufgerufen wird. Co-Authored-By: Claude Sonnet 5 --- update.sh | 129 +++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/update.sh b/update.sh index 4512a80..28d2ce5 100755 --- a/update.sh +++ b/update.sh @@ -12,66 +12,77 @@ set -euo pipefail -PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -WEBROOT="${WEBROOT:-/var/www/html}" -CONFIG_FILE="${CONFIG_FILE:-$WEBROOT/config.php}" +# Die gesamte Logik steckt bewusst in einer Funktion, die erst ganz am Ende +# der Datei aufgerufen wird: Bash liest eine Funktionsdefinition komplett ein, +# bevor sie ausgeführt wird. Würde der Skriptkörper stattdessen direkt (ohne +# Funktion) ausgeführt, könnte der "git pull" in Schritt 2 die Datei auf der +# Festplatte mitten in der Ausführung verändern - Bash liest dann ab diesem +# Punkt inkonsistente/veraltete Zeilen nach und das Skript verhält sich +# unvorhersehbar (genau das ist ohne dieses main()-Pattern schon passiert). +main() { + PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + WEBROOT="${WEBROOT:-/var/www/html}" + CONFIG_FILE="${CONFIG_FILE:-$WEBROOT/config.php}" + + cd "$PROJECT_DIR" + + command -v php >/dev/null 2>&1 || fail "php ist nicht installiert bzw. nicht im PATH." + [ -d "$WEBROOT" ] || fail "Webroot $WEBROOT existiert nicht." + [ -w "$WEBROOT" ] || fail "Keine Schreibrechte auf $WEBROOT." + + # --- 1. Sicherstellen, dass das Projektverzeichnis sauber ist --- + if ! git diff --quiet || ! git diff --cached --quiet; then + fail "Lokale Änderungen im Projektverzeichnis vorhanden - bitte erst committen oder stashen." + fi + + # --- 2. Neuesten Stand holen --- + log "git pull..." + git pull --ff-only + + # --- 3. PHP-Syntaxcheck als Sicherheitsnetz vor dem Kopieren --- + log "Prüfe PHP-Syntax..." + while IFS= read -r -d '' file; do + php -l "$file" >/dev/null || fail "Syntaxfehler in $file - es wird nichts kopiert." + done < <(find html -name '*.php' -print0) + + # --- 4. Unit-Tests: müssen grün sein, bevor irgendetwas deployt wird --- + if [ -f tests/run.sh ]; then + if [ ! -x vendor/bin/phpunit ]; then + command -v composer >/dev/null 2>&1 || fail "composer ist nicht installiert - wird für die Tests benötigt." + log "Installiere Test-Abhängigkeiten (composer install)..." + composer install --no-interaction --no-progress + fi + log "Führe Tests aus..." + bash tests/run.sh || fail "Tests fehlgeschlagen - es wird nichts deployt. Siehe Ausgabe oben." + else + log "Noch keine Tests vorhanden - werden später ergänzt." + fi + + # --- 5. Dateien kopieren, config.php bleibt unangetastet --- + log "Kopiere Dateien nach $WEBROOT..." + config_backup="" + if [ -f "$CONFIG_FILE" ]; then + config_backup="$(mktemp)" + cp "$CONFIG_FILE" "$config_backup" + fi + + cp -r html/. "$WEBROOT/" + + if [ -n "$config_backup" ]; then + cp "$config_backup" "$CONFIG_FILE" + rm -f "$config_backup" + fi + + # --- 6. Datenbank-Migrationen --- + if [ -d migrations ] && [ -f migrations/run_migrations.php ]; then + log "Wende Datenbank-Migrationen an..." + php migrations/run_migrations.php "$CONFIG_FILE" + fi + + log "Update abgeschlossen." +} log() { echo "==> $*"; } fail() { echo "FEHLER: $*" >&2; exit 1; } -cd "$PROJECT_DIR" - -command -v php >/dev/null 2>&1 || fail "php ist nicht installiert bzw. nicht im PATH." -[ -d "$WEBROOT" ] || fail "Webroot $WEBROOT existiert nicht." -[ -w "$WEBROOT" ] || fail "Keine Schreibrechte auf $WEBROOT." - -# --- 1. Sicherstellen, dass das Projektverzeichnis sauber ist --- -if ! git diff --quiet || ! git diff --cached --quiet; then - fail "Lokale Änderungen im Projektverzeichnis vorhanden - bitte erst committen oder stashen." -fi - -# --- 2. Neuesten Stand holen --- -log "git pull..." -git pull --ff-only - -# --- 3. PHP-Syntaxcheck als Sicherheitsnetz vor dem Kopieren --- -log "Prüfe PHP-Syntax..." -while IFS= read -r -d '' file; do - php -l "$file" >/dev/null || fail "Syntaxfehler in $file - es wird nichts kopiert." -done < <(find html -name '*.php' -print0) - -# --- 4. Unit-Tests: müssen grün sein, bevor irgendetwas deployt wird --- -if [ -f tests/run.sh ]; then - if [ ! -x vendor/bin/phpunit ]; then - command -v composer >/dev/null 2>&1 || fail "composer ist nicht installiert - wird für die Tests benötigt." - log "Installiere Test-Abhängigkeiten (composer install)..." - composer install --no-interaction --no-progress - fi - log "Führe Tests aus..." - bash tests/run.sh || fail "Tests fehlgeschlagen - es wird nichts deployt. Siehe Ausgabe oben." -else - log "Noch keine Tests vorhanden - werden später ergänzt." -fi - -# --- 5. Dateien kopieren, config.php bleibt unangetastet --- -log "Kopiere Dateien nach $WEBROOT..." -config_backup="" -if [ -f "$CONFIG_FILE" ]; then - config_backup="$(mktemp)" - cp "$CONFIG_FILE" "$config_backup" -fi - -cp -r html/. "$WEBROOT/" - -if [ -n "$config_backup" ]; then - cp "$config_backup" "$CONFIG_FILE" - rm -f "$config_backup" -fi - -# --- 6. Datenbank-Migrationen --- -if [ -d migrations ] && [ -f migrations/run_migrations.php ]; then - log "Wende Datenbank-Migrationen an..." - php migrations/run_migrations.php "$CONFIG_FILE" -fi - -log "Update abgeschlossen." +main "$@"