Files
my-protfolio/scripts/deploy-release.sh

34 lines
1.5 KiB
Bash

#!/usr/bin/env bash
set -Eeuo pipefail
deploy_root="${1:?deployment checkout is required}"
revision="${2:?commit SHA is required}"
[[ "$deploy_root" == /* && "$deploy_root" != / ]] || { echo 'Use an absolute DEPLOY_PATH.' >&2; exit 2; }
[[ "$revision" =~ ^[0-9a-f]{40,64}$ ]] || { echo 'Invalid commit SHA.' >&2; exit 2; }
cd -- "$deploy_root"
# Serialize manual and CI deployments; old queued runs cannot replace newer code.
exec 9>.deploy.lock
flock -x 9
[[ -f .env ]] || { echo 'Fill in .env before deploying.' >&2; exit 1; }
git diff --quiet && git diff --cached --quiet || { echo 'Commit or remove server checkout edits first.' >&2; exit 1; }
[[ "$(git symbolic-ref --short HEAD)" == main ]] || { echo 'The deployment checkout must be on main.' >&2; exit 1; }
git fetch origin main
if [[ "$(git rev-parse origin/main)" != "$revision" ]]; then
echo 'Skipping an outdated deployment; a newer main commit exists.'
exit 0
fi
git merge --ff-only "$revision"
export PORTFOLIO_IMAGE="portfolio:$revision"
# Keep a consistent backup before migrations can run in the new container.
container="$(docker compose ps -q portfolio-app)"
if [[ -n "$container" ]]; then
backup_name="before-$revision-$(date +%s)"
mkdir -p backups
docker compose exec -T portfolio-app node maintenance.mjs backup "/tmp/$backup_name"
docker cp "$container:/tmp/$backup_name" "backups/$backup_name"
fi
# Build once; Next's production compilation includes the type check.
docker compose up --build -d --remove-orphans --wait --wait-timeout 60