Merge pull request #5740 from joaovictor91123/fix/jobs-filter-url-syn… #3233
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: coverage | |
| # Coverage + full Vitest suite for code changes. This workflow always reports a | |
| # stable `coverage` PR check so branch protection can require it safely; pure | |
| # content/docs/markdown PRs skip inside the job instead of skipping the workflow. | |
| # Codecov consumes the generated lcov/JUnit reports for patch/project coverage | |
| # and Test Analytics, while this job remains the single test-producing lane. | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - "content/**" | |
| - "README.md" | |
| - "docs/**" | |
| - "**/*.md" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| concurrency: | |
| group: coverage-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| coverage: | |
| name: coverage | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| steps: | |
| - name: Determine coverage scope | |
| id: coverage-scope | |
| if: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GITHUB_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| node --input-type=module <<'NODE' | |
| import { appendFileSync } from "node:fs"; | |
| function normalizePath(filename) { | |
| return String(filename || "").replace(/\\/g, "/").replace(/^\.\//, ""); | |
| } | |
| function isCoverageIgnoredPath(filename) { | |
| const normalized = normalizePath(filename); | |
| return ( | |
| normalized === "README.md" || | |
| normalized.startsWith("content/") || | |
| normalized.startsWith("docs/") || | |
| normalized.endsWith(".md") | |
| ); | |
| } | |
| async function listChangedFiles() { | |
| const repo = process.env.GITHUB_REPOSITORY; | |
| const prNumber = process.env.PR_NUMBER; | |
| const token = process.env.GITHUB_TOKEN; | |
| const files = []; | |
| for (let page = 1; ; page += 1) { | |
| const url = new URL(`https://api.github.com/repos/${repo}/pulls/${prNumber}/files`); | |
| url.searchParams.set("per_page", "100"); | |
| url.searchParams.set("page", String(page)); | |
| const response = await fetch(url, { | |
| headers: { | |
| accept: "application/vnd.github+json", | |
| authorization: `Bearer ${token}`, | |
| "x-github-api-version": "2022-11-28", | |
| }, | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`GitHub pull files API returned ${response.status} ${response.statusText}`); | |
| } | |
| const pageFiles = await response.json(); | |
| if (!Array.isArray(pageFiles) || pageFiles.length === 0) break; | |
| files.push(...pageFiles.map((file) => normalizePath(file.filename)).filter(Boolean)); | |
| if (pageFiles.length < 100) break; | |
| } | |
| return files; | |
| } | |
| const files = await listChangedFiles(); | |
| const runCoverage = files.length === 0 || files.some((file) => !isCoverageIgnoredPath(file)); | |
| appendFileSync(process.env.GITHUB_OUTPUT, `run_coverage=${runCoverage ? "true" : "false"}\n`); | |
| if (runCoverage) { | |
| console.log(`Coverage required for ${files.length} changed file(s).`); | |
| } else { | |
| console.log("Coverage skipped for content/docs/markdown-only PR."); | |
| } | |
| NODE | |
| - name: Skip coverage for content/docs/markdown-only PR | |
| if: ${{ github.event_name == 'pull_request' && steps.coverage-scope.outputs.run_coverage != 'true' }} | |
| run: echo "No code files changed; coverage check passes without running the test suite." | |
| - name: Checkout | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup pnpm | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| uses: pnpm/action-setup@4f4305e1fe60ad818b8ae6fc4a697cc47eab0b2d | |
| - name: Setup Node.js | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f | |
| with: | |
| node-version: 24.17.0 | |
| cache: pnpm | |
| - name: Install dependencies | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| run: pnpm install --frozen-lockfile | |
| - name: Prepare test reports dir | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| run: rm -rf reports/junit && mkdir -p reports/junit | |
| # EXPERIMENT: cache the generated prebuild artifacts. Key hashes every | |
| # input to `prebuild` (content, the build script, registry builder source, | |
| # routes, prettier via the lockfile). A hit restores the artifacts and the | |
| # build step below is skipped. Because content/** changes on nearly every | |
| # merge, this only hits across runs that share an identical content | |
| # snapshot — in practice, re-pushes of the same code PR (the iterate loop). | |
| # Note: prebuild also derives entry `updatedAt` from `git log -- content`; | |
| # a hit requires byte-identical content, so within a non-rebased PR the git | |
| # history (and thus updatedAt) is identical too. The display timestamp can | |
| # only go stale in the rare case of byte-identical content with a different | |
| # commit touch-history, which is acceptable for a non-required lane. | |
| - name: Restore prebuild artifacts | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| id: prebuild-cache | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: | | |
| apps/web/public/data | |
| apps/web/src/generated | |
| apps/web/src/routeTree.gen.ts | |
| key: prebuild-v1-${{ runner.os }}-${{ hashFiles('content/**', 'scripts/build-content-index.mjs', 'packages/registry/src/**', 'packages/registry/package.json', 'apps/web/src/routes/**', 'pnpm-lock.yaml') }} | |
| - name: Build registry artifacts | |
| if: ${{ (github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true') && steps.prebuild-cache.outputs.cache-hit != 'true' }} | |
| run: pnpm --filter web run prebuild | |
| - name: Apply local D1 migrations | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| run: pnpm --filter web db:migrate:local | |
| - name: Run Vitest suite with coverage | |
| if: ${{ github.event_name != 'pull_request' || steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| run: pnpm test:coverage | |
| - name: Upload coverage to Codecov (pull request) | |
| if: ${{ github.event_name == 'pull_request' && steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 | |
| with: | |
| files: ./coverage/lcov.info | |
| fail_ci_if_error: false | |
| - name: Upload coverage to Codecov (trusted) | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage/lcov.info | |
| fail_ci_if_error: false | |
| - name: Upload Vitest results to Codecov (pull request) | |
| if: ${{ !cancelled() && github.event_name == 'pull_request' && steps.coverage-scope.outputs.run_coverage == 'true' }} | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 | |
| with: | |
| files: ./reports/junit/vitest.xml | |
| report_type: test_results | |
| fail_ci_if_error: false | |
| - name: Upload Vitest results to Codecov (trusted) | |
| if: ${{ !cancelled() && github.event_name != 'pull_request' }} | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./reports/junit/vitest.xml | |
| report_type: test_results | |
| fail_ci_if_error: false |