# ROBOTS ON PAYROLL / THE VAULT
# What this is: a GitHub Actions workflow that gives every PR its own live Vercel preview URL, posted as a PR comment.
# How to use it: download this file and give it to your AI (Claude, ChatGPT,
# Cursor, Lovable chat) as a reference. Say: "Use this as my playbook for
# setting up PR preview environments."
# Latest version + full guide: https://robotsonpayroll.com/resources/github-actions-runbooks
#
# preview-envs.yml
# Every PR gets its own live preview URL on Vercel, posted as a PR comment.
# Same build-locally pattern as the prod deploy (pull -> build -> deploy
# --prebuilt), so previews and prod go through identical machinery.
#
# SECRETS REQUIRED:
#   VERCEL_TOKEN, VERCEL_ORG_ID, VERCEL_PROJECT_ID (same three as the deploy
#   runbook; from `vercel link` -> .vercel/project.json)
#
# NOTE: If Vercel's Git integration is still connected, Vercel already makes
# previews on its own and this duplicates them. Pick one owner. This workflow
# exists for when Actions owns deploys (you disabled Vercel auto-deploy) or
# when you want tests gating previews.

name: PR preview deploy

on:
  pull_request:
    branches: [main]

# One preview per PR. New pushes to the same PR cancel the older in-flight
# preview build (unlike prod, cancelling a preview is free and correct).
concurrency:
  group: preview-${{ github.ref }}
  cancel-in-progress: true

env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

jobs:
  preview:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write # needed to comment the URL on the PR

    steps:
      - uses: actions/checkout@v7

      - uses: actions/setup-node@v6
        with:
          node-version: 22
          cache: npm

      - run: npm ci

      # Broken PRs should not get preview URLs; fail here, fix, push again.
      - name: Lint and test
        run: |
          npm run lint --if-present
          npm test --if-present

      - name: Install Vercel CLI
        run: npm install --global vercel@latest

      - name: Pull Vercel preview settings
        run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

      - name: Build
        run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy preview
        id: deploy
        run: |
          url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
          echo "url=$url" >> "$GITHUB_OUTPUT"

      # Sticky comment: finds this workflow's earlier comment on the PR and
      # edits it instead of stacking a new comment on every push.
      - name: Comment preview URL on the PR
        uses: actions/github-script@v8
        with:
          script: |
            const marker = '<!-- preview-envs -->';
            const url = '${{ steps.deploy.outputs.url }}';
            const body = `${marker}\n**Preview deployed:** ${url}\n\n_Updated ${new Date().toISOString()} for commit ${context.payload.pull_request.head.sha.slice(0, 7)}._`;

            const { data: comments } = await github.rest.issues.listComments({
              ...context.repo, issue_number: context.issue.number, per_page: 100,
            });
            const existing = comments.find(c => c.body.includes(marker));

            if (existing) {
              await github.rest.issues.updateComment({
                ...context.repo, comment_id: existing.id, body,
              });
            } else {
              await github.rest.issues.createComment({
                ...context.repo, issue_number: context.issue.number, body,
              });
            }

# SECURITY NOTE: `pull_request` (used here) runs the PR's own code WITHOUT
# access to your secrets for forks, which is safe. Never "upgrade" this to
# `pull_request_target` to make fork previews work; that trigger hands your
# secrets to code from strangers (the classic pwn-request attack, and the
# reason checkout v7 now blocks fork checkouts under it by default).
# For a solo/private repo where all PRs are yours, this is a non-issue.
