Beim Sprung von 1.5.0 auf 1.10.1 endete scripts/update.sh mitten in der Ausgabe. Kein Fehler, keine Zeile, einfach zurueck zur Eingabeaufforderung. Ursache war eine abgeschnittene Leitung: git log --oneline "HEAD..$ZIEL" | head -15 | sed ... head schliesst die Leitung nach 15 Zeilen, git log schreibt weiter und bekommt SIGPIPE (141). Mit "set -o pipefail" gilt die ganze Kette als gescheitert, "set -e" beendet das Skript - stumm. Zeitabhaengig, deshalb monatelang unauffaellig: Solange git log fertig wurde, bevor head zumachte, ging es gut. Die Schwelle liegt exakt bei 15 Commits, und v1.5.0..v1.10.0 waren die ersten 16. Behoben, indem der Erzeuger selbst begrenzt (git log -15) statt die Leitung zu kappen. Dieselbe Behandlung fuer die beiden Tag-Listen. Dieselbe Falle steckte in der Selbstpruefung von sicherung.sh: openssl enc -d ... | head -c 5 | grep -q "PGDMP" Beide Leser schliessen frueh. Bei kleiner Datenbank steht alles im Puffer und es faellt nicht auf; mit wachsender Datenbank kippt es - und dann meldet das Skript eine INTAKTE Sicherung als kaputt und verweigert das Update. Jetzt liest dd eine feste Menge und endet regulaer. Damit so etwas nicht wieder stumm passiert: - Eine ERR-Falle nennt Zeilennummer und Exitcode und erklaert bei 141, dass es SIGPIPE ist und ein Fehler im Skript, nicht beim Benutzer. - Ein Test verbietet "| head" in Skripten mit pipefail und nennt die Zeile. Gegenprobe gemacht: Er schlaegt an. - Bei mehr als 15 Commits steht "... und N weitere" darunter, statt sie wortlos wegzulassen. Nachgestellt: der Ablauf von 1.5.0 auf 1.10.1 laeuft durch.
433 lines
16 KiB
Bash
Executable File
433 lines
16 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Betreuungs-Cockpit aktualisieren.
|
|
#
|
|
# ./scripts/update.sh auf die neueste veroeffentlichte Fassung
|
|
# ./scripts/update.sh v1.2.0 auf eine bestimmte Fassung
|
|
# ./scripts/update.sh --ja ohne Rueckfrage (fuer cron)
|
|
# ./scripts/update.sh --pruefen nur nachsehen, nichts aendern
|
|
# ./scripts/update.sh --verwerfen eigene Aenderungen an versionierten
|
|
# Dateien wegwerfen statt beiseitelegen
|
|
#
|
|
# Was das Skript tut, in dieser Reihenfolge:
|
|
#
|
|
# 1. Voraussetzungen pruefen (Verzeichnis, git, docker, .env)
|
|
# 2. Fassungen holen und vergleichen
|
|
# 3. Zeigen, was sich aendert (Changelog-Abschnitte dazwischen)
|
|
# 4. Nachfragen
|
|
# 5. SICHERUNG anstossen - und abbrechen, wenn sie nicht klappt
|
|
# 6. Eigene Aenderungen beiseitelegen, umschalten, neu bauen, starten
|
|
# 7. Die beiden SQL-Skripte ausfuehren (sie sind idempotent)
|
|
# 8. Pruefen, ob die neue Fassung wirklich laeuft
|
|
#
|
|
# Die Reihenfolge ist Absicht: Bis einschliesslich Schritt 4 wird nichts
|
|
# veraendert. Wer vorher abbricht - oder wobei etwas schiefgeht -, findet
|
|
# alles so vor wie zuvor. Erst danach wird angefasst.
|
|
#
|
|
# Schritt 5 ist der wichtigste: Eine Datenbank-Migration laesst sich nicht
|
|
# zurueckrollen. Ohne Sicherung wird hier nichts aktualisiert.
|
|
#
|
|
# Schritt 7 ebenfalls: Die SQL-Skripte laufen NICHT mit den Migrationen
|
|
# mit. Wer sie vergisst, hat einen veralteten Trigger und merkt es erst,
|
|
# wenn etwas nicht geht.
|
|
#
|
|
# Die .env wird nie angefasst - sie ist nicht versioniert.
|
|
|
|
# Die geschweiften Klammern sorgen dafuer, dass bash die ganze Datei liest,
|
|
# bevor sie irgendetwas ausfuehrt. Ohne sie koennte der git-checkout weiter
|
|
# unten das Skript unter den eigenen Fuessen austauschen.
|
|
{
|
|
set -euo pipefail
|
|
|
|
# --- Ausgabe -----------------------------------------------------------------
|
|
|
|
if [ -t 1 ]; then
|
|
ROT=$'\033[31m'; GRUEN=$'\033[32m'; GELB=$'\033[33m'; FETT=$'\033[1m'; AUS=$'\033[0m'
|
|
else
|
|
ROT=''; GRUEN=''; GELB=''; FETT=''; AUS=''
|
|
fi
|
|
|
|
schritt() { printf '\n%s==> %s%s\n' "$FETT" "$1" "$AUS"; }
|
|
gut() { printf ' %s%s%s\n' "$GRUEN" "$1" "$AUS"; }
|
|
warnung() { printf ' %s%s%s\n' "$GELB" "$1" "$AUS"; }
|
|
abbruch() { printf '\n%sAbbruch: %s%s\n\n' "$ROT" "$1" "$AUS" >&2; exit 1; }
|
|
|
|
# --- Unerwarteter Abbruch ----------------------------------------------------
|
|
#
|
|
# "set -e" beendet das Skript bei jedem Befehl, der nicht 0 zurueckgibt -
|
|
# stumm. Auf dem Bildschirm bricht die Ausgabe dann einfach ab, und man
|
|
# sucht an der falschen Stelle.
|
|
#
|
|
# Genau das ist beim Sprung von v1.5.0 auf v1.10.1 passiert: Eine Leitung
|
|
# der Form "git log ... | head -15" hat den Erzeuger mit SIGPIPE beendet,
|
|
# "pipefail" hat das an die Kette weitergereicht, und das Skript war weg.
|
|
#
|
|
# Diese Falle sagt jetzt wenigstens, WO es passiert ist. Exitcode 141
|
|
# heisst SIGPIPE - dann wurde irgendwo wieder eine Leitung zu frueh
|
|
# geschlossen.
|
|
unerwartet() {
|
|
code=$1
|
|
zeile=$2
|
|
printf '%sAbbruch in Zeile %s (Exitcode %s).%s\n' "$ROT" "$zeile" "$code" "$AUS" >&2
|
|
if [ "$code" = "141" ]; then
|
|
printf '%sExitcode 141 ist SIGPIPE: eine Leitung wurde zu frueh geschlossen,%s\n' "$ROT" "$AUS" >&2
|
|
printf '%setwa durch "| head". Das ist ein Fehler im Skript, nicht bei dir.%s\n' "$ROT" "$AUS" >&2
|
|
fi
|
|
printf '%sKam der Abbruch vor Schritt 5, wurde nichts veraendert.%s\n' "$ROT" "$AUS" >&2
|
|
}
|
|
trap 'unerwartet $? $LINENO' ERR
|
|
|
|
|
|
# --- Aufrufparameter ---------------------------------------------------------
|
|
|
|
ZIEL=""
|
|
OHNE_RUECKFRAGE=0
|
|
NUR_PRUEFEN=0
|
|
OHNE_SICHERUNG=0
|
|
VERWERFEN=0
|
|
ENTSCHEIDUNG=""
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--ja|-j) OHNE_RUECKFRAGE=1 ;;
|
|
--pruefen|-p) NUR_PRUEFEN=1 ;;
|
|
--ohne-sicherung) OHNE_SICHERUNG=1 ;;
|
|
--verwerfen) VERWERFEN=1 ;;
|
|
--hilfe|-h)
|
|
sed -n '2,34p' "$0" | sed 's/^#\s\?//'
|
|
exit 0 ;;
|
|
-*) abbruch "Unbekannte Angabe: $arg (--hilfe zeigt die Moeglichkeiten)" ;;
|
|
*) ZIEL="$arg" ;;
|
|
esac
|
|
done
|
|
|
|
# --- 1. Voraussetzungen ------------------------------------------------------
|
|
|
|
schritt "Voraussetzungen"
|
|
|
|
cd "$(dirname "$0")/.." || abbruch "Das Projektverzeichnis ist nicht erreichbar."
|
|
PROJEKT="$(pwd)"
|
|
|
|
[ -f docker-compose.yml ] || abbruch "Hier liegt keine docker-compose.yml: $PROJEKT"
|
|
[ -f .env ] || abbruch "Es gibt keine .env. Ohne sie startet die Anwendung nicht."
|
|
command -v git >/dev/null || abbruch "git ist nicht installiert."
|
|
docker compose version >/dev/null 2>&1 || abbruch "docker compose (v2) ist nicht verfuegbar."
|
|
|
|
gut "Verzeichnis: $PROJEKT"
|
|
|
|
# Nur nachsehen - angefasst wird die Arbeitskopie erst kurz vor dem
|
|
# Umschalten, wenn Sicherung und Rueckfrage durch sind. Ein Abbruch
|
|
# dazwischen darf keinen Halbzustand hinterlassen.
|
|
SCHMUTZIG=""
|
|
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
|
SCHMUTZIG="ja"
|
|
warnung "Es gibt eigene Aenderungen an versionierten Dateien."
|
|
git status --short --untracked-files=no | sed 's/^/ /'
|
|
printf ' Sie werden vor dem Umschalten beiseite gelegt.\n'
|
|
else
|
|
gut "Arbeitskopie ist sauber"
|
|
fi
|
|
|
|
# --- 2. Was ist da, was kommt ------------------------------------------------
|
|
|
|
schritt "Fassungen"
|
|
|
|
if ! git fetch --tags --quiet origin; then
|
|
abbruch "Konnte die Fassungen nicht vom Server holen.
|
|
Erreichst du ihn? Stimmen die Zugangsdaten?
|
|
Es wurde nichts geaendert."
|
|
fi
|
|
|
|
JETZT="$(git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD)"
|
|
# Kein "| head -1": Siehe den Hinweis zu SIGPIPE weiter unten. Die erste
|
|
# Zeile holt die Shell selbst.
|
|
ALLE_TAGS="$(git tag --list 'v*' --sort=-v:refname)"
|
|
NEUESTE="${ALLE_TAGS%%$'
|
|
'*}"
|
|
|
|
[ -n "$NEUESTE" ] || abbruch "Es gibt keine veroeffentlichte Fassung (kein Tag)."
|
|
|
|
if [ -z "$ZIEL" ]; then
|
|
ZIEL="$NEUESTE"
|
|
fi
|
|
|
|
git rev-parse --verify --quiet "$ZIEL^{commit}" >/dev/null \
|
|
|| abbruch "Die Fassung '$ZIEL' gibt es nicht. Vorhanden:
|
|
$(printf '%s
|
|
' "$ALLE_TAGS" | sed -n '1,5p' | sed 's/^/ /')"
|
|
|
|
printf ' Jetzt: %s\n' "$JETZT"
|
|
printf ' Ziel: %s%s%s\n' "$FETT" "$ZIEL" "$AUS"
|
|
|
|
if [ "$(git rev-parse HEAD)" = "$(git rev-parse "$ZIEL^{commit}")" ]; then
|
|
gut "Bereits auf dem gewuenschten Stand - nichts zu tun."
|
|
exit 0
|
|
fi
|
|
|
|
# --- 3. Was aendert sich -----------------------------------------------------
|
|
|
|
schritt "Was sich aendert"
|
|
|
|
# Der Changelog muss aus der ZIELfassung kommen: Der laufende Stand kennt
|
|
# die neuen Abschnitte ja noch gar nicht.
|
|
CHANGELOG="$(git show "$ZIEL:CHANGELOG.md" 2>/dev/null || true)"
|
|
|
|
if [ -n "$CHANGELOG" ]; then
|
|
# Alle Abschnitte zwischen dem laufenden und dem gewuenschten Stand.
|
|
JETZT_NR="${JETZT#v}"
|
|
printf '%s
|
|
' "$CHANGELOG" | awk -v jetzt="$JETZT_NR" '
|
|
/^## \[/ {
|
|
nummer = $0
|
|
sub(/^## \[/, "", nummer); sub(/\].*/, "", nummer)
|
|
if (nummer == jetzt) exit
|
|
drucken = (nummer != "Unveröffentlicht")
|
|
}
|
|
drucken && zeilen < 60 { print " " $0; zeilen++ }
|
|
'
|
|
else
|
|
warnung "Kein CHANGELOG.md in $ZIEL gefunden."
|
|
fi
|
|
|
|
printf '\n'
|
|
# "-15" statt "| head -15": Bei mehr Commits als der Grenze schliesst head
|
|
# die Leitung, git bekommt SIGPIPE, und mit "set -o pipefail" gilt die ganze
|
|
# Kette als gescheitert - "set -e" beendet das Skript dann OHNE Meldung.
|
|
# Genau das ist beim Sprung von v1.5.0 auf v1.10.1 passiert.
|
|
ANZAHL="$(git rev-list --count "HEAD..$ZIEL")"
|
|
git log --oneline --no-decorate -15 "HEAD..$ZIEL" | sed 's/^/ /'
|
|
if [ "$ANZAHL" -gt 15 ]; then
|
|
printf ' ... und %s weitere
|
|
' "$((ANZAHL - 15))"
|
|
fi
|
|
|
|
if [ "$NUR_PRUEFEN" = "1" ]; then
|
|
printf '\n'
|
|
gut "Nur geprueft - es wurde nichts geaendert."
|
|
[ -n "$SCHMUTZIG" ] && warnung "Beim echten Lauf wuerden deine Aenderungen beiseite gelegt."
|
|
exit 0
|
|
fi
|
|
|
|
# --- 4. Nachfragen -----------------------------------------------------------
|
|
|
|
if [ "$OHNE_RUECKFRAGE" != "1" ]; then
|
|
printf '\n%sJetzt aktualisieren auf %s? [j/N] %s' "$FETT" "$ZIEL" "$AUS"
|
|
read -r antwort </dev/tty || antwort=""
|
|
case "$antwort" in
|
|
[jJ]|[jJ][aA]) ;;
|
|
*) printf '\n'; warnung "Abgebrochen, nichts geaendert."; exit 0 ;;
|
|
esac
|
|
fi
|
|
|
|
# --- 5. Sicherung ------------------------------------------------------------
|
|
|
|
if [ "$OHNE_SICHERUNG" = "1" ]; then
|
|
schritt "Sicherung wird uebersprungen"
|
|
warnung "Auf eigene Gefahr - eine Migration laesst sich nicht zurueckrollen."
|
|
else
|
|
schritt "Sicherung"
|
|
|
|
if docker compose ps --status running --services 2>/dev/null | grep -qx sicherung; then
|
|
if docker compose exec -T sicherung /bin/sh /sicherung.sh; then
|
|
gut "Sicherung angelegt und selbst geprueft."
|
|
else
|
|
abbruch "Die Sicherung ist fehlgeschlagen. Es wird nichts aktualisiert.
|
|
Mit --ohne-sicherung laesst sich das uebergehen - aber ueberleg
|
|
dir das zweimal."
|
|
fi
|
|
else
|
|
warnung "Der Dienst 'sicherung' laeuft nicht - es wurde nichts gesichert."
|
|
if [ "$OHNE_RUECKFRAGE" != "1" ]; then
|
|
printf '\n %sTrotzdem weitermachen? [j/N] %s' "$FETT" "$AUS"
|
|
read -r weiter </dev/tty || weiter=""
|
|
case "$weiter" in [jJ]|[jJ][aA]) ;; *) abbruch "Abgebrochen." ;; esac
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# --- 6. Umschalten und bauen -------------------------------------------------
|
|
|
|
# Aenderungen an versionierten Dateien blockieren das Umschalten.
|
|
#
|
|
# Im Betrieb ist das der Normalfall: Man passt die docker-compose.yml an,
|
|
# bis etwas laeuft. Genau diese Anpassungen sind spaeter oft schon
|
|
# eingearbeitet - das Skript soll sie also nicht zum Hindernis machen.
|
|
#
|
|
# Verworfen wird trotzdem nichts stillschweigend. Standard ist "beiseite
|
|
# legen": git stash macht es rueckholbar. Wer sie wirklich weghaben will,
|
|
# nimmt --verwerfen.
|
|
#
|
|
# Die .env ist nie betroffen - sie ist nicht versioniert.
|
|
schritt "Eigene Aenderungen"
|
|
|
|
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
|
printf '\n Diese versionierten Dateien sind veraendert:\n\n'
|
|
git status --short --untracked-files=no | sed 's/^/ /'
|
|
printf '\n'
|
|
|
|
if [ "$VERWERFEN" = "1" ]; then
|
|
ENTSCHEIDUNG="verwerfen"
|
|
elif [ "$OHNE_RUECKFRAGE" = "1" ]; then
|
|
# Ohne jemanden zum Fragen: die sichere Variante.
|
|
ENTSCHEIDUNG="beiseite"
|
|
else
|
|
printf ' %s[b]%s eiseite legen (git stash, spaeter rueckholbar)\n' "$FETT" "$AUS"
|
|
printf ' %s[v]%s erwerfen (endgueltig weg)\n' "$FETT" "$AUS"
|
|
printf ' %s[a]%s bbrechen\n\n' "$FETT" "$AUS"
|
|
printf ' Was soll damit geschehen? [b/v/a] '
|
|
read -r wahl </dev/tty || wahl=""
|
|
case "$wahl" in
|
|
[bB]|'') ENTSCHEIDUNG="beiseite" ;;
|
|
[vV]) ENTSCHEIDUNG="verwerfen" ;;
|
|
*) abbruch "Abgebrochen, nichts geaendert." ;;
|
|
esac
|
|
fi
|
|
|
|
if [ "$ENTSCHEIDUNG" = "verwerfen" ]; then
|
|
git checkout -- .
|
|
warnung "Aenderungen verworfen."
|
|
else
|
|
STASH_NAME="vor Update $(date +%Y-%m-%d_%H%M)"
|
|
git stash push --quiet --message "$STASH_NAME" -- . \
|
|
|| abbruch "Konnte die Aenderungen nicht beiseite legen."
|
|
gut "Beiseite gelegt als: $STASH_NAME"
|
|
printf ' Ansehen: git stash list\n'
|
|
printf ' Zurueck: git stash pop\n'
|
|
printf ' Wegwerfen: git stash drop\n'
|
|
fi
|
|
else
|
|
gut "Arbeitskopie ist sauber"
|
|
fi
|
|
|
|
schritt "Umschalten auf $ZIEL"
|
|
|
|
# Eine unversionierte Datei kann im Weg stehen, wenn die Zielfassung sie
|
|
# fuehrt. Das passiert beim Update auf die Fassung, die dieses Skript
|
|
# eingefuehrt hat: Man hat es sich von Hand geholt, jetzt gehoert es dazu.
|
|
# Solche Dateien werden nicht weggeworfen, sondern beiseite geschoben.
|
|
if ! git checkout --quiet "$ZIEL" 2>/dev/null; then
|
|
IM_WEG="$(git checkout "$ZIEL" 2>&1 | sed -n '/would be overwritten/,/^Aborting/p' | grep -E '^\s' | tr -d ' ' | grep -v '^$' || true)"
|
|
|
|
if [ -n "$IM_WEG" ]; then
|
|
ZEIT="$(date +%Y%m%d-%H%M%S)"
|
|
printf ' Diese unversionierten Dateien stehen im Weg:
|
|
'
|
|
for datei in $IM_WEG; do
|
|
[ -e "$datei" ] || continue
|
|
mv "$datei" "${datei}.vor-update-${ZEIT}"
|
|
printf ' %s -> %s.vor-update-%s
|
|
' "$datei" "$datei" "$ZEIT"
|
|
done
|
|
git checkout --quiet "$ZIEL" || abbruch "Das Umschalten auf $ZIEL ist fehlgeschlagen.
|
|
Deine Aenderungen liegen im Stash: git stash list"
|
|
else
|
|
abbruch "Das Umschalten auf $ZIEL ist fehlgeschlagen.
|
|
$([ -n "$SCHMUTZIG" ] && printf ' Deine Aenderungen liegen im Stash: git stash list')"
|
|
fi
|
|
fi
|
|
|
|
gut "$(git describe --tags --always)"
|
|
|
|
# Das Ausfuehrbarkeitsbit kommt normalerweise aus dem Repository mit. Wer
|
|
# Dateien von Hand kopiert hat - etwa um an dieses Skript zu kommen, bevor
|
|
# es in der laufenden Fassung existierte -, hat es verloren. Dann waere der
|
|
# naechste Aufruf ein "Permission denied", und man sucht an der falschen
|
|
# Stelle.
|
|
chmod +x scripts/*.sh 2>/dev/null || true
|
|
|
|
schritt "Bauen und starten"
|
|
printf ' Das dauert beim ersten Mal einige Minuten.\n\n'
|
|
|
|
if ! GIT_COMMIT="$(git rev-parse --short HEAD)" \
|
|
BUILD_ZEIT="$(date -Iseconds)" \
|
|
docker compose up -d --build; then
|
|
printf '\n'
|
|
abbruch "Bauen oder Starten ist fehlgeschlagen.
|
|
Die Quellen stehen jetzt auf $ZIEL, die Anwendung laeuft aber
|
|
noch mit dem alten Abbild - oder gar nicht.
|
|
|
|
Zurueck auf den vorherigen Stand:
|
|
git checkout $JETZT && docker compose up -d --build
|
|
$([ -n "$SCHMUTZIG" ] && printf '\n Deine Aenderungen liegen im Stash: git stash list')"
|
|
fi
|
|
|
|
# --- 7. Warten, bis die Anwendung antwortet ----------------------------------
|
|
|
|
schritt "Warten auf die Anwendung"
|
|
|
|
# Adresse und Port stehen in der .env - Standard ist die Loopback-Adresse.
|
|
ADRESSE="$(grep -E '^APP_BIND=' .env | tail -1 | cut -d= -f2- | tr -d '"' || true)"
|
|
PORT="$(grep -E '^APP_PORT=' .env | tail -1 | cut -d= -f2- | tr -d '"' || true)"
|
|
[ -n "$ADRESSE" ] || ADRESSE="127.0.0.1"
|
|
[ -n "$PORT" ] || PORT="3000"
|
|
# Auf 0.0.0.0 kann man nicht zugreifen - dann ueber die Loopback-Adresse.
|
|
[ "$ADRESSE" = "0.0.0.0" ] && ADRESSE="127.0.0.1"
|
|
|
|
GESUND="http://${ADRESSE}:${PORT}/api/gesundheit"
|
|
ANTWORT=""
|
|
|
|
for _ in $(seq 1 60); do
|
|
ANTWORT="$(curl -fsS --max-time 5 "$GESUND" 2>/dev/null || true)"
|
|
case "$ANTWORT" in *'"bereit"'*) break ;; esac
|
|
printf '.'
|
|
sleep 3
|
|
done
|
|
printf '\n'
|
|
|
|
case "$ANTWORT" in
|
|
*'"bereit"'*) gut "Die Anwendung antwortet." ;;
|
|
*)
|
|
printf '\n'
|
|
docker compose logs app --tail 40 | sed 's/^/ /'
|
|
abbruch "Die Anwendung antwortet nicht unter $GESUND.
|
|
Die letzten Zeilen aus dem Log stehen oben.
|
|
Zurueck geht es mit: git checkout $JETZT && docker compose up -d --build"
|
|
;;
|
|
esac
|
|
|
|
# --- 8. SQL-Skripte ----------------------------------------------------------
|
|
|
|
schritt "Volltextsuche und Audit-Schutz"
|
|
printf ' Diese beiden laufen nicht mit den Migrationen mit.\n'
|
|
printf ' Sie sind idempotent - mehrfaches Ausfuehren schadet nicht.\n\n'
|
|
|
|
PRISMA="node node_modules/prisma/build/index.js"
|
|
|
|
for skript in volltextsuche audit-schutz; do
|
|
if docker compose exec -T app $PRISMA db execute \
|
|
--schema prisma/schema.prisma --file "prisma/sql/${skript}.sql" >/dev/null 2>&1; then
|
|
gut "${skript}.sql ausgefuehrt"
|
|
else
|
|
warnung "${skript}.sql ist fehlgeschlagen - bitte von Hand nachholen:"
|
|
printf ' docker compose exec app %s db execute \\\n' "$PRISMA"
|
|
printf ' --schema prisma/schema.prisma --file prisma/sql/%s.sql\n' "$skript"
|
|
fi
|
|
done
|
|
|
|
# --- 9. Nachschau ------------------------------------------------------------
|
|
|
|
schritt "Ergebnis"
|
|
|
|
LAEUFT="$(printf '%s' "$ANTWORT" | sed -n 's/.*"version":"\([^"]*\)".*/\1/p')"
|
|
ERWARTET="${ZIEL#v}"
|
|
|
|
printf ' Erwartet: %s\n' "$ERWARTET"
|
|
printf ' Laeuft: %s\n' "${LAEUFT:-unbekannt}"
|
|
|
|
if [ "$LAEUFT" = "$ERWARTET" ]; then
|
|
printf '\n'
|
|
gut "Fertig. Version $ERWARTET laeuft."
|
|
else
|
|
printf '\n'
|
|
warnung "Die laufende Fassung stimmt nicht mit der erwarteten ueberein."
|
|
warnung "Vermutlich hat der Bau den alten Behaelter stehen lassen:"
|
|
printf ' docker compose up -d --build --force-recreate app\n'
|
|
fi
|
|
|
|
printf '\n Zustand: docker compose ps\n'
|
|
printf ' Log: docker compose logs app --tail 50\n'
|
|
printf ' Zurueck: git checkout %s && docker compose up -d --build\n\n' "$JETZT"
|
|
|
|
exit 0
|
|
}
|