#!/usr/bin/env bash set -euo pipefail repository="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" expected_repository="$HOME/yawn" state_directory="$HOME/.local/state/yawn" deployed_revision_file="$state_directory/deployed-revision" compose=(docker compose --project-name yawn --project-directory "$repository" --file "$repository/compose.yaml") 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 flock; 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 mkdir -p "$state_directory" exec 9>"$state_directory/deploy.lock" if ! flock -n 9; then printf 'Another Yawn deployment is already running.\n' exit 0 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 git fetch origin main remote_revision="$(git rev-parse FETCH_HEAD)" current_revision="$(git rev-parse HEAD)" deployed_revision="" if [[ -f "$deployed_revision_file" ]]; then read -r deployed_revision <"$deployed_revision_file" fi container="$("${compose[@]}" ps -q yawn 2>/dev/null || true)" container_status="missing" if [[ -n "$container" ]]; then container_status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container" 2>/dev/null || true)" fi if [[ "$current_revision" == "$remote_revision" && "$deployed_revision" == "$remote_revision" && "$container_status" == "healthy" ]]; then printf 'Yawn is already running revision %s.\n' "${remote_revision:0:12}" exit 0 fi printf 'Deploying revision %s...\n' "${remote_revision:0:12}" flock -u 9 exec 9>&- "$repository/server/deploy-docker.sh"