diff --git a/.github/workflows/coverage-report.yml b/.github/workflows/coverage-report.yml new file mode 100644 index 000000000..4b8073f79 --- /dev/null +++ b/.github/workflows/coverage-report.yml @@ -0,0 +1,79 @@ +name: Coverage Report + +on: + workflow_call: + +jobs: + report: + name: Report + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Download coverage artifact + uses: actions/download-artifact@v7 + with: + name: coverage + path: coverage/ + + # On push to main, deploy HTML coverage report to GitHub Pages + - name: Deploy coverage to GitHub Pages + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./coverage + destination_dir: coverage + + # On PRs, fetch baseline coverage from GitHub Pages + - name: Fetch baseline coverage from GitHub Pages + if: github.event_name == 'pull_request' + run: | + mkdir -p coverage-base + curl -fsSL https://metamask.github.io/ocap-kernel/coverage/coverage-summary.json \ + -o coverage-base/coverage-summary.json || { echo "No baseline coverage found"; exit 1; } + + - name: Post coverage report + if: github.event_name == 'pull_request' + uses: davelosert/vitest-coverage-report-action@5b6122e3a819a3be7b27fc961b7faafb3bf00e4d + with: + json-summary-path: coverage/coverage-summary.json + json-final-path: coverage/coverage-final.json + json-summary-compare-path: coverage-base/coverage-summary.json + file-coverage-mode: changes + + - name: Post coverage report link + if: github.event_name == 'pull_request' + uses: actions/github-script@v8 + with: + script: | + const marker = ''; + const body = `${marker}\nšŸ“Š [View full HTML coverage report for \`main\`](https://metamask.github.io/ocap-kernel/coverage/)`; + + const { data: comments } = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + }); + + const existing = comments.find(c => c.body?.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ + comment_id: existing.id, + owner: context.repo.owner, + repo: context.repo.repo, + body, + }); + } else { + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body, + }); + } diff --git a/.github/workflows/lint-build-test.yml b/.github/workflows/lint-build-test.yml index 3a6224dce..a284413a3 100644 --- a/.github/workflows/lint-build-test.yml +++ b/.github/workflows/lint-build-test.yml @@ -108,7 +108,14 @@ jobs: env: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - run: yarn build - - run: yarn test:ci + - run: "yarn test --coverage=${{ matrix.node-version == '24.x' && 'true' || 'false' }}" + - name: Upload coverage artifact + if: ${{ matrix.node-version == '24.x' }} + uses: actions/upload-artifact@v6 + with: + name: coverage + path: coverage/ + retention-days: 7 - name: Require clean working directory shell: bash run: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0759a9864..cc4089d2a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,6 +58,15 @@ jobs: needs: check-workflows uses: ./.github/workflows/lint-build-test.yml + coverage-report: + name: Coverage report + needs: lint-build-test + if: github.event_name != 'merge_group' + uses: ./.github/workflows/coverage-report.yml + permissions: + contents: write + pull-requests: write + is-release: name: Determine whether this is a release merge commit needs: lint-build-test diff --git a/package.json b/package.json index 116aebe09..54051f466 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,8 @@ "lint:misc": "prettier --no-error-on-unmatched-pattern '**/*.json' '**/*.md' '**/*.html' '**/*.yml' '!**/CHANGELOG.old.md' '!.yarnrc.yml' '!CLAUDE.md' '!merged-packages/**' --ignore-path .gitignore --log-level error", "postinstall": "simple-git-hooks && yarn rebuild:native", "prepack": "./scripts/prepack.sh", - "pretest": "bash scripts/reset-coverage-thresholds.sh", "rebuild:native": "./scripts/rebuild-native.sh", - "test": "yarn pretest && vitest run", - "test:ci": "vitest run --coverage false", + "test": "vitest run", "test:dev": "turbo run test:dev", "test:dev:quiet": "turbo run test:dev:quiet --output-logs=errors-only", "test:e2e": "yarn workspaces foreach --all run test:e2e", diff --git a/scripts/reset-coverage-thresholds.sh b/scripts/reset-coverage-thresholds.sh deleted file mode 100755 index 76306ff4f..000000000 --- a/scripts/reset-coverage-thresholds.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# Find the vitest.config.ts file -CONFIG_FILE="vitest.config.ts" - -# Create a temporary file -TMP_FILE=$(mktemp) - -# Process the file -awk ' - /statements:/ { sub(/statements: [0-9.]+,/, "statements: 0,") } - /functions:/ { sub(/functions: [0-9.]+,/, "functions: 0,") } - /branches:/ { sub(/branches: [0-9.]+,/, "branches: 0,") } - /lines:/ { sub(/lines: [0-9.]+,/, "lines: 0,") } - { print } -' "$CONFIG_FILE" > "$TMP_FILE" - -# Replace original file with modified content -mv "$TMP_FILE" "$CONFIG_FILE" diff --git a/vitest.config.ts b/vitest.config.ts index db10f7441..fe602d389 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -49,7 +49,7 @@ export default defineConfig({ coverage: { enabled: true, provider: 'v8', - reporter: ['text', 'json', 'html'], + reporter: ['text', 'json', 'json-summary', 'html'], reportsDirectory: './coverage', include: ['**/src/**/*.{ts,tsx}'], exclude: [ @@ -60,135 +60,6 @@ export default defineConfig({ '**/*.{test,spec}.{ts,tsx,js,jsx}', path.join(import.meta.dirname, './packages/brow-2-brow/**'), ], - thresholds: { - autoUpdate: true, - 'packages/cli/**': { - statements: 52.32, - functions: 53.57, - branches: 68.88, - lines: 52.63, - }, - 'packages/create-package/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, - }, - 'packages/extension/**': { - statements: 1.29, - functions: 0, - branches: 0, - lines: 1.31, - }, - 'packages/kernel-agents/**': { - statements: 88.16, - functions: 80, - branches: 75.38, - lines: 88.13, - }, - 'packages/kernel-browser-runtime/**': { - statements: 84.31, - functions: 78.3, - branches: 81.81, - lines: 84.55, - }, - 'packages/kernel-errors/**': { - statements: 99.24, - functions: 97.29, - branches: 96, - lines: 99.21, - }, - 'packages/kernel-language-model-service/**': { - statements: 99, - functions: 100, - branches: 94.11, - lines: 98.97, - }, - 'packages/kernel-platforms/**': { - statements: 99.28, - functions: 100, - branches: 91.89, - lines: 99.26, - }, - 'packages/kernel-rpc-methods/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, - }, - 'packages/kernel-shims/**': { - statements: 0, - functions: 0, - branches: 0, - lines: 0, - }, - 'packages/kernel-store/**': { - statements: 98.37, - functions: 100, - branches: 91.42, - lines: 98.36, - }, - 'packages/kernel-ui/**': { - statements: 95.03, - functions: 95.83, - branches: 87.53, - lines: 95.11, - }, - 'packages/kernel-utils/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, - }, - 'packages/logger/**': { - statements: 98.66, - functions: 96.66, - branches: 97.36, - lines: 100, - }, - 'packages/nodejs/**': { - statements: 86.84, - functions: 83.33, - branches: 87.09, - lines: 87.61, - }, - 'packages/nodejs-test-workers/**': { - statements: 23.52, - functions: 25, - branches: 25, - lines: 25, - }, - 'packages/ocap-kernel/**': { - statements: 94.05, - functions: 96, - branches: 86.51, - lines: 94.06, - }, - 'packages/omnium-gatherum/**': { - statements: 4.16, - functions: 4.54, - branches: 0, - lines: 4.22, - }, - 'packages/remote-iterables/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, - }, - 'packages/streams/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, - }, - 'packages/template-package/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, - }, - }, }, }, });