name: Preview
on:
pull_request_target:
types:
- opened
- reopened
- synchronize
- closed
concurrency:
group: pr-preview-${{ github.event.pull_request.number }}
cancel-in-progress: false
env:
# Alchemy secrets
STAGE: pr-${{ github.event.pull_request.number }}
GITHUB_SHA: ${{ github.event.pull_request.head.sha }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
PULL_REQUEST: ${{ github.event.pull_request.number }}
CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
ALCHEMY_PASSWORD: ${{ secrets.ALCHEMY_PASSWORD }}
ALCHEMY_STATE_TOKEN: ${{ secrets.ALCHEMY_STATE_TOKEN }}
# App Secrets
BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }}
jobs:
deploy-preview:
if: ${{ github.event.action != 'closed' }}
runs-on: ubuntu-latest
# Requires approval for external contributors (configured in repo Settings → Environments)
environment: preview
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
# Checkout the PR head commit (safe after environment approval)
ref: ${{ github.event.pull_request.head.sha }}
- &a1
name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: "10"
- &a2
name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
cache: pnpm
- &a3
name: Install dependencies
shell: bash
run: pnpm install
- name: Deploy Preview
run: pnpm --filter ./apps/web run deploy
cleanup-preview:
if: ${{ github.event.action == 'closed' }}
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- *a1
- *a2
- *a3
- name: Cleanup Preview
run: pnpm --filter ./apps/web run destroy