next.js/.github/workflows/pull_request_stats.yml
pull_request_stats.yml174 lines5.9 KB
on:
  pull_request:
    types: [opened, synchronize]
  push:
    branches:
      - canary

name: Generate Stats

concurrency:
  # Keep cancel-on-update behavior for PRs, but allow canary pushes to run independently.
  group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
  NAPI_CLI_VERSION: 2.18.4
  TURBO_VERSION: 2.9.4
  NODE_LTS_VERSION: 20
  TEST_CONCURRENCY: 6

  TURBO_TEAM: 'vtest314-next-adapter-e2e-tests'
  # Prefer shared remote cache across runs, but keep local cache enabled so jobs
  # degrade gracefully if the remote cache or token is unavailable.
  TURBO_CACHE: 'local:rw,remote:rw'
  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
  NEXT_TELEMETRY_DISABLED: 1
  # we build a dev binary for use in CI so skip downloading
  # canary next-swc binaries in the monorepo
  NEXT_SKIP_NATIVE_POSTINSTALL: 1
  # Vercel KV Store for test timings
  KV_REST_API_URL: ${{ secrets.KV_REST_API_URL }}
  KV_REST_API_TOKEN: ${{ secrets.KV_REST_API_TOKEN }}
  NEXT_TEST_JOB: 1
  NEXT_DISABLE_SWC_WASM: 1

jobs:
  pr-ci-metadata:
    name: Upload PR CI metadata
    if: ${{ github.event_name == 'pull_request' }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - name: Write PR metadata
        env:
          PR_NUMBER: ${{ github.event.pull_request.number }}
          PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
          PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
          PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
          PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
          PR_IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
        run: |
          mkdir -p pr-ci-metadata
          node <<'NODE'
          const fs = require('fs')

          fs.writeFileSync(
            'pr-ci-metadata/pr.json',
            JSON.stringify(
              {
                number: Number(process.env.PR_NUMBER),
                headSha: process.env.PR_HEAD_SHA,
                headRef: process.env.PR_HEAD_REF,
                headRepo: process.env.PR_HEAD_REPO,
                baseRef: process.env.PR_BASE_REF,
                isFork: process.env.PR_IS_FORK === 'true',
              },
              null,
              2
            )
          )
          NODE

      - name: Upload PR metadata
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: pr-ci-metadata
          path: pr-ci-metadata/pr.json
          retention-days: 1

  build:
    uses: ./.github/workflows/build_reusable.yml
    secrets: inherit
    with:
      stepName: 'generate-pull-request-stats'
      uploadSwcArtifact: 'yes'
      uploadAnalyzerArtifacts: 'yes'

  stats:
    name: Stats (${{ matrix.bundler }})
    needs: build
    timeout-minutes: 25
    strategy:
      fail-fast: false
      matrix:
        bundler: [webpack, turbopack]
    runs-on: ubuntu-latest-16-core-oss
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 25

      - name: Check non-docs only change
        run: echo "DOCS_CHANGE<<EOF" >> $GITHUB_OUTPUT; echo "$(node scripts/run-for-change.mjs --not --type docs --exec echo 'nope')" >> $GITHUB_OUTPUT; echo 'EOF' >> $GITHUB_OUTPUT
        id: docs-change

      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        with:
          name: next-swc-binary
          path: packages/next-swc/native

      - run: cp -r packages/next-swc/native .github/actions/next-stats-action/native
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}

      - uses: ./.github/actions/next-stats-action
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        with:
          bundler: ${{ matrix.bundler }}
        env:
          TURBO_TEAM: ${{ env.TURBO_TEAM }}
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_CACHE: ${{ env.TURBO_CACHE }}
          PREVIEW_BUILDS_BASE_URL: ${{ vars.PREVIEW_BUILDS_BASE_URL }}

      - name: Upload stats results
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: pr-stats-${{ matrix.bundler }}
          path: pr-stats-${{ matrix.bundler }}.json
          retention-days: 1

  stats-aggregate:
    name: Aggregate Stats
    needs: stats
    if: always() && needs.stats.result != 'cancelled'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 25

      - name: Check non-docs only change
        run: echo "DOCS_CHANGE<<EOF" >> $GITHUB_OUTPUT; echo "$(node scripts/run-for-change.mjs --not --type docs --exec echo 'nope')" >> $GITHUB_OUTPUT; echo 'EOF' >> $GITHUB_OUTPUT
        id: docs-change

      - name: Download all stats artifacts
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          pattern: pr-stats-*
          path: stats-results
          merge-multiple: true

      - name: Setup Node.js
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_LTS_VERSION }}

      - name: Install dependencies
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        working-directory: .github/actions/next-stats-action
        run: npm install

      - name: Aggregate and post results
        if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }}
        working-directory: .github/actions/next-stats-action
        run: node src/aggregate-results.js ${{ github.workspace }}/stats-results
        env:
          KV_REST_API_URL: ${{ secrets.KV_REST_API_URL }}
          KV_REST_API_TOKEN: ${{ secrets.KV_REST_API_TOKEN }}
Quest for Codev2.0.0
/
SIGN IN