name: Deploy Examples

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    # Skip entirely for fork PRs — they don't have access to deploy secrets.
    # Use /deploy-preview slash command for fork PRs instead.
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
    name: Deploy ${{ matrix.example.name }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write
    strategy:
      fail-fast: false
      matrix:
        example:
          - name: app-router-cloudflare
            project: app-router-cloudflare
            wrangler_config: dist/server/wrangler.json
          - name: pages-router-cloudflare
            project: pages-router-cloudflare
            wrangler_config: dist/pages_router_cloudflare/wrangler.json
          - name: app-router-playground
            project: app-router-playground
            wrangler_config: dist/server/wrangler.json
          - name: realworld-api-rest
            project: realworld-api-rest
            wrangler_config: dist/realworld_api_rest/wrangler.json
          - name: nextra-docs-template
            project: nextra-docs-template
            wrangler_config: dist/server/wrangler.json
          - name: benchmarks
            project: benchmarks
            wrangler_config: dist/server/wrangler.json
          - name: hackernews
            project: hackernews
            wrangler_config: dist/server/wrangler.json
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm

      - run: pnpm install --frozen-lockfile

      - name: Build vinext plugin
        run: pnpm run build

      - name: Build example
        run: pnpm exec vite build
        working-directory: examples/${{ matrix.example.name }}

      - name: Apply D1 migrations (benchmarks only)
        if: matrix.example.name == 'benchmarks' && github.event_name == 'push' && github.ref == 'refs/heads/main'
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          workingDirectory: examples/benchmarks
          command: d1 migrations apply vinext-benchmarks --remote

      - name: Deploy to Cloudflare Workers (Production)
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          workingDirectory: examples/${{ matrix.example.name }}
          command: deploy --config ${{ matrix.example.wrangler_config }}

      - name: Deploy Preview Version
        if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          workingDirectory: examples/${{ matrix.example.name }}
          command: versions upload --config ${{ matrix.example.wrangler_config }} --preview-alias pr-${{ github.event.pull_request.number }}

  smoke-test:
    name: Smoke Test Deployments
    runs-on: ubuntu-latest
    needs: deploy
    steps:
      - uses: actions/checkout@v4

      - name: Smoke test (production)
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        run: ./scripts/smoke-test.sh

      - name: Smoke test (preview)
        if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
        run: ./scripts/smoke-test.sh --preview pr-${{ github.event.pull_request.number }}

  comment:
    name: Comment Preview URLs
    runs-on: ubuntu-latest
    needs: deploy
    if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
    permissions:
      pull-requests: write
    steps:
      - name: Comment PR with preview URLs
        uses: actions/github-script@v7
        with:
          script: |
            const prNumber = context.issue.number;
            const alias = `pr-${prNumber}`;
            
            const examples = [
              { name: 'app-router-cloudflare', project: 'app-router-cloudflare' },
              { name: 'pages-router-cloudflare', project: 'pages-router-cloudflare' },
              { name: 'app-router-playground', project: 'app-router-playground', original: 'https://app-router.vercel.app' },
              { name: 'realworld-api-rest', project: 'realworld-api-rest' },
              { name: 'nextra-docs-template', project: 'nextra-docs-template' },
              { name: 'benchmarks', project: 'benchmarks' },
              { name: 'hackernews', project: 'hackernews', original: 'https://next-react-server-components.vercel.app' },
            ];
            
            const { data: comments } = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
            });
            
            const marker = '<!-- vinext-deploy-previews -->';
            const existingComment = comments.find(c => c.body?.includes(marker));
            
            const rows = examples
              .map(e => {
                const orig = e.original ? `[original](${e.original})` : '';
                return `| ${e.name} | [preview](https://${alias}-${e.project}.vinext.workers.dev) | [production](https://${e.project}.vinext.workers.dev) | ${orig} |`;
              })
              .join('\n');
            
            const body = [
              marker,
              '| Example | Preview | Production | Original |',
              '|---------|---------|------------|----------|',
              rows,
            ].join('\n');
            
            if (existingComment) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existingComment.id,
                body,
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: prNumber,
                body,
              });
            }
