From d753ff11a7ecc5792cfab3ae05886163cd89be52 Mon Sep 17 00:00:00 2001 From: fds2610-bot Date: Sun, 2 Aug 2026 23:03:23 +0200 Subject: [PATCH] Fix #169: update.sh bricht bei rotem Testergebnis ab statt nur zu warnen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Schritt 9/9 setzte bisher nur eine Warnung ab und lief mit Exit-Code 0 weiter, obwohl die neue Version bereits live war. Jetzt zählt auch tests/e2e/run.sh zum Gate (überspringt sich selbst mit Exit 0 ohne Runner), ein Fehlschlag setzt UPDATE_FAILED=true und beendet das Script mit Exit-Code 1. Kein automatischer Rollback – stattdessen ein lauter Hinweis auf das Backup aus Schritt 3 und ./scripts/restore.sh. --no-tests bleibt als Notausstieg bestehen. --- Changes.md | 5 +++ docs/update-backup.md | 28 +++++++++++++--- scripts/update.sh | 77 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 93 insertions(+), 17 deletions(-) diff --git a/Changes.md b/Changes.md index b96d169..4cd7137 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,11 @@ --- +## 2026-08-02 – Testsuite als echtes Gate in update.sh (#169) + +- Schritt 9/9 von `scripts/update.sh` gab bei rotem Testergebnis nur eine Warnung aus – Exit-Code 0, kein Abbruch. Ein Update mit fehlgeschlagenen Tests galt damit als erfolgreich, obwohl die neue Version zu diesem Zeitpunkt bereits live war. +- **`scripts/update.sh`:** Schritt 9 führt jetzt zusätzlich zur PHP-Suite `tests/e2e/run.sh` aus und wertet beide Ergebnisse als Gate: Schlägt eine der beiden Suiten fehl, setzt `UPDATE_FAILED=true` und der Lauf endet mit Exit-Code 1. `tests/e2e/run.sh` überspringt sich selbst mit Exit-Code 0, wenn kein e2e-runner-Projekt bzw. kein Playwright-Image vorhanden ist (Normalfall auf Produktivmaschinen) – das zählt als bestanden, nicht als Fehler; nachgeladen wird nichts. Kein automatischer Rollback (Migrationen sind ggf. nicht rückwärtskompatibel): bei rotem Ergebnis nennt das Script stattdessen laut die Pfade des in Schritt 3 erstellten Backups und den Befehl `./scripts/restore.sh`. `--no-tests` bleibt als dokumentierter Notausstieg bestehen. + ## 2026-08-02 – Aufräumen des verwaisten data/uploads-Verzeichnisses (#173) - Rest aus dem Umzug der Nutzdaten nach `data/` (#150): Ein root-eigenes, leeres `data/uploads` blieb auf Produktivsystemen zurück und lenkte bei der Suche nach Rechteproblemen unter `data/` ab. Weder `docker-compose.yml` noch `docker-entrypoint.sh` legen es an – aktuell wird ausschließlich `data/legacy-uploads` verwendet. diff --git a/docs/update-backup.md b/docs/update-backup.md index 684d0f7..80fd755 100644 --- a/docs/update-backup.md +++ b/docs/update-backup.md @@ -62,14 +62,31 @@ Das Script erledigt in dieser Reihenfolge: 5. **Container-Neustart** – `docker compose down --remove-orphans` + `up -d` 6. **Healthcheck** – Wartet bis die Datenbank `healthy` meldet (max. 120 s) 7. **Migrationen** – `scripts/migrate.php` wird explizit ausgeführt (idempotent) -8. **Tests** – Die Test-Suite wird ausgeführt und das Ergebnis angezeigt +8. **Tests als Gate** – PHP-Suite und `tests/e2e/run.sh` werden ausgeführt; schlägt eine der beiden fehl, endet `update.sh` mit Exit-Code 1 + +### Tests als Gate + +Ein Fehlschlag in Schritt 9 ist kein bloßer Hinweis mehr, sondern bricht das Update +mit Exit-Code 1 ab – die zuvor als „erfolgreich" gemeldete, aber ungeprüfte Version +lief sonst bereits live weiter. Geprüft werden zwei Suiten: + +- **PHP-Suite** (`tests/run.php`) – läuft immer. +- **E2E-Suite** (`tests/e2e/run.sh`) – läuft nur, wenn auf der Maschine ein + e2e-runner-Projekt samt gepulltem Playwright-Image vorhanden ist. Fehlt eines + davon (Normalfall auf Produktivmaschinen), überspringt sich `run.sh` selbst mit + Exit-Code 0 – das zählt als bestanden, `update.sh` lädt dabei nichts nach. + +Es gibt **keinen automatischen Rollback** – Migrationen sind unter Umständen nicht +rückwärtskompatibel. Bei rotem Ergebnis nennt `update.sh` stattdessen laut die +Pfade des in Schritt 3 erstellten Backups und verweist auf `./scripts/restore.sh` +zum manuellen Zurückspielen. ### Optionen | Option | Bedeutung | |---|---| | `--no-backup` | Backup überspringen (z. B. wenn gerade erst gesichert) | -| `--no-tests` | Tests nicht ausführen (schnellerer Ablauf) | +| `--no-tests` | Tests nicht ausführen – dokumentierter Notausstieg; die laufende Version bleibt dann ungeprüft | | `--force-rebuild` | Docker-Image immer neu bauen, unabhängig von Dateiänderungen | ### Migrationen @@ -99,6 +116,9 @@ docker compose logs db # Datenbank-Log Falls ein Update fehlschlägt und ein Rollback nötig ist, das letzte Backup einspielen: ```bash -docker compose exec -T db mariadb -u steuerkram -psteuerkram steuerkram \ - < backups/steuerkram_db_YYYYMMDD_HHMM.sql +./scripts/restore.sh ``` + +Spielt automatisch das neueste vollständige Backup-Paar (DB + Uploads) ein und +führt anschließend ausstehende Migrationen aus. Ein bestimmter Zeitstempel lässt +sich explizit angeben: `./scripts/restore.sh 20260517_134945`. diff --git a/scripts/update.sh b/scripts/update.sh index a485895..145ea83 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -9,7 +9,9 @@ # • Docker-Image-Rebuild (bei Änderungen an Dockerfile, composer.json, etc.) # • Datenbank-Migrationen # • Berechtigungen und Upload-Verzeichnisse -# • Optionale Testausführung +# • Testsuite als Gate: schlägt sie fehl, endet update.sh mit Exit-Code 1 +# und weist laut auf das Backup aus Schritt 3 hin (kein automatischer +# Rollback – Migrationen sind ggf. nicht rückwärtskompatibel) # # Usage: # ./update.sh [--no-backup] [--no-tests] [--force-rebuild] @@ -151,6 +153,11 @@ fi # ════════════════════════════════════════════════════════════════════════════ step "3/9 Backup erstellen" +# Pfade des in diesem Lauf erstellten Backups – falls Schritt 9 die Test-Suite +# rot meldet, werden sie dort als manueller Rollback-Hinweis ausgegeben. +BACKUP_DB_PATH="" +BACKUP_UPLOADS_PATH="" + if [[ "$OPT_NO_BACKUP" == "true" ]]; then warn "Backup übersprungen (--no-backup)" else @@ -159,6 +166,8 @@ else info "Erstelle Backup vor dem Update..." if bash "$PROJECT_DIR/scripts/backup.sh"; then ok "Backup erfolgreich erstellt" + BACKUP_DB_PATH=$(ls -t "$PROJECT_DIR/backups/steuerkram_db_"*.sql 2>/dev/null | head -1) + BACKUP_UPLOADS_PATH=$(ls -t "$PROJECT_DIR/backups/steuerkram_uploads_"*.tar.gz 2>/dev/null | head -1) else warn "Backup fehlgeschlagen – Update wird trotzdem fortgesetzt" warn "Prüfe den Backup-Fehler manuell: ./scripts/backup.sh" @@ -351,25 +360,67 @@ if [[ "$UPDATE_FAILED" == "false" ]]; then fi # ════════════════════════════════════════════════════════════════════════════ -# SCHRITT 9: Tests ausführen +# SCHRITT 9: Tests als Gate # ════════════════════════════════════════════════════════════════════════════ -step "9/9 Tests" +# Ein Fehlschlag hier bricht das Update nicht mehr nur mit einer Warnung ab – +# UPDATE_FAILED=true sorgt über die Zusammenfassung unten für Exit-Code 1. +# Kein automatischer Rollback: Migrationen sind ggf. nicht rückwärtskompatibel, +# darum nur ein lauter Hinweis auf das Backup aus Schritt 3 (siehe #169). +step "9/9 Tests (Gate)" if [[ "$OPT_NO_TESTS" == "true" ]]; then - warn "Tests übersprungen (--no-tests)" + warn "Tests übersprungen (--no-tests) – die laufende Version ist UNGEPRÜFT" else - info "Führe Test-Suite aus..." - if TEST_OUTPUT=$(docker compose exec -T -u www-data web php /var/www/html/tests/run.php 2>&1); then - TEST_EXIT=0 - else - TEST_EXIT=$? - fi + TEST_FAILED=false + info "Führe PHP-Test-Suite aus..." + if TEST_OUTPUT=$(docker compose exec -T -u www-data web php /var/www/html/tests/run.php 2>&1); then + PHP_TEST_EXIT=0 + else + PHP_TEST_EXIT=$? + fi echo "$TEST_OUTPUT" | while read -r line; do info "$line"; done - if [[ "$TEST_EXIT" -ne 0 ]]; then - warn "Einige Tests sind fehlgeschlagen – bitte prüfen" - warn "Vollständiger Testlauf: docker compose exec -u www-data web php tests/run.php" + if [[ "$PHP_TEST_EXIT" -ne 0 ]]; then + fail "PHP-Test-Suite fehlgeschlagen" + TEST_FAILED=true + else + ok "PHP-Test-Suite bestanden" + fi + + # E2E-Suite ist bewusst optional: Ohne e2e-runner-Projekt oder Playwright- + # Image (Normalfall auf einer Produktionsmaschine) überspringt run.sh sich + # selbst mit Exit-Code 0 – das zählt hier als bestanden, nicht als Fehler. + # run.sh lädt dabei nichts nach; das Gate darf das ebenfalls nicht tun. + info "Führe E2E-Test-Suite aus (übersprungen, falls kein Runner vorhanden)..." + if E2E_OUTPUT=$("$PROJECT_DIR/tests/e2e/run.sh" 2>&1); then + E2E_TEST_EXIT=0 + else + E2E_TEST_EXIT=$? + fi + echo "$E2E_OUTPUT" | while read -r line; do info "$line"; done + + if [[ "$E2E_TEST_EXIT" -ne 0 ]]; then + fail "E2E-Test-Suite fehlgeschlagen" + TEST_FAILED=true + else + ok "E2E-Test-Suite bestanden oder übersprungen" + fi + + if [[ "$TEST_FAILED" == "true" ]]; then + UPDATE_FAILED=true + fail "Tests fehlgeschlagen – die aktuell laufende Version ist UNGEPRÜFT" + info "Kein automatischer Rollback (Migrationen sind ggf. nicht rückwärtskompatibel)." + if [[ -n "$BACKUP_DB_PATH" ]]; then + info "Backup von vor diesem Update:" + info " DB: $BACKUP_DB_PATH" + [[ -n "$BACKUP_UPLOADS_PATH" ]] && info " Uploads: $BACKUP_UPLOADS_PATH" + info "Manuell zurückspielen: ./scripts/restore.sh" + else + warn "Kein Backup aus Schritt 3/9 vorhanden (--no-backup gesetzt oder DB war inaktiv)." + fi + info "Vollständiger PHP-Testlauf: docker compose exec -u www-data web php tests/run.php" + info "Vollständiger E2E-Testlauf: tests/e2e/run.sh" else ok "Alle Tests bestanden" fi