add landing page #43
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Preview Deployment | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| jobs: | |
| deploy-preview: | |
| name: Deploy Convex Preview | |
| runs-on: ubuntu-latest | |
| # Only run for PRs from the same repo (not forks) | |
| if: github.event.pull_request.head.repo.full_name == github.repository | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v1 | |
| with: | |
| bun-version: "1.2.21" | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Deploy Convex Preview | |
| id: convex-deploy | |
| working-directory: apps/server | |
| env: | |
| CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_PREVIEW_DEPLOY_KEY }} | |
| run: | | |
| echo "🚀 Deploying Convex preview for PR #${{ github.event.pull_request.number }}..." | |
| # Deploy to Convex preview | |
| OUTPUT=$(bunx convex deploy --preview-create pr-${{ github.event.pull_request.number }} 2>&1) | |
| echo "$OUTPUT" | |
| # Extract the deployment URL from output | |
| CONVEX_URL=$(echo "$OUTPUT" | grep -o 'https://[a-z0-9-]*\.convex\.cloud' | head -1) | |
| if [ -z "$CONVEX_URL" ]; then | |
| echo "❌ Failed to extract Convex URL from deployment output" | |
| exit 1 | |
| fi | |
| # Derive the site URL from the cloud URL | |
| CONVEX_SITE_URL=$(echo "$CONVEX_URL" | sed 's/\.convex\.cloud/.convex.site/') | |
| echo "✅ Convex Preview deployed!" | |
| echo " Cloud URL: $CONVEX_URL" | |
| echo " Site URL: $CONVEX_SITE_URL" | |
| # Set outputs for later steps | |
| echo "convex_url=$CONVEX_URL" >> $GITHUB_OUTPUT | |
| echo "convex_site_url=$CONVEX_SITE_URL" >> $GITHUB_OUTPUT | |
| - name: Set Convex Environment Variables | |
| working-directory: apps/server | |
| env: | |
| CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_PREVIEW_DEPLOY_KEY }} | |
| BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }} | |
| GITHUB_CLIENT_ID: ${{ secrets.AUTH_GITHUB_CLIENT_ID }} | |
| GITHUB_CLIENT_SECRET: ${{ secrets.AUTH_GITHUB_CLIENT_SECRET }} | |
| run: | | |
| echo "⚙️ Setting Convex environment variables..." | |
| PR_NUM=${{ github.event.pull_request.number }} | |
| RAILWAY_URL="https://web-openchat-pr-${PR_NUM}.up.railway.app" | |
| # Core settings | |
| bunx convex env set SITE_URL "$RAILWAY_URL" --preview-name pr-${PR_NUM} | |
| bunx convex env set NEXT_PUBLIC_DEPLOYMENT "preview" --preview-name pr-${PR_NUM} | |
| # Auth settings - must match production for oAuthProxy to work | |
| bunx convex env set BETTER_AUTH_SECRET "$BETTER_AUTH_SECRET" --preview-name pr-${PR_NUM} | |
| bunx convex env set GITHUB_CLIENT_ID "$GITHUB_CLIENT_ID" --preview-name pr-${PR_NUM} | |
| bunx convex env set GITHUB_CLIENT_SECRET "$GITHUB_CLIENT_SECRET" --preview-name pr-${PR_NUM} | |
| echo "✅ Convex env vars set" | |
| echo " SITE_URL: $RAILWAY_URL" | |
| echo " NEXT_PUBLIC_DEPLOYMENT: preview" | |
| echo " BETTER_AUTH_SECRET: [set]" | |
| echo " GITHUB_CLIENT_ID: [set]" | |
| echo " GITHUB_CLIENT_SECRET: [set]" | |
| - name: Configure Railway Environment | |
| env: | |
| RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }} | |
| run: | | |
| echo "🚂 Configuring Railway environment via GraphQL API..." | |
| PR_NUM=${{ github.event.pull_request.number }} | |
| CONVEX_URL="${{ steps.convex-deploy.outputs.convex_url }}" | |
| CONVEX_SITE_URL="${{ steps.convex-deploy.outputs.convex_site_url }}" | |
| ENV_NAME="openchat-pr-${PR_NUM}" | |
| PROJECT_ID="e3803b5c-22bf-4cbe-a8b3-2e4c8a5fbe8a" | |
| SERVICE_ID="f12f449e-b9d8-471b-94ea-7107b7c5da47" | |
| # Wait for Railway to create the PR environment | |
| echo "Waiting for Railway PR environment..." | |
| sleep 20 | |
| # Get the environment ID | |
| echo "Looking up environment ID for ${ENV_NAME}..." | |
| ENV_RESPONSE=$(curl -s -X POST \ | |
| -H "Authorization: Bearer ${RAILWAY_TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"query\": \"query { project(id: \\\"${PROJECT_ID}\\\") { environments { edges { node { id name } } } } }\"}" \ | |
| https://backboard.railway.app/graphql/v2) | |
| echo "Environment response: ${ENV_RESPONSE}" | |
| ENV_ID=$(echo "$ENV_RESPONSE" | jq -r ".data.project.environments.edges[] | select(.node.name == \"${ENV_NAME}\") | .node.id") | |
| if [ -z "$ENV_ID" ] || [ "$ENV_ID" == "null" ]; then | |
| echo "⚠️ Could not find environment ${ENV_NAME}, skipping Railway config" | |
| exit 0 | |
| fi | |
| echo "Found environment ID: ${ENV_ID}" | |
| # Set VITE_CONVEX_URL | |
| echo "Setting VITE_CONVEX_URL..." | |
| curl -s -X POST \ | |
| -H "Authorization: Bearer ${RAILWAY_TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"query\": \"mutation { variableUpsert(input: { projectId: \\\"${PROJECT_ID}\\\", environmentId: \\\"${ENV_ID}\\\", serviceId: \\\"${SERVICE_ID}\\\", name: \\\"VITE_CONVEX_URL\\\", value: \\\"${CONVEX_URL}\\\" }) }\"}" \ | |
| https://backboard.railway.app/graphql/v2 | |
| # Set VITE_CONVEX_SITE_URL | |
| echo "Setting VITE_CONVEX_SITE_URL..." | |
| curl -s -X POST \ | |
| -H "Authorization: Bearer ${RAILWAY_TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"query\": \"mutation { variableUpsert(input: { projectId: \\\"${PROJECT_ID}\\\", environmentId: \\\"${ENV_ID}\\\", serviceId: \\\"${SERVICE_ID}\\\", name: \\\"VITE_CONVEX_SITE_URL\\\", value: \\\"${CONVEX_SITE_URL}\\\" }) }\"}" \ | |
| https://backboard.railway.app/graphql/v2 | |
| echo "✅ Railway environment variables updated" | |
| - name: Comment on PR | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const prNumber = context.payload.pull_request.number; | |
| const convexUrl = '${{ steps.convex-deploy.outputs.convex_url }}'; | |
| const convexSiteUrl = '${{ steps.convex-deploy.outputs.convex_site_url }}'; | |
| const railwayUrl = `https://web-openchat-pr-${prNumber}.up.railway.app`; | |
| const body = `## 🚀 Preview Deployment Ready | |
| | Environment | URL | | |
| |------------|-----| | |
| | **Frontend** | [${railwayUrl}](${railwayUrl}) | | |
| | **Convex Dashboard** | [Dashboard](https://dashboard.convex.dev) | | |
| ### Convex Preview Backend | |
| - Cloud URL: \`${convexUrl}\` | |
| - Site URL: \`${convexSiteUrl}\` | |
| --- | |
| <sub>🤖 Deployed automatically by GitHub Actions</sub>`; | |
| // Find existing comment | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.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: prNumber, | |
| body: body | |
| }); | |
| } | |
| - name: Summary | |
| if: always() | |
| run: | | |
| PR_NUM=${{ github.event.pull_request.number }} | |
| echo "## Preview Deployment Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Component | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----------|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Convex Preview | ✅ Deployed |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### URLs" >> $GITHUB_STEP_SUMMARY | |
| echo "- Frontend: https://web-openchat-pr-${PR_NUM}.up.railway.app" >> $GITHUB_STEP_SUMMARY | |
| echo "- Convex: ${{ steps.convex-deploy.outputs.convex_url }}" >> $GITHUB_STEP_SUMMARY |