Skip to content

feat: add pr flow

feat: add pr flow #12

Workflow file for this run

name: PR Check
on:
pull_request:
branches: [ main ]
permissions:
contents: read
pull-requests: write # Needed to comment on PRs
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install Dependencies
run: |
npm run install:all
- name: Build Frontend
run: cd frontend && npm run build
- name: Build Backend
run: cd backend && npm run build
- name: Check for sensitive data
run: |
echo "Checking for sensitive data in source files..."
# First show all matches with context
echo "πŸ” Scanning files for sensitive patterns..."
find frontend/src backend/src -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/.github/*" -exec grep -H -n "API_KEY\|SECRET\|PASSWORD\|PRIVATE_KEY" {} \; || true
# Then do the actual check
FOUND_FILES=$(find frontend/src backend/src -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/.github/*" -exec grep -l "API_KEY\|SECRET\|PASSWORD\|PRIVATE_KEY" {} \;)
if [ ! -z "$FOUND_FILES" ]; then
echo "⚠️ Warning: Possible sensitive data found in these files:"
echo "$FOUND_FILES"
echo "Please review the matches above and ensure no sensitive data is being committed."
exit 1
else
echo "βœ… No sensitive data patterns found"
fi
- name: Start Backend
run: |
cd backend
npm run dev &
echo "Waiting for backend to start..."
sleep 2
- name: Start Frontend Dev Server
run: |
cd frontend
npm run dev &
echo "Waiting for frontend to start..."
sleep 2
- name: Test Application
run: |
# Test backend health endpoint
BACKEND_HEALTH=$(curl -s http://localhost:3456/health)
if [[ $BACKEND_HEALTH != *"ok"* ]]; then
echo "❌ Backend health check failed"
exit 1
fi
echo "βœ… Backend is healthy"
# Test frontend is running
FRONTEND_RESPONSE=$(curl -s http://localhost:5173)
if [[ $FRONTEND_RESPONSE != *"<!DOCTYPE html>"* ]]; then
echo "❌ Frontend check failed"
exit 1
fi
echo "βœ… Frontend is running"
# Test Bitcoin price endpoint
PRICE_CHECK=$(curl -s http://localhost:3456/api/price/bitcoin)
if [[ $PRICE_CHECK != *"success"* ]]; then
echo "❌ Bitcoin price endpoint failed"
exit 1
fi
echo "βœ… Bitcoin price endpoint is working"
- name: Create Render Preview
env:
RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }}
run: |
# Create a unique name for this PR preview
PR_NAME="pr-${GITHUB_HEAD_REF:-$GITHUB_REF_NAME}-${{ github.event.number }}"
echo "Creating preview for $PR_NAME"
# Get owner ID first
echo "Getting owner ID..."
OWNER_INFO=$(curl -s -H "Authorization: Bearer $RENDER_API_KEY" https://api.render.com/v1/owners)
# Extract the owner ID from the nested structure
OWNER_ID=$(echo "$OWNER_INFO" | jq -r '.[0].owner.id')
if [ -z "$OWNER_ID" ] || [ "$OWNER_ID" = "null" ]; then
echo "❌ Failed to get owner ID"
exit 1
fi
echo "Using Render team ID: ${OWNER_ID:0:8}..." # Only show first 8 chars
# Deploy backend service
echo "Creating backend service..."
BACKEND_RESPONSE=$(curl -X POST https://api.render.com/v1/services \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "'$PR_NAME'-backend",
"type": "web_service",
"runtime": "node",
"buildCommand": "cd backend && npm install && npm run build",
"startCommand": "cd backend && npm run start",
"envVars": [
{"key": "PORT", "value": "3456"}
],
"ownerId": "'$OWNER_ID'",
"serviceDetails": {
"plan": "free",
"pullRequestPreviewsEnabled": true,
"region": "oregon",
"env": "node",
"rootDir": ".",
"numInstances": 1,
"healthCheckPath": "/health",
"buildFilter": {
"paths": ["backend/**"]
}
},
"autoDeploy": "no"
}')
echo "Backend service creation response:"
echo "$BACKEND_RESPONSE"
BACKEND_ID=$(echo "$BACKEND_RESPONSE" | jq -r '.service.id // empty')
if [ -z "$BACKEND_ID" ]; then
echo "❌ Failed to create backend service"
exit 1
fi
echo "Waiting for backend service to be ready..."
for i in {1..30}; do
BACKEND_STATUS=$(curl -s -H "Authorization: Bearer $RENDER_API_KEY" \
"https://api.render.com/v1/services/$BACKEND_ID" | jq -r '.service.status // empty')
if [ "$BACKEND_STATUS" = "live" ]; then
break
fi
echo "Backend status: $BACKEND_STATUS"
sleep 10
done
# Get backend URL
BACKEND_INFO=$(curl -s -H "Authorization: Bearer $RENDER_API_KEY" \
"https://api.render.com/v1/services/$BACKEND_ID")
BACKEND_URL=$(echo "$BACKEND_INFO" | jq -r '.service.url // empty')
if [ -z "$BACKEND_URL" ]; then
echo "❌ Failed to get backend URL"
echo "Backend info: $BACKEND_INFO"
exit 1
fi
echo "Backend URL: $BACKEND_URL"
# Deploy frontend service
echo "Creating frontend service..."
FRONTEND_RESPONSE=$(curl -X POST https://api.render.com/v1/services \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "'$PR_NAME'-frontend",
"type": "static_site",
"buildCommand": "cd frontend && npm install && npm run build",
"publishPath": "frontend/dist",
"envVars": [
{"key": "VITE_BACKEND_URL", "value": "'$BACKEND_URL'"}
],
"ownerId": "'$OWNER_ID'",
"serviceDetails": {
"plan": "free",
"pullRequestPreviewsEnabled": true,
"region": "oregon",
"buildFilter": {
"paths": ["frontend/**"]
}
},
"autoDeploy": "no"
}')
echo "Frontend service creation response:"
echo "$FRONTEND_RESPONSE"
FRONTEND_ID=$(echo "$FRONTEND_RESPONSE" | jq -r '.service.id // empty')
if [ -z "$FRONTEND_ID" ]; then
echo "❌ Failed to create frontend service"
exit 1
fi
echo "Waiting for frontend service to be ready..."
for i in {1..30}; do
FRONTEND_STATUS=$(curl -s -H "Authorization: Bearer $RENDER_API_KEY" \
"https://api.render.com/v1/services/$FRONTEND_ID" | jq -r '.service.status // empty')
if [ "$FRONTEND_STATUS" = "live" ]; then
break
fi
echo "Frontend status: $FRONTEND_STATUS"
sleep 10
done
# Get frontend URL
FRONTEND_INFO=$(curl -s -H "Authorization: Bearer $RENDER_API_KEY" \
"https://api.render.com/v1/services/$FRONTEND_ID")
FRONTEND_URL=$(echo "$FRONTEND_INFO" | jq -r '.service.url // empty')
if [ -z "$FRONTEND_URL" ]; then
echo "❌ Failed to get frontend URL"
echo "Frontend info: $FRONTEND_INFO"
exit 1
fi
echo "Frontend URL: $FRONTEND_URL"
# Save URLs for the PR comment
echo "FRONTEND_URL=$FRONTEND_URL" >> $GITHUB_ENV
echo "BACKEND_URL=$BACKEND_URL" >> $GITHUB_ENV
- name: Comment PR
uses: actions/github-script@v7
with:
script: |
let comment = '## PR Check Results\n\n';
comment += '### Application Tests\n\n';
comment += 'βœ… Backend started successfully\n';
comment += 'βœ… Frontend started successfully\n';
comment += 'βœ… Health checks passed\n\n';
comment += '### Preview Deployment\n\n';
comment += `🌐 Frontend Preview: ${process.env.FRONTEND_URL}\n`;
comment += `πŸ”— Backend API: ${process.env.BACKEND_URL}\n\n`;
comment += '⏳ Preview environment is being deployed and will be ready in a few minutes.\n\n';
comment += '⚠️ Please test the preview deployment before merging!';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});