name: Deploy to Railway on: push: branches: ["main"] workflow_dispatch: inputs: environment: description: 'Deployment environment' required: true default: 'production' type: choice options: - production - staging jobs: deploy: name: Deploy to Railway runs-on: ubuntu-latest environment: name: ${{ github.event.inputs.environment || 'production' }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Railway CLI run: | curl -fsSL https://railway.app/install.sh | sh - name: Deploy to Railway env: RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }} run: | railway link ${{ secrets.RAILWAY_PROJECT_ID }} railway up --detach if: env.RAILWAY_TOKEN != '' - name: Wait for deployment run: | echo "Waiting for deployment to complete..." sleep 30 - name: Health check run: | if [ -n "${{ secrets.RAILWAY_DOMAIN }}" ]; then echo "Checking health endpoint..." curl -f https://${{ secrets.RAILWAY_DOMAIN }}/health || exit 1 echo "✅ Deployment successful and healthy!" else echo "⚠️ Railway domain not configured, skipping health check" fi continue-on-error: true - name: Notify deployment status (Slack) if: always() && env.SLACK_WEBHOOK != '' env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} run: | if [ "${{ job.status }}" == "success" ]; then STATUS_EMOJI="✅" STATUS_TEXT="successful" COLOR="good" else STATUS_EMOJI="❌" STATUS_TEXT="failed" COLOR="danger" fi curl -X POST $SLACK_WEBHOOK \ -H 'Content-Type: application/json' \ -d "{ \"text\": \"${STATUS_EMOJI} Railway Deployment ${STATUS_TEXT}\", \"attachments\": [{ \"color\": \"${COLOR}\", \"fields\": [ {\"title\": \"Repository\", \"value\": \"${{ github.repository }}\", \"short\": true}, {\"title\": \"Branch\", \"value\": \"${{ github.ref_name }}\", \"short\": true}, {\"title\": \"Commit\", \"value\": \"${{ github.sha }}\", \"short\": false}, {\"title\": \"Author\", \"value\": \"${{ github.actor }}\", \"short\": true} ] }] }" - name: Notify deployment status (Discord) if: always() && env.DISCORD_WEBHOOK != '' env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | if [ "${{ job.status }}" == "success" ]; then STATUS_EMOJI="✅" STATUS_TEXT="successful" COLOR=3066993 else STATUS_EMOJI="❌" STATUS_TEXT="failed" COLOR=15158332 fi curl -X POST $DISCORD_WEBHOOK \ -H 'Content-Type: application/json' \ -d "{ \"content\": \"${STATUS_EMOJI} Railway Deployment ${STATUS_TEXT}\", \"embeds\": [{ \"title\": \"Deployment to Railway\", \"color\": ${COLOR}, \"fields\": [ {\"name\": \"Repository\", \"value\": \"${{ github.repository }}\", \"inline\": true}, {\"name\": \"Branch\", \"value\": \"${{ github.ref_name }}\", \"inline\": true}, {\"name\": \"Commit\", \"value\": \"${GITHUB_SHA:0:7}\", \"inline\": true}, {\"name\": \"Author\", \"value\": \"${{ github.actor }}\", \"inline\": true} ], \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\" }] }" post-deploy: name: Post-Deployment Tasks runs-on: ubuntu-latest needs: deploy if: success() steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Run API health checks env: RAILWAY_DOMAIN: ${{ secrets.RAILWAY_DOMAIN }} run: | if [ -n "$RAILWAY_DOMAIN" ]; then pip install httpx python << 'EOF' import asyncio import httpx import os async def check_apis(): domain = os.getenv("RAILWAY_DOMAIN") base_url = f"https://{domain}" print(f"\n{'='*60}") print(f"Checking API Health: {base_url}") print(f"{'='*60}\n") async with httpx.AsyncClient(timeout=30.0) as client: # Check main health endpoint try: response = await client.get(f"{base_url}/health") print(f"✅ Main health: {response.status_code}") except Exception as e: print(f"❌ Main health: {e}") # Check API health summary try: response = await client.get(f"{base_url}/api/health/summary") if response.status_code == 200: data = response.json() print(f"✅ API Health Summary:") print(f" Total APIs: {data['summary']['total']}") print(f" Connected: {data['summary']['connected']}") print(f" Not Configured: {data['summary']['not_configured']}") print(f" Errors: {data['summary']['errors']}") else: print(f"⚠️ API health: {response.status_code}") except Exception as e: print(f"❌ API health: {e}") print(f"\n{'='*60}") asyncio.run(check_apis()) EOF else echo "⚠️ Railway domain not configured, skipping health checks" fi