deploy.sh: handle first-deploy and --force re-deploys

The previous version short-circuited with 'nothing to do' when local
HEAD already matched the target — which is wrong on the first deploy
(no container yet) and inconvenient when re-running after a manual
fix. Now:
  * Auto-proceeds when no container is running for the web service.
  * Accepts --force to rebuild + restart at the same revision.
  * Skips the empty changelog section when CURRENT == TARGET.
This commit is contained in:
nickviljoen 2026-05-09 16:35:36 +02:00
parent 458c75311e
commit aacefbd7df

View file

@ -29,30 +29,40 @@ MODE=${1:-}
shift || true
DRY_RUN=false
FORCE=false
TARGET_TAG=""
parse_flags() {
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=true ;;
--force) FORCE=true ;;
esac
done
}
case "$MODE" in
dev)
for arg in "$@"; do
[[ "$arg" == "--dry-run" ]] && DRY_RUN=true
done
parse_flags "$@"
;;
prod)
TARGET_TAG=${1:-}
shift || true
for arg in "$@"; do
[[ "$arg" == "--dry-run" ]] && DRY_RUN=true
done
parse_flags "$@"
if [[ -z "$TARGET_TAG" ]]; then
echo "Usage: $0 prod <tag> [--dry-run]"
echo "Usage: $0 prod <tag> [--dry-run] [--force]"
exit 1
fi
;;
""|-h|--help)
cat <<EOF
Usage:
$(basename "$0") dev [--dry-run] Deploy latest develop to this server
$(basename "$0") prod <tag> [--dry-run] Deploy a specific tag to this server
$(basename "$0") dev [--dry-run] [--force]
$(basename "$0") prod <tag> [--dry-run] [--force]
--dry-run Show what would change, make no changes.
--force Re-build + re-up even if local HEAD already matches the target.
Implied automatically on first deploy (no running container).
Run on the target server. Requires permission to talk to docker.
EOF
@ -101,24 +111,39 @@ fi
TARGET_REV=$(git rev-parse "$TARGET_REF")
TARGET_SHORT=$(git rev-parse --short "$TARGET_REF")
CONTAINER_RUNNING=false
if docker compose ps --status running --quiet web 2>/dev/null | grep -q .; then
CONTAINER_RUNNING=true
fi
if [[ "$CURRENT_REV" == "$TARGET_REV" ]]; then
echo "Already at $TARGET_SHORT — nothing to do."
exit 0
if [[ "$CONTAINER_RUNNING" == "false" ]]; then
echo "Already at $TARGET_SHORT, but no running container — proceeding to build/up."
FORCE=true
elif [[ "$FORCE" == "true" ]]; then
echo "Already at $TARGET_SHORT — --force passed, re-building and restarting."
else
echo "Already at $TARGET_SHORT — nothing to do. (Pass --force to rebuild anyway.)"
exit 0
fi
fi
echo "Target: $TARGET_SHORT $(git log -1 --format='%s' "$TARGET_REF")"
echo ""
echo "Commits to apply:"
git log --oneline "$CURRENT_REV..$TARGET_REV" | head -20
CHANGE_COUNT=$(git log --oneline "$CURRENT_REV..$TARGET_REV" | wc -l | tr -d ' ')
if [[ $CHANGE_COUNT -gt 20 ]]; then
echo " ... and $((CHANGE_COUNT - 20)) more"
fi
echo ""
if git diff --name-only "$CURRENT_REV" "$TARGET_REV" | grep -qE "(^|/)migrations/versions/"; then
echo "Note: Alembic migrations changed — flask db upgrade will run."
if [[ "$CURRENT_REV" != "$TARGET_REV" ]]; then
echo "Commits to apply:"
git log --oneline "$CURRENT_REV..$TARGET_REV" | head -20
CHANGE_COUNT=$(git log --oneline "$CURRENT_REV..$TARGET_REV" | wc -l | tr -d ' ')
if [[ $CHANGE_COUNT -gt 20 ]]; then
echo " ... and $((CHANGE_COUNT - 20)) more"
fi
echo ""
if git diff --name-only "$CURRENT_REV" "$TARGET_REV" | grep -qE "(^|/)migrations/versions/"; then
echo "Note: Alembic migrations changed — flask db upgrade will run."
echo ""
fi
fi
if [[ "$DRY_RUN" == "true" ]]; then