#!/usr/bin/env bash set -euo pipefail sha=${1:?commit SHA required} directory=${2:?deployment directory required} origin=${3:?public origin required} case "$sha" in *[!0-9a-f]*|'') echo 'Invalid image tag' >&2; exit 2 ;; esac case "$directory:$origin" in /opt/personal-website:https://stanrunge.dev) environment=/etc/personal-website/prod.env ;; /opt/personal-website-staging:https://staging.stanrunge.dev) environment=/etc/personal-website-staging/staging.env ;; *) echo 'Unrecognized deployment target' >&2; exit 2 ;; esac image="git.stanrunge.dev/stan/personal-website:$sha" compose="$directory/compose.prod.yml" previous_tag=$(sed -n 's/^IMAGE_TAG=//p' "$directory/.env" | head -n 1) switched=0 rollback() { if [ "$switched" -eq 1 ] && [ -n "$previous_tag" ]; then echo "Health check failed; restoring prior image tag $previous_tag" >&2 printf 'IMAGE_TAG=%s\n' "$previous_tag" | sudo tee "$directory/.env" >/dev/null sudo docker compose --env-file "$directory/.env" -f "$compose" up -d fi } trap rollback ERR sudo docker run --rm --network backend --env-file "$environment" "$image" \ bun scripts/deploy-preflight.ts "$origin" printf 'IMAGE_TAG=%s\n' "$sha" | sudo tee "$directory/.env" >/dev/null switched=1 sudo docker compose --env-file "$directory/.env" -f "$compose" up -d container=$(sudo docker compose --env-file "$directory/.env" -f "$compose" ps -q app) expected_image=$(sudo docker image inspect -f '{{.Id}}' "$image") actual_image=$(sudo docker inspect -f '{{.Image}}' "$container") if [ "$actual_image" != "$expected_image" ]; then echo 'Compose did not start the intended image' >&2 false fi curl --retry 12 --retry-delay 2 --retry-all-errors --fail --silent --show-error \ "$origin/login" >/dev/null curl --retry 6 --retry-delay 2 --retry-all-errors --fail --silent --show-error \ "$origin/projects/catch-em-all" >/dev/null trap - ERR echo "Deployed $sha to $origin"