From c349eed49dd0917a069d6b7b11fad6002dcf35a0 Mon Sep 17 00:00:00 2001 From: BuTzZ Date: Wed, 29 Jul 2026 13:21:17 +0200 Subject: [PATCH] Abort stale first deployments --- deploy/README.md | 3 +++ .../scripts/tests/upload-and-deploy.test.sh | 26 +++++++++++++++++++ deploy/scripts/upload-and-deploy.sh | 23 ++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/deploy/README.md b/deploy/README.md index b1425cb..23f1cf5 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -138,6 +138,9 @@ Der Erstlauf wird dafür als begrenzter systemd-Job gestartet; das lokale Upload-Skript wartet über wiederverbindbare SSH-Prüfungen auf exakt den angeforderten Commit. So konkurriert der initiale Aufruf nicht mit dem Auto-Deploy-Timer und ein kurzzeitiger SSH-Abbruch beendet den Import nicht. +Wechselt `origin/main` währenddessen auf einen neueren Commit, beendet das +Upload-Skript nur seinen manuellen Livegang mit einer klaren Meldung; der +systemd-Dienst setzt das automatische Deployment des neuen Stands fort. App und Nginx werden beim ersten Release erst gestartet, wenn sowohl der Routingindex als auch ein nicht leerer, zur PBF-Prüfsumme passender Bestand an Häfen, Schleusen und Brücken geprüft wurde. Ein HTTP-Healthcheck allein kann diff --git a/deploy/scripts/tests/upload-and-deploy.test.sh b/deploy/scripts/tests/upload-and-deploy.test.sh index b76e307..1131ebe 100644 --- a/deploy/scripts/tests/upload-and-deploy.test.sh +++ b/deploy/scripts/tests/upload-and-deploy.test.sh @@ -52,6 +52,9 @@ case "$*" in *"rev-parse HEAD"*) printf '%s\n' "$FAKE_REVISION" ;; + *"ls-remote --exit-code origin refs/heads/main"*) + printf '%s\trefs/heads/main\n' "$FAKE_MAIN_REVISION" + ;; *) printf 'Unerwarteter Git-Aufruf: %s\n' "$*" >&2 exit 90 @@ -92,6 +95,7 @@ output="$( FAKE_CALL_LOG="$FAKE_LOG" \ FAKE_CHECK_COUNT="$CHECK_COUNT" \ FAKE_REVISION="$REVISION" \ + FAKE_MAIN_REVISION="$REVISION" \ WATERMAPS_RELEASE_WAIT_SECONDS=60 \ WATERMAPS_RELEASE_POLL_SECONDS=5 \ "$UPLOAD_SCRIPT" \ @@ -117,4 +121,26 @@ assert_contains \ "$output" assert_contains "sleep|5" "$(<"$FAKE_LOG")" +NEWER_REVISION="4444444444444444444444444444444444444444" +set +e +mismatch_output="$( + PATH="$FAKE_BIN:$PATH" \ + FAKE_CALL_LOG="$FAKE_LOG" \ + FAKE_CHECK_COUNT="$CHECK_COUNT" \ + FAKE_REVISION="$REVISION" \ + FAKE_MAIN_REVISION="$NEWER_REVISION" \ + "$UPLOAD_SCRIPT" \ + --host 203.0.113.10 \ + --identity "$TEST_IDENTITY" \ + 2>&1 +)" +mismatch_status=$? +set -e + +[[ "$mismatch_status" -ne 0 ]] || + fail "Ein nicht veröffentlichter lokaler HEAD wurde für das Deployment akzeptiert." +assert_contains \ + "Lokaler HEAD $REVISION ist nicht der aktuelle origin/main-Commit $NEWER_REVISION." \ + "$mismatch_output" + printf 'Upload/Erstdeployment: systemd-Start und revisionsgenaues Warten: OK\n' diff --git a/deploy/scripts/upload-and-deploy.sh b/deploy/scripts/upload-and-deploy.sh index c573c3f..fc47ade 100755 --- a/deploy/scripts/upload-and-deploy.sh +++ b/deploy/scripts/upload-and-deploy.sh @@ -79,6 +79,24 @@ revision="$(git -C "$WM_ROOT_DIR" rev-parse HEAD)" [[ "$revision" =~ ^[0-9a-f]{40}$ ]] || wm_local_die "Aktueller Git-Commit konnte nicht als vollständige SHA ermittelt werden." +origin_main_revision() { + local main_revision + + main_revision="$( + git -C "$WM_ROOT_DIR" \ + ls-remote --exit-code origin refs/heads/main | + awk 'NR == 1 { print $1 }' + )" + [[ "$main_revision" =~ ^[0-9a-f]{40}$ ]] || + return 1 + printf '%s\n' "$main_revision" +} + +published_revision="$(origin_main_revision)" || + wm_local_die "origin/main konnte nicht revisionsgenau gelesen werden." +[[ "$published_revision" == "$revision" ]] || + wm_local_die "Lokaler HEAD $revision ist nicht der aktuelle origin/main-Commit $published_revision." + set -a # shellcheck disable=SC1090 source "$local_env" @@ -115,6 +133,7 @@ wait_for_remote_release() { local poll_seconds="${WATERMAPS_RELEASE_POLL_SECONDS:-15}" local deadline local attempts=0 + local current_main_revision local remote_check [[ "$timeout_seconds" =~ ^[1-9][0-9]*$ ]] && @@ -142,6 +161,10 @@ wait_for_remote_release() { attempts=$((attempts + 1)) if ((attempts == 1 || attempts % 4 == 0)); then + if current_main_revision="$(origin_main_revision 2>/dev/null)" && + [[ "$current_main_revision" != "$expected_revision" ]]; then + wm_local_die "origin/main wurde während des Erstdeployments von $expected_revision auf $current_main_revision verschoben; starte den Livegang aus dem aktuellen main-Stand erneut." + fi printf '[watermaps] Das revisionsgenaue Erstdeployment läuft unter systemd; warte auf Commit %s …\n' \ "$expected_revision" fi