#!/usr/bin/env bash
# Deploy a specific image tag on the target host. Run IN the directory that holds
# docker-compose.yml, docker-compose.prod.yml, and a mode-600 .env with the secrets.
#
# Records the previously-deployed tag (for rollback) and waits for the app to be
# healthy before returning success.
#
# Usage:  IMAGE_TAG=<tag> REGISTRY=<registry> ./deploy.sh
set -euo pipefail

: "${IMAGE_TAG:?IMAGE_TAG is required}"
: "${REGISTRY:?REGISTRY is required}"

COMPOSE=(docker compose -f docker-compose.yml -f docker-compose.prod.yml)
export IMAGE_TAG REGISTRY

# Preserve the currently-deployed tag so rollback has a target.
if [ -f deployed-tag.txt ]; then
  cp deployed-tag.txt previous-tag.txt
fi

echo "==> Pulling ${REGISTRY}:${IMAGE_TAG}"
"${COMPOSE[@]}" pull

echo "==> Starting"
"${COMPOSE[@]}" up -d --remove-orphans

echo "${IMAGE_TAG}" > deployed-tag.txt

echo "==> Waiting for the app to become healthy"
app_container="$("${COMPOSE[@]}" ps -q app)"
for _ in $(seq 1 40); do
  status="$(docker inspect -f '{{.State.Health.Status}}' "$app_container" 2>/dev/null || echo starting)"
  if [ "$status" = "healthy" ]; then
    echo "==> App is healthy (tag ${IMAGE_TAG})"
    exit 0
  fi
  sleep 5
done

echo "ERROR: app did not become healthy in time" >&2
"${COMPOSE[@]}" logs --tail 50 app >&2 || true
exit 1
