Files
weirsoe-party-protocol/scripts/run_local_mvp_smoke.sh
Asger Geel Weirsøe a81bc1250c
Some checks failed
CI / test-and-quality (push) Failing after 4m4s
Big visual overhaul docker compsoe file etc
2026-03-23 14:11:30 +01:00

124 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
APP_PORT="${APP_PORT:-8000}"
BASE_URL="${BASE_URL:-http://127.0.0.1:${APP_PORT}}"
USE_SPA_UI="${USE_SPA_UI:-false}"
ALLOW_SPA_CUTOVER="${ALLOW_SPA_CUTOVER:-0}"
KEEP_STACK_RUNNING="${KEEP_STACK_RUNNING:-1}"
BOOTSTRAP_MVP_ARGS="${BOOTSTRAP_MVP_ARGS:-}"
ARTIFACT_DIR="${ARTIFACT_DIR:-${ROOT_DIR}/artifacts/local}"
ARTIFACT_FILE="${ARTIFACT_FILE:-${ARTIFACT_DIR}/smoke-$(date -u +%Y%m%dT%H%M%SZ).json}"
HEALTH_RETRIES="${HEALTH_RETRIES:-60}"
HEALTH_SLEEP_SECONDS="${HEALTH_SLEEP_SECONDS:-2}"
require_command() {
local command_name="$1"
local hint="$2"
if ! command -v "${command_name}" >/dev/null 2>&1; then
echo "[local-smoke] missing command: ${command_name}" >&2
echo "[local-smoke] ${hint}" >&2
exit 1
fi
}
if [[ "${USE_SPA_UI}" == "true" ]] && [[ "${ALLOW_SPA_CUTOVER}" != "1" ]]; then
echo "[local-smoke] USE_SPA_UI=true is outside the canonical MVP smoke path" >&2
echo "[local-smoke] set ALLOW_SPA_CUTOVER=1 only for separate SPA cutover verification" >&2
exit 1
fi
case "${ARTIFACT_FILE}" in
"${ROOT_DIR}"/*) ;;
*)
echo "[local-smoke] ARTIFACT_FILE must live inside ${ROOT_DIR}" >&2
exit 1
;;
esac
require_command "docker" "install Docker Desktop or Docker Engine before running the local smoke flow"
require_command "curl" "install curl so the script can poll the local /healthz endpoint"
mkdir -p "$(dirname "${ARTIFACT_FILE}")"
COMPOSE_CMD=(docker compose)
if [[ "${USE_SPA_UI}" == "true" ]]; then
COMPOSE_CMD+=(--profile spa)
fi
print_failure_context() {
echo "[local-smoke] docker compose state after failure" >&2
(
cd "${ROOT_DIR}"
"${COMPOSE_CMD[@]}" ps >&2 || true
"${COMPOSE_CMD[@]}" logs --tail=80 app db redis >&2 || true
)
}
cleanup() {
local exit_code="$1"
if [[ "${exit_code}" -ne 0 ]]; then
print_failure_context
fi
if [[ "${KEEP_STACK_RUNNING}" != "1" ]]; then
echo "[local-smoke] shutting down docker compose stack"
(
cd "${ROOT_DIR}"
"${COMPOSE_CMD[@]}" down --remove-orphans
)
fi
}
trap 'cleanup "$?"' EXIT
wait_for_healthz() {
local attempt
for ((attempt = 1; attempt <= HEALTH_RETRIES; attempt += 1)); do
if curl -fsS "${BASE_URL}/healthz" >/dev/null; then
echo "[local-smoke] healthz OK"
return 0
fi
echo "[local-smoke] waiting for healthz (${attempt}/${HEALTH_RETRIES})"
sleep "${HEALTH_SLEEP_SECONDS}"
done
echo "[local-smoke] healthz did not become ready: ${BASE_URL}/healthz" >&2
return 1
}
run_compose_exec() {
(
cd "${ROOT_DIR}"
"${COMPOSE_CMD[@]}" exec -T app "$@"
)
}
echo "[local-smoke] starting docker compose stack"
(
cd "${ROOT_DIR}"
export USE_SPA_UI APP_PORT
"${COMPOSE_CMD[@]}" up -d --build
)
wait_for_healthz
echo "[local-smoke] bootstrap MVP host + demo questions"
if [[ -n "${BOOTSTRAP_MVP_ARGS}" ]]; then
# shellcheck disable=SC2206
bootstrap_args=(${BOOTSTRAP_MVP_ARGS})
run_compose_exec python manage.py bootstrap_mvp "${bootstrap_args[@]}"
else
run_compose_exec python manage.py bootstrap_mvp
fi
container_artifact="/app/${ARTIFACT_FILE#${ROOT_DIR}/}"
echo "[local-smoke] gameplay smoke -> ${ARTIFACT_FILE}"
run_compose_exec python manage.py smoke_staging --artifact "${container_artifact}"
echo "[local-smoke] artifact: ${ARTIFACT_FILE}"
if [[ "${KEEP_STACK_RUNNING}" == "1" ]]; then
echo "[local-smoke] stack left running for manual UI follow-up at ${BASE_URL}"
else
echo "[local-smoke] stack will be stopped on exit"
fi