feat: add production deploy script with auto-rollback and Gitea Actions workflow

Add automated production deployment pipeline:
- scripts/deploy-prod.sh: Full deployment script with pre/post DB backups,
  migration tracking via shared.schema_migrations table, health checks,
  and automatic rollback on failure (restores DB, reverts code, rebuilds)
- .gitea/workflows/deploy.yml: Manual-trigger Gitea Actions workflow for
  intentional production deployments with optional --seed-existing flag
- scripts/db-backup.sh: Add --yes/-y flag to skip interactive confirmation
  prompts, enabling automated restore during rollback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 09:05:45 -04:00
parent 83115c9b5c
commit 95c83a57b6
3 changed files with 484 additions and 2 deletions

View File

@@ -21,6 +21,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
BACKUP_DIR="$PROJECT_DIR/backups"
KEEP_DAYS=0 # 0 = keep forever
FORCE_YES=false # skip interactive confirmations (for automation)
DB_USER="${POSTGRES_USER:-hoafinance}"
DB_NAME="${POSTGRES_DB:-hoafinance}"
COMPOSE_CMD="docker compose"
@@ -121,8 +122,12 @@ do_restore() {
warn "This will DESTROY the current '${DB_NAME}' database and replace it"
warn "with the contents of: $(basename "$file")"
echo ""
read -rp "Type 'yes' to continue: " confirm
[ "$confirm" = "yes" ] || { info "Aborted."; exit 0; }
if [ "$FORCE_YES" = true ]; then
info "Skipping confirmation (--yes flag set)"
else
read -rp "Type 'yes' to continue: " confirm
[ "$confirm" = "yes" ] || { info "Aborted."; exit 0; }
fi
echo ""
info "Step 1/4 — Terminating active connections ..."
@@ -229,6 +234,7 @@ Usage:
Options:
--dir DIR Backup directory (default: ./backups)
--keep DAYS Auto-delete backups older than DAYS (default: keep all)
--yes, -y Skip interactive confirmation prompts (for automation)
Supported restore formats:
.dump.gz Custom-format pg_dump, gzipped (default backup format)
@@ -255,6 +261,7 @@ while [ $# -gt 0 ]; do
case "$1" in
--dir) BACKUP_DIR="$2"; shift 2 ;;
--keep) KEEP_DAYS="$2"; shift 2 ;;
--yes|-y) FORCE_YES=true; shift ;;
--help) usage ;;
*)
if [ "$COMMAND" = "restore" ] && [ -z "$RESTORE_FILE" ]; then