Add auto-deploy on PR workflow
This commit is contained in:
242
.github/workflows/auto-deploy-pr.yml
vendored
Normal file
242
.github/workflows/auto-deploy-pr.yml
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
name: Auto Deploy PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
push:
|
||||
branches: [main, master, RAILWAY-DEPLOY-BRANCH]
|
||||
|
||||
env:
|
||||
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
|
||||
jobs:
|
||||
detect-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
deployments: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Detect Project Type
|
||||
id: detect
|
||||
run: |
|
||||
# Detect what kind of project this is
|
||||
if [ -f "railway.toml" ] || [ -f "railway.json" ]; then
|
||||
echo "platform=railway" >> $GITHUB_OUTPUT
|
||||
elif [ -f "wrangler.toml" ] || [ -f "wrangler.json" ]; then
|
||||
echo "platform=cloudflare-workers" >> $GITHUB_OUTPUT
|
||||
elif [ -f "next.config.js" ] || [ -f "next.config.mjs" ] || [ -f "next.config.ts" ]; then
|
||||
echo "platform=cloudflare-pages" >> $GITHUB_OUTPUT
|
||||
echo "framework=next" >> $GITHUB_OUTPUT
|
||||
elif [ -f "vite.config.ts" ] || [ -f "vite.config.js" ]; then
|
||||
echo "platform=cloudflare-pages" >> $GITHUB_OUTPUT
|
||||
echo "framework=vite" >> $GITHUB_OUTPUT
|
||||
elif [ -f "Dockerfile" ]; then
|
||||
echo "platform=railway" >> $GITHUB_OUTPUT
|
||||
elif [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
|
||||
echo "platform=railway" >> $GITHUB_OUTPUT
|
||||
echo "framework=python" >> $GITHUB_OUTPUT
|
||||
elif [ -f "package.json" ]; then
|
||||
echo "platform=cloudflare-pages" >> $GITHUB_OUTPUT
|
||||
echo "framework=static" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "platform=railway" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Get repo name for service naming
|
||||
echo "repo_name=${GITHUB_REPOSITORY#*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
# Set environment based on event
|
||||
if [ "${{ github.event_name }}" == "pull_request" ]; then
|
||||
echo "environment=preview" >> $GITHUB_OUTPUT
|
||||
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "environment=production" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Install Dependencies
|
||||
if: steps.detect.outputs.platform == 'cloudflare-pages' || steps.detect.outputs.platform == 'cloudflare-workers'
|
||||
run: |
|
||||
if [ -f "package.json" ]; then
|
||||
npm ci || npm install
|
||||
fi
|
||||
|
||||
- name: Build (if needed)
|
||||
if: steps.detect.outputs.platform == 'cloudflare-pages'
|
||||
run: |
|
||||
if [ -f "package.json" ]; then
|
||||
npm run build || true
|
||||
fi
|
||||
|
||||
# ============ RAILWAY DEPLOYMENT ============
|
||||
- name: Install Railway CLI
|
||||
if: steps.detect.outputs.platform == 'railway' && env.RAILWAY_TOKEN != ''
|
||||
run: npm install -g @railway/cli
|
||||
|
||||
- name: Deploy to Railway
|
||||
if: steps.detect.outputs.platform == 'railway' && env.RAILWAY_TOKEN != ''
|
||||
id: railway
|
||||
run: |
|
||||
# Link to existing project or create new one
|
||||
railway link --environment ${{ steps.detect.outputs.environment }} 2>/dev/null || true
|
||||
|
||||
# Deploy
|
||||
DEPLOY_URL=$(railway up --detach 2>&1 | grep -oP 'https://[^\s]+' | head -1 || echo "")
|
||||
|
||||
if [ -n "$DEPLOY_URL" ]; then
|
||||
echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
|
||||
echo "success=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
# Try to get the URL from railway status
|
||||
DEPLOY_URL=$(railway status --json 2>/dev/null | jq -r '.deployments[0].url // empty' || echo "")
|
||||
echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
|
||||
echo "success=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# ============ CLOUDFLARE PAGES DEPLOYMENT ============
|
||||
- name: Deploy to Cloudflare Pages
|
||||
if: steps.detect.outputs.platform == 'cloudflare-pages' && env.CLOUDFLARE_API_TOKEN != ''
|
||||
id: cloudflare-pages
|
||||
run: |
|
||||
npm install -g wrangler
|
||||
|
||||
# Determine output directory
|
||||
if [ -d "dist" ]; then
|
||||
OUTPUT_DIR="dist"
|
||||
elif [ -d "build" ]; then
|
||||
OUTPUT_DIR="build"
|
||||
elif [ -d "out" ]; then
|
||||
OUTPUT_DIR="out"
|
||||
elif [ -d ".next" ]; then
|
||||
OUTPUT_DIR=".next"
|
||||
elif [ -d "public" ]; then
|
||||
OUTPUT_DIR="public"
|
||||
else
|
||||
OUTPUT_DIR="."
|
||||
fi
|
||||
|
||||
PROJECT_NAME="${{ steps.detect.outputs.repo_name }}"
|
||||
|
||||
# Create project if it doesn't exist
|
||||
wrangler pages project create "$PROJECT_NAME" --production-branch main 2>/dev/null || true
|
||||
|
||||
# Deploy
|
||||
if [ "${{ steps.detect.outputs.environment }}" == "preview" ]; then
|
||||
RESULT=$(wrangler pages deploy "$OUTPUT_DIR" --project-name="$PROJECT_NAME" --branch="pr-${{ steps.detect.outputs.pr_number }}" 2>&1)
|
||||
else
|
||||
RESULT=$(wrangler pages deploy "$OUTPUT_DIR" --project-name="$PROJECT_NAME" --branch=main 2>&1)
|
||||
fi
|
||||
|
||||
DEPLOY_URL=$(echo "$RESULT" | grep -oP 'https://[^\s]+\.pages\.dev' | head -1 || echo "")
|
||||
echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
|
||||
echo "success=true" >> $GITHUB_OUTPUT
|
||||
|
||||
# ============ CLOUDFLARE WORKERS DEPLOYMENT ============
|
||||
- name: Deploy to Cloudflare Workers
|
||||
if: steps.detect.outputs.platform == 'cloudflare-workers' && env.CLOUDFLARE_API_TOKEN != ''
|
||||
id: cloudflare-workers
|
||||
run: |
|
||||
npm install -g wrangler
|
||||
|
||||
if [ "${{ steps.detect.outputs.environment }}" == "preview" ]; then
|
||||
RESULT=$(wrangler deploy --env preview 2>&1 || wrangler deploy 2>&1)
|
||||
else
|
||||
RESULT=$(wrangler deploy 2>&1)
|
||||
fi
|
||||
|
||||
DEPLOY_URL=$(echo "$RESULT" | grep -oP 'https://[^\s]+\.workers\.dev' | head -1 || echo "")
|
||||
echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
|
||||
echo "success=true" >> $GITHUB_OUTPUT
|
||||
|
||||
# ============ COMMENT ON PR ============
|
||||
- name: Comment Deployment URL on PR
|
||||
if: github.event_name == 'pull_request' && (steps.railway.outputs.success == 'true' || steps.cloudflare-pages.outputs.success == 'true' || steps.cloudflare-workers.outputs.success == 'true')
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const railwayUrl = '${{ steps.railway.outputs.url }}';
|
||||
const pagesUrl = '${{ steps.cloudflare-pages.outputs.url }}';
|
||||
const workersUrl = '${{ steps.cloudflare-workers.outputs.url }}';
|
||||
const platform = '${{ steps.detect.outputs.platform }}';
|
||||
|
||||
const deployUrl = railwayUrl || pagesUrl || workersUrl || 'Deployment in progress...';
|
||||
|
||||
const platformEmoji = {
|
||||
'railway': '🚂',
|
||||
'cloudflare-pages': '📄',
|
||||
'cloudflare-workers': '⚡'
|
||||
};
|
||||
|
||||
const body = `## ${platformEmoji[platform] || '🚀'} Preview Deployment Ready!
|
||||
|
||||
| Platform | URL |
|
||||
|----------|-----|
|
||||
| **${platform}** | ${deployUrl ? `[${deployUrl}](${deployUrl})` : 'Deploying...'} |
|
||||
|
||||
---
|
||||
🤖 *Auto-deployed by BlackRoad OS*`;
|
||||
|
||||
// Find existing comment
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
});
|
||||
|
||||
const botComment = comments.find(c => c.body.includes('Preview Deployment Ready'));
|
||||
|
||||
if (botComment) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: botComment.id,
|
||||
body: body
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: body
|
||||
});
|
||||
}
|
||||
|
||||
# ============ CREATE GITHUB DEPLOYMENT ============
|
||||
- name: Create GitHub Deployment Status
|
||||
if: steps.railway.outputs.success == 'true' || steps.cloudflare-pages.outputs.success == 'true' || steps.cloudflare-workers.outputs.success == 'true'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const deployUrl = '${{ steps.railway.outputs.url }}' || '${{ steps.cloudflare-pages.outputs.url }}' || '${{ steps.cloudflare-workers.outputs.url }}';
|
||||
const environment = '${{ steps.detect.outputs.environment }}';
|
||||
|
||||
const deployment = await github.rest.repos.createDeployment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: context.sha,
|
||||
environment: environment,
|
||||
auto_merge: false,
|
||||
required_contexts: []
|
||||
});
|
||||
|
||||
if (deployment.data.id) {
|
||||
await github.rest.repos.createDeploymentStatus({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
deployment_id: deployment.data.id,
|
||||
state: 'success',
|
||||
environment_url: deployUrl,
|
||||
description: 'Deployment successful'
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user