110 lines
3.3 KiB
Bash
Executable File
110 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set +x
|
|
set -Eeuo pipefail
|
|
umask 077
|
|
|
|
# The only active Pre-Production env source. Never source the checkout's .env.
|
|
ENV_FILE='/home/kai/.config/metalcircle/preprod.env'
|
|
DEPLOYMENT_STARTED=0
|
|
on_error() {
|
|
local status=$?
|
|
if [[ "$DEPLOYMENT_STARTED" == 0 ]]; then
|
|
printf 'Deployment aborted. Running container unchanged.\n' >&2
|
|
else
|
|
printf 'Deployment verification failed after the container update. Manual investigation required.\n' >&2
|
|
fi
|
|
exit "$status"
|
|
}
|
|
trap on_error ERR
|
|
|
|
CHECK_ONLY=0
|
|
if [[ "${1:-}" == '--check' && "$#" == 1 ]]; then
|
|
CHECK_ONLY=1
|
|
elif [[ "$#" != 0 ]]; then
|
|
printf 'Usage: ./scripts/deploy-preprod.sh [--check]\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd -P)"
|
|
cd -- "$REPO_ROOT"
|
|
|
|
if ! TOP_LEVEL="$(git rev-parse --show-toplevel 2>/dev/null)" || [[ "$(cd -- "$TOP_LEVEL" && pwd -P)" != "$REPO_ROOT" ]]; then
|
|
printf 'FEHLER: %s liegt nicht in einem Git-Repository-Checkout.\n' "$REPO_ROOT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
BRANCH="$(git branch --show-current)"
|
|
if [[ "$BRANCH" != "main" ]]; then
|
|
printf 'FEHLER: Deployment ist nur von Branch main erlaubt (aktuell: %s).\n' "${BRANCH:-unbekannt}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
WORKTREE_STATUS="$(git status --porcelain --untracked-files=all)"
|
|
if [[ -n "$WORKTREE_STATUS" ]]; then
|
|
printf 'FEHLER: Working Tree ist nicht sauber. Änderungen zuerst committen oder entfernen.\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$CHECK_ONLY" == 0 ]]; then
|
|
printf 'Aktualisiere main mit Fast-Forward ...\n'
|
|
git pull --ff-only origin main
|
|
fi
|
|
|
|
host_check() {
|
|
python3 "$SCRIPT_DIR/preprod_config.py" --env-file "$ENV_FILE" "$@"
|
|
}
|
|
|
|
compose() {
|
|
# Executes sudo docker compose --env-file "$ENV_FILE" -f compose.yml -f compose.preprod.yml.
|
|
# The helper clears ambient overrides and suppresses secret-bearing raw diagnostics.
|
|
host_check compose "$@"
|
|
}
|
|
|
|
run_preflight() {
|
|
"$@" python push_preflight.py \
|
|
--expected-service-account metalcircle-push-preprod@metalcircle-30d9b.iam.gserviceaccount.com
|
|
"$@" python gitea_preflight.py
|
|
}
|
|
|
|
printf 'Prüfe externe Environment-Datei und Host-Secret ...\n'
|
|
host_check check
|
|
CONFIG_FINGERPRINT="$(host_check fingerprint)"
|
|
printf 'Prüfe Pre-Production-Compose-Konfiguration ...\n'
|
|
compose config --quiet
|
|
|
|
printf 'Baue Web-Image ...\n'
|
|
compose build web
|
|
|
|
printf 'Prüfe Firebase und Gitea im temporären Container ...\n'
|
|
run_preflight compose run --rm --no-deps -T web
|
|
|
|
if [[ "$(host_check fingerprint)" != "$CONFIG_FINGERPRINT" ]]; then
|
|
printf 'ERROR: Environment or Firebase secret changed during deployment. Start again.\n' >&2
|
|
false
|
|
fi
|
|
|
|
if [[ "$CHECK_ONLY" == 1 ]]; then
|
|
printf 'PASS: Pre-Production preflights completed; running container unchanged.\n'
|
|
exit 0
|
|
fi
|
|
|
|
printf 'Sichere geprüfte Environment-Datei außerhalb des Checkouts ...\n'
|
|
host_check backup
|
|
|
|
printf 'Aktualisiere ausschließlich den Webcontainer ...\n'
|
|
DEPLOYMENT_STARTED=1
|
|
compose up -d --no-deps web
|
|
|
|
printf 'Prüfe Firebase und Gitea im laufenden Webcontainer ...\n'
|
|
run_preflight compose exec -T web
|
|
|
|
printf '\nCompose-Status:\n'
|
|
compose ps --format json
|
|
|
|
printf '\nWeb-Logs der letzten 2 Minuten (maximal 100 Zeilen, sicher gefiltert):\n'
|
|
compose logs --since=2m --tail=100 --no-color web
|
|
|
|
printf '\nDeployter Git-Commit:\n'
|
|
git log -1 --format='%h %s'
|