#!/usr/bin/env bash set -euo pipefail; repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" export FETCHML_REPO_ROOT="$repo_root" env="${1:-dev}"; if [ "$env" != "dev" ] && [ "$env" != "prod" ]; then echo "usage: $0 [dev|prod]" >&2 exit 2 fi probe_https_health_openssl() { host="$1" port="$2" path="$3" req="GET ${path} HTTP/1.1\r\nHost: ${host}\r\nConnection: close\r\n\r\n" resp=$(printf "%b" "$req" | openssl s_client -connect "127.0.0.1:${port}" -servername "${host}" -tls1_2 -quiet 2>/dev/null || true) printf "%s" "$resp" | tr -d '\r' | head -n 1 | grep -Eq '^HTTP/1\.[01] 200' } compose_cmd="docker-compose"; if ! command -v docker-compose >/dev/null 2>&1; then compose_cmd="docker compose"; fi compose_files=() compose_project_args=("--project-directory" "$repo_root") api_base="" prometheus_base="" stack_name="" api_wait_seconds=90 prometheus_wait_seconds=90 if [ "$env" = "dev" ]; then mkdir -p \ "$repo_root/data/dev/redis" \ "$repo_root/data/dev/minio" \ "$repo_root/data/dev/prometheus" \ "$repo_root/data/dev/grafana" \ "$repo_root/data/dev/loki" \ "$repo_root/data/dev/logs" \ "$repo_root/data/dev/experiments" \ "$repo_root/data/dev/active" \ "$repo_root/data/dev/workspaces" stack_name="dev" api_wait_seconds=180 prometheus_wait_seconds=180 compose_files=("-f" "$repo_root/deployments/docker-compose.dev.yml") api_base="https://localhost:9101" if ! curl -skf "$api_base/health" >/dev/null 2>&1; then api_base="http://localhost:9101" fi prometheus_base="http://localhost:9090" else mkdir -p \ "$repo_root/data/prod-smoke/caddy/data" \ "$repo_root/data/prod-smoke/caddy/config" \ "$repo_root/data/prod-smoke/redis" \ "$repo_root/data/prod-smoke/logs" \ "$repo_root/data/prod-smoke/experiments" \ "$repo_root/data/prod-smoke/active" stack_name="prod" compose_files=("-f" "$repo_root/deployments/docker-compose.prod.smoke.yml") api_base="https://localhost:8443" export FETCHML_DOMAIN=localhost export CADDY_EMAIL=smoke@example.invalid fi cleanup() { status=$?; if [ "$status" -ne 0 ]; then $compose_cmd "${compose_project_args[@]}" "${compose_files[@]}" logs --no-color || true; fi if [ "${KEEP_STACK:-0}" != "1" ]; then $compose_cmd "${compose_project_args[@]}" "${compose_files[@]}" down -v >/dev/null 2>&1 || true; fi exit "$status"; } trap cleanup EXIT; echo "Starting $stack_name stack for smoke test..."; $compose_cmd "${compose_project_args[@]}" "${compose_files[@]}" up -d --build >/dev/null; echo "Waiting for API to become healthy..."; deadline=$(($(date +%s) + $api_wait_seconds)); while true; do if [ "$env" = "dev" ]; then if curl -skf "$api_base/health" >/dev/null 2>&1; then break; fi; else if probe_https_health_openssl "localhost" "8443" "/health"; then break; fi; fi if [ $(date +%s) -ge $deadline ]; then echo "Timed out waiting for $api_base/health"; exit 1; fi; sleep 2; done; if [ "$env" = "dev" ]; then echo "Checking metrics endpoint..."; curl -skf "$api_base/metrics" >/dev/null; echo "Waiting for Prometheus target api-server to be up..."; deadline=$(($(date +%s) + $prometheus_wait_seconds)); query_url="$prometheus_base/api/v1/query?query=up%7Bjob%3D%22api-server%22%7D"; while true; do resp=$(curl -sf "$query_url" || true); resp_compact=$(printf "%s" "$resp" | tr -d '\n' | tr -d '\r'); if echo "$resp_compact" | grep -Fq '"instance":"api-server:9101"' && echo "$resp_compact" | grep -Fq ',"1"]'; then break; fi; if [ $(date +%s) -ge $deadline ]; then echo "Timed out waiting for Prometheus api-server target to be up"; echo "$resp"; exit 1; fi; sleep 2; done; fi