name: Deploy on: push: branches: [main] concurrency: group: deploy-production cancel-in-progress: false jobs: deploy: name: Deploy to Production runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Deploy via SSH uses: appleboy/ssh-action@v1 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_KEY }} port: ${{ secrets.SSH_PORT }} script: | set -euo pipefail export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" cd /home/${{ secrets.SSH_USER }}/ss echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting deployment..." echo "$(date '+%Y-%m-%d %H:%M:%S') - Pulling latest changes..." git fetch origin main # Hard reset to remote to drop any stale build artifacts (e.g. tsbuildinfo) # that would otherwise block 'git pull'. The deploy server is treated as # a deployment target, not a development checkout. git reset --hard origin/main echo "$(date '+%Y-%m-%d %H:%M:%S') - Installing dependencies..." pnpm install --frozen-lockfile echo "$(date '+%Y-%m-%d %H:%M:%S') - Building..." pnpm build echo "$(date '+%Y-%m-%d %H:%M:%S') - Installing Playwright Chromium (if missing)..." cd apps/web && npx playwright install chromium --with-deps 2>/dev/null || true echo "$(date '+%Y-%m-%d %H:%M:%S') - Pre-rendering public pages..." pnpm prerender || echo "WARNING: Pre-render failed (non-fatal)" cd /home/${{ secrets.SSH_USER }}/ss echo "$(date '+%Y-%m-%d %H:%M:%S') - Running database migrations..." cd apps/api && pnpm db:migrate && cd ../.. echo "$(date '+%Y-%m-%d %H:%M:%S') - Reloading PM2 processes..." pm2 reload ecosystem.config.js echo "$(date '+%Y-%m-%d %H:%M:%S') - Deployment complete!" # NOTE: This trigger only fires when the GitHub Actions SSH-deploy workflow runs. # Current production deploys are Coolify-driven via git.semih.ai webhooks (see MEMORY.md). # When the GitHub Actions workflow is re-activated for production, this step will # automatically call Fusion to create a changelog entry after a successful deploy. - name: Trigger Fusion changelog automation if: success() continue-on-error: true run: | if [ -z "${{ secrets.FUSION_CHANGELOG_AUTOMATION_ID }}" ] || [ -z "${{ secrets.FUSION_DAEMON_TOKEN }}" ]; then echo "Fusion changelog secrets not configured — skipping automation trigger" exit 0 fi curl -sf -X POST \ -H "Authorization: Bearer ${{ secrets.FUSION_DAEMON_TOKEN }}" \ "https://fusion.semih.ai/api/automations/${{ secrets.FUSION_CHANGELOG_AUTOMATION_ID }}/run?projectId=proj_155fecc31ef14928&scope=project" \ || echo "Fusion trigger failed (non-fatal, continuing)"