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!" # Fires after a successful PM2 reload. Calls the Fusion Routine API # (POST /api/routines//trigger), which runs the changelog auto-publisher # script: it reads recent github/main commits, summarizes them via DeepSeek, # and POSTs an entry to /api/changelog/internal. # FUSION_CHANGELOG_AUTOMATION_ID is the routine UUID (kept as-is for # backward compatibility; semantically it's a routine ID since the legacy # /automations endpoint was retired in favor of /routines). - 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 --max-time 120 \ -H "Authorization: Bearer ${{ secrets.FUSION_DAEMON_TOKEN }}" \ "https://fusion.semih.ai/api/routines/${{ secrets.FUSION_CHANGELOG_AUTOMATION_ID }}/trigger?projectId=proj_155fecc31ef14928&scope=project" \ || echo "Fusion trigger failed (non-fatal, continuing)"