fix(worker): inline NEXT_DEPLOYMENT_ID into worker bundles #12923
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: 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 | |
| warm_cdn_cache: true | |
| - name: static-export | |
| project: static-export | |
| working_directory: examples/static-export | |
| wrangler_config: deploy/wrangler.jsonc | |
| static_export: true | |
| - name: web | |
| project: vinext-web | |
| working_directory: apps/web | |
| wrangler_config: dist/server/wrangler.json | |
| warm_cdn_cache: true | |
| warm_cdn_target: https://vinext.dev | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: ./.github/actions/setup | |
| - name: Build vinext plugin | |
| run: vp run build | |
| - name: Build example | |
| if: matrix.example.static_export != true | |
| run: vp build | |
| working-directory: ${{ matrix.example.working_directory }} | |
| - name: Build static export | |
| if: matrix.example.static_export == true | |
| run: vp exec vinext build | |
| working-directory: ${{ matrix.example.working_directory }} | |
| - name: Verify static export artifact | |
| if: matrix.example.static_export == true | |
| run: node scripts/verify-output.mjs | |
| 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' && matrix.example.warm_cdn_cache != true | |
| 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 to Cloudflare Workers with CDN warmup (Production) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.example.warm_cdn_cache == true | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| WARM_CDN_TARGET: ${{ matrix.example.warm_cdn_target }} | |
| run: | | |
| args=(--skip-build --config "${{ matrix.example.wrangler_config }}" --experimental-warm-cdn-cache) | |
| if [[ -n "$WARM_CDN_TARGET" ]]; then | |
| args+=(--warm-cdn-target "$WARM_CDN_TARGET") | |
| fi | |
| vp exec vinext-cloudflare deploy "${args[@]}" | |
| - 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 }} | |
| # `versions upload` does not apply non-versioned workers.dev/preview URL | |
| # settings. A newly added assets-only Worker has no routes until this runs. | |
| - name: Apply Static Export Preview Routes | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.static_export == true | |
| 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: triggers deploy --config ${{ matrix.example.wrangler_config }} | |
| - name: Seed RSC prewarm test Worker | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: >- | |
| vp exec wrangler deploy | |
| --config ../../tests/fixtures/rsc-prewarm-seed/wrangler.jsonc | |
| --name rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }} | |
| - name: Install Chromium for RSC prewarm verification | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' | |
| run: vp exec playwright install chromium | |
| - name: Deploy and prewarm RSC test Worker | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| VINEXT_CDN_WARM_DEBUG: "1" | |
| run: >- | |
| vp exec vinext-cloudflare deploy | |
| --skip-build | |
| --config ${{ matrix.example.wrangler_config }} | |
| --name rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }} | |
| --experimental-warm-cdn-cache | |
| - name: Verify deploy-prewarmed RSC browser reuse | |
| id: verify-rsc-prewarm | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' | |
| continue-on-error: true | |
| env: | |
| PLAYWRIGHT_PROJECT: cloudflare-workers | |
| VINEXT_E2E_BASE_URL: https://rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }}.vinext.workers.dev | |
| run: vp exec playwright test tests/e2e/cloudflare-workers/rsc-prewarm.spec.ts | |
| # A Playwright retry against the same keys could pass because the failed | |
| # first attempt filled them. Repeat the deployment under a fresh hostname. | |
| - name: Seed fresh Worker for RSC prewarm verification retry | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' && steps.verify-rsc-prewarm.outcome == 'failure' | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: >- | |
| vp exec wrangler deploy | |
| --config ../../tests/fixtures/rsc-prewarm-seed/wrangler.jsonc | |
| --name rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }}-retry | |
| - name: Retry deploy and RSC prewarm with fresh Worker | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' && steps.verify-rsc-prewarm.outcome == 'failure' | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| VINEXT_CDN_WARM_DEBUG: "1" | |
| run: >- | |
| vp exec vinext-cloudflare deploy | |
| --skip-build | |
| --config ${{ matrix.example.wrangler_config }} | |
| --name rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }}-retry | |
| --experimental-warm-cdn-cache | |
| - name: Retry deploy-prewarmed RSC browser reuse with fresh Worker | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' && steps.verify-rsc-prewarm.outcome == 'failure' | |
| env: | |
| PLAYWRIGHT_PROJECT: cloudflare-workers | |
| VINEXT_E2E_BASE_URL: https://rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }}-retry.vinext.workers.dev | |
| run: vp exec playwright test tests/e2e/cloudflare-workers/rsc-prewarm.spec.ts | |
| - name: Delete RSC prewarm retry Worker | |
| if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' && steps.verify-rsc-prewarm.outcome == 'failure' | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: >- | |
| vp exec wrangler delete rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }}-retry | |
| --config ${{ matrix.example.wrangler_config }} | |
| --force | |
| - name: Delete RSC prewarm test Worker | |
| if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && matrix.example.name == 'workers-cache' | |
| working-directory: ${{ matrix.example.working_directory }} | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| run: >- | |
| vp exec wrangler delete rsc-prewarm-${{ github.run_id }}-${{ github.run_attempt }} | |
| --config ${{ matrix.example.wrangler_config }} | |
| --force | |
| smoke-test: | |
| name: Smoke Test Deployments | |
| runs-on: ubuntu-latest | |
| needs: deploy | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| 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 }} | |
| deployed-e2e: | |
| name: E2E Deployed Example | |
| runs-on: ubuntu-latest | |
| needs: deploy | |
| if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: ./.github/actions/setup | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: ./.github/actions/playwright-cache | |
| with: | |
| browser: chromium | |
| mode: cache | |
| restore-keys: | | |
| playwright-chromium-${{ runner.os }}- | |
| - name: Install Playwright Chromium | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: vp exec playwright install chromium | |
| - name: Test deployed Web Worker | |
| env: | |
| PLAYWRIGHT_PROJECT: cloudflare-workers | |
| VINEXT_E2E_BASE_URL: ${{ github.event_name == 'pull_request' && format('https://pr-{0}-app-router-cloudflare.vinext.workers.dev', github.event.pull_request.number) || 'https://app-router-cloudflare.vinext.workers.dev' }} | |
| run: >- | |
| vp exec playwright test | |
| tests/e2e/cloudflare-workers/web-worker.spec.ts | |
| tests/e2e/cloudflare-workers/optimistic-search-navigation.spec.ts | |
| 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: 'static-export', project: 'static-export' }, | |
| { name: 'web', project: 'vinext-web', production: 'https://vinext.dev' }, | |
| ]; | |
| 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})` : ''; | |
| const production = e.production || `https://${e.project}.vinext.workers.dev`; | |
| return `| ${e.name} | [preview](https://${alias}-${e.project}.vinext.workers.dev) | [production](${production}) | ${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, | |
| }); | |
| } |