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:
65
.gitea/workflows/deploy.yml
Normal file
65
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,65 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Production Deployment Workflow for HOA LedgerIQ
|
||||
#
|
||||
# Trigger: Manual only (workflow_dispatch) — production deploys are intentional.
|
||||
# Runner: Self-hosted on the production server at /opt/hoa-ledgeriq.
|
||||
#
|
||||
# This workflow does NOT use actions/checkout. The runner operates directly
|
||||
# on the production directory. The deploy script itself handles git pull.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
name: Deploy to Production
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
seed_existing:
|
||||
description: "Mark existing migrations as applied without running them (first deployment only)"
|
||||
required: false
|
||||
default: "false"
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: /opt/hoa-ledgeriq
|
||||
|
||||
steps:
|
||||
- name: Pre-deploy info
|
||||
run: |
|
||||
echo "## Pre-Deploy Info" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Server:** $(hostname)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Directory:** $(pwd)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Current commit:** $(git rev-parse --short HEAD)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Branch:** $(git branch --show-current || echo 'detached')" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Triggered by:** ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Seed existing:** ${{ inputs.seed_existing }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Started at:** $(date -Iseconds)" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Run deployment
|
||||
run: |
|
||||
DEPLOY_FLAGS=""
|
||||
if [ "${{ inputs.seed_existing }}" = "true" ]; then
|
||||
DEPLOY_FLAGS="--seed-existing"
|
||||
fi
|
||||
bash scripts/deploy-prod.sh $DEPLOY_FLAGS
|
||||
env:
|
||||
TERM: xterm
|
||||
|
||||
- name: Deployment result
|
||||
if: always()
|
||||
run: |
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## Deployment Result" >> $GITHUB_STEP_SUMMARY
|
||||
if [ "${{ job.status }}" = "success" ]; then
|
||||
echo "- **Status:** Successful" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Commit:** $(git rev-parse --short HEAD)" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "- **Status:** FAILED (auto-rollback triggered)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Commit (after rollback):** $(git rev-parse --short HEAD)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Check the deploy log on the server for details" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "- **Completed at:** $(date -Iseconds)" >> $GITHUB_STEP_SUMMARY
|
||||
Reference in New Issue
Block a user