#!/usr/bin/env bash set -euo pipefail repository="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" expected_repository="$HOME/yawn" if [[ "$repository" != "$expected_repository" ]]; then printf 'Expected the repository at %s, found %s\n' "$expected_repository" "$repository" >&2 exit 1 fi for command in git docker; do if ! command -v "$command" >/dev/null 2>&1; then printf 'Missing required command: %s\n' "$command" >&2 exit 1 fi done if ! docker compose version >/dev/null 2>&1; then printf 'Docker Compose v2 is required.\n' >&2 exit 1 fi cd "$repository" if [[ "$(git branch --show-current)" != "main" ]]; then printf 'Deployments must run from the main branch.\n' >&2 exit 1 fi if [[ -n "$(git status --porcelain --untracked-files=normal)" ]]; then printf 'Refusing to deploy a checkout with local changes.\n' >&2 exit 1 fi printf 'Updating main...\n' git fetch origin main fetched="$(git rev-parse FETCH_HEAD)" git merge --ff-only "$fetched" if [[ "$(git rev-parse HEAD)" != "$fetched" ]]; then printf 'HEAD does not match origin/main after updating.\n' >&2 exit 1 fi printf 'Building the production image...\n' docker compose build --pull yawn docker compose up -d --remove-orphans yawn container="$(docker compose ps -q yawn)" if [[ -z "$container" ]]; then printf 'Docker Compose did not create the Yawn container.\n' >&2 exit 1 fi printf 'Waiting for Yawn to become healthy...\n' for _ in {1..60}; do status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container")" case "$status" in healthy) printf 'The Yawn container is healthy.\n' exit 0 ;; unhealthy | exited | dead) docker compose logs --tail 50 yawn >&2 exit 1 ;; esac sleep 2 done printf 'Yawn did not become healthy before the timeout.\n' >&2 docker compose logs --tail 50 yawn >&2 exit 1