name: Deploy Examples on: push: branches: [main] pull_request: # run on PRs against any base branch, not just main concurrency: group: deploy-${{ github.event_name }}-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: deploy: # Skip entirely for fork PRs — they don't have access to deploy secrets. 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 working_directory: examples/app-router-cloudflare wrangler_config: dist/server/wrangler.json - name: pages-router-cloudflare project: pages-router-cloudflare working_directory: examples/pages-router-cloudflare wrangler_config: dist/pages_router_cloudflare/wrangler.json - name: app-router-playground project: app-router-playground working_directory: examples/app-router-playground wrangler_config: dist/server/wrangler.json - name: realworld-api-rest project: realworld-api-rest working_directory: examples/realworld-api-rest wrangler_config: dist/realworld_api_rest/wrangler.json - name: nextra-docs-template project: nextra-docs-template working_directory: examples/nextra-docs-template wrangler_config: dist/server/wrangler.json - name: benchmarks project: benchmarks working_directory: examples/benchmarks wrangler_config: dist/server/wrangler.json - name: hackernews project: hackernews working_directory: examples/hackernews wrangler_config: dist/server/wrangler.json - name: workers-cache project: workers-cache working_directory: examples/workers-cache wrangler_config: dist/server/wrangler.json - name: web project: vinext-web working_directory: apps/web wrangler_config: dist/server/wrangler.json steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup - name: Build vinext plugin run: vp run build - name: Build example run: vp build working-directory: ${{ matrix.example.working_directory }} - name: Apply D1 migrations (benchmarks only) if: matrix.example.name == 'benchmarks' && github.event_name == 'push' && github.ref == 'refs/heads/main' uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} workingDirectory: examples/benchmarks command: d1 migrations apply vinext-benchmarks --remote - name: Apply D1 migrations (web only) if: matrix.example.name == 'web' && github.event_name == 'push' && github.ref == 'refs/heads/main' uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} workingDirectory: apps/web command: d1 migrations apply vinext-metrics --remote - name: Deploy to Cloudflare Workers (Production) if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} workingDirectory: ${{ matrix.example.working_directory }} 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@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} workingDirectory: ${{ matrix.example.working_directory }} 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 permissions: contents: read steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 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' }, { name: 'workers-cache', project: 'workers-cache' }, { name: 'web', project: 'vinext-web' }, ]; const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, }); const marker = ''; 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, }); }