#!/usr/bin/env bash set -Eeuo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" UPLOAD_SCRIPT="$ROOT_DIR/deploy/scripts/upload-and-deploy.sh" TEST_ROOT="$(mktemp -d)" FAKE_BIN="$TEST_ROOT/bin" FAKE_LOG="$TEST_ROOT/calls.log" CHECK_COUNT="$TEST_ROOT/release-check-count" TEST_IDENTITY="$TEST_ROOT/deploy-key" REVISION="3333333333333333333333333333333333333333" LOCAL_ENV="$ROOT_DIR/deploy/.env.production" CREATED_LOCAL_ENV=false cleanup() { if [[ "$CREATED_LOCAL_ENV" == "true" && -f "$LOCAL_ENV" ]]; then rm -f -- "$LOCAL_ENV" fi rm -rf -- "$TEST_ROOT" } trap cleanup EXIT mkdir -p "$FAKE_BIN" touch "$FAKE_LOG" "$TEST_IDENTITY" printf '0\n' >"$CHECK_COUNT" if [[ ! -f "$LOCAL_ENV" ]]; then cp "$ROOT_DIR/deploy/.env.production.example" "$LOCAL_ENV" CREATED_LOCAL_ENV=true fi fail() { printf 'Fehler: %s\n' "$*" >&2 exit 1 } assert_contains() { local expected="$1" local actual="$2" grep -Fq -- "$expected" <<<"$actual" || fail "Erwarteter Text fehlt: $expected" } cat >"$FAKE_BIN/git" <<'SH' #!/usr/bin/env bash set -Eeuo pipefail case "$*" in *"status --porcelain --untracked-files=normal"*) exit 0 ;; *"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 ;; esac SH cat >"$FAKE_BIN/rsync" <<'SH' #!/usr/bin/env bash set -Eeuo pipefail printf 'rsync|%s\n' "$*" >>"$FAKE_CALL_LOG" SH cat >"$FAKE_BIN/ssh" <<'SH' #!/usr/bin/env bash set -Eeuo pipefail printf 'ssh|%s\n' "$*" >>"$FAKE_CALL_LOG" if [[ "$*" == *"WATERMAPS_DEPLOY_REVISION=$FAKE_REVISION"* ]]; then count="$(<"$FAKE_CHECK_COUNT")" count=$((count + 1)) printf '%s\n' "$count" >"$FAKE_CHECK_COUNT" ((count >= 2)) fi SH cat >"$FAKE_BIN/sleep" <<'SH' #!/usr/bin/env bash set -Eeuo pipefail printf 'sleep|%s\n' "$*" >>"$FAKE_CALL_LOG" SH chmod 0755 "$FAKE_BIN/"* set +e output="$( PATH="$FAKE_BIN:$PATH" \ 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" \ --host 203.0.113.10 \ --identity "$TEST_IDENTITY" \ --go-live \ 2>&1 )" status=$? set -e [[ "$status" -eq 0 ]] || fail "Upload-Simulation ist fehlgeschlagen: $output" [[ "$(<"$CHECK_COUNT")" == "2" ]] || fail "Der revisionsgenaue Status wurde nicht bis zur Aktivierung erneut geprüft." assert_contains \ "systemctl start --no-block watermaps-auto-deploy.service" \ "$(<"$FAKE_LOG")" assert_contains \ "Das revisionsgenaue Erstdeployment läuft unter systemd" \ "$output" assert_contains \ "Commit $REVISION ist auf dem Server aktiv." \ "$output" assert_contains "sleep|5" "$(<"$FAKE_LOG")" assert_contains \ "WATERMAPS_ENV_FILE=/opt/watermaps/deploy/.env.production WATERMAPS_IMAGES_ENV_FILE=/opt/watermaps/deploy/.env.images /opt/watermaps/current/deploy/scripts/go-live.sh '203.0.113.10'" \ "$(<"$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'