34 lines
1.5 KiB
Bash
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
|