#!/usr/bin/env bash # # Update-Skript. # # Holt den Stand aus dem Fork (Remote „origin“) und spielt alles ein, was dazu # nötig ist: Backup, Abhängigkeiten, Image-Neubau bei Bedarf, Migrationen. # # Es gibt derzeit nur die Entwicklungsumgebung und keinen getrennten Produktions- # server; deshalb ist der Fork die Quelle. Der Upstream dient als Backup und zur # Veröffentlichung. Für eine spätere Produktion: UPDATE_REMOTE=upstream setzen. # # ./scripts/update.sh [--no-backup] [--no-tests] [--force-rebuild] set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")/.." OHNE_BACKUP=false OHNE_TESTS=false NEUBAU_ERZWINGEN=false for arg in "$@"; do case "$arg" in --no-backup) OHNE_BACKUP=true ;; --no-tests) OHNE_TESTS=true ;; --force-rebuild) NEUBAU_ERZWINGEN=true ;; --help|-h) echo "Aufruf: $0 [--no-backup] [--no-tests] [--force-rebuild]" exit 0 ;; *) echo "Unbekannte Option: $arg" >&2 exit 1 ;; esac done melde() { printf '\n\033[1m▸ %s\033[0m\n' "$1"; } # ── Backup vor jeder Änderung ─────────────────────────────────────────────── if [[ "$OHNE_BACKUP" == false ]]; then melde "Backup" ./scripts/backup.sh fi # ── Stand aus dem Fork holen ──────────────────────────────────────────────── melde "Code aktualisieren" QUELLE="${UPDATE_REMOTE:-origin}" BRANCH="main" if ! git remote get-url "$QUELLE" >/dev/null 2>&1; then echo "Remote „$QUELLE“ existiert nicht." >&2 exit 1 fi VORHER="$(git rev-parse HEAD)" # Remote und Branch stehen ausdrücklich da, damit kein Tracking nötig ist. # HTTP/1.1, weil Codeberg bei HTTP/2 mit 504 hängen bleibt. git -c http.version=HTTP/1.1 pull --ff-only "$QUELLE" "$BRANCH" NACHHER="$(git rev-parse HEAD)" # Kein vorzeitiger Abbruch bei unverändertem Code: Er kann schon von Hand gezogen worden # sein, dann fehlen den Containern noch die Migrationen (idempotent). Ein Image-Neubau # nach einem von Hand gezogenen Stand muss mit --force-rebuild erzwungen werden. GEAENDERT="$(git diff --name-only "$VORHER" "$NACHHER" || true)" # ── Image neu bauen, wenn sich die Grundlage geändert hat ─────────────────── if [[ "$NEUBAU_ERZWINGEN" == true ]] \ || grep -qE '^(Dockerfile|composer\.(json|lock)|php/|nginx/)' <<<"$GEAENDERT"; then melde "Container-Image neu bauen" docker compose build --pull fi melde "Container starten" docker compose up -d # ── Migrationen ───────────────────────────────────────────────────────────── # Der Entrypoint spielt sie beim Start bereits ein; der zweite Lauf ist # idempotent und macht sichtbar, ob etwas fehlgeschlagen ist. melde "Migrationen" docker compose exec -T php php scripts/migrate.php # ── Berechtigungen ────────────────────────────────────────────────────────── melde "Berechtigungen" docker compose exec -T php chown -R www-data:www-data /var/www/html/data # ── Tests ─────────────────────────────────────────────────────────────────── if [[ "$OHNE_TESTS" == false ]]; then melde "Tests" docker compose exec -u www-data -T php php tests/run.php fi melde "Update abgeschlossen ($(git rev-parse --short HEAD))"