This document describes the code coverage reporting system used in the TypeScript repository to track test coverage across the codebase. The system uses c8 (V8's native code coverage tool) to collect coverage data during test execution and integrates with Codecov for reporting and tracking over time.
For information about the test infrastructure that generates coverage data, see page 12.2. For details about the main CI pipeline where coverage reports are generated and uploaded, see page 13.1.
The TypeScript repository uses a two-layer coverage reporting system:
c8 tool instruments code during test execution and generates coverage reports in multiple formatsCoverage data is collected from both source TypeScript files and built JavaScript files, providing comprehensive visibility into which parts of the compiler are exercised by the test suite.
The coverage job in CI runs on a dedicated self-hosted runner and is triggered on every push and PR (but not on merge_group events). Coverage results are both archived as a GitHub Actions artifact and uploaded to Codecov.
Sources: .github/workflows/ci.yml132-164
The repository uses c8, a code coverage tool that leverages V8's built-in coverage instrumentation. Unlike Istanbul/nyc which perform AST-based instrumentation, c8 uses the JavaScript engine's native coverage capabilities. Coverage is activated by passing the --coverage flag to npm test, which is handled by the test runner harness.
Sources: .github/workflows/ci.yml151-152 .c8rc.json1-8
Diagram: c8 configuration structure showing all configuration properties and their relationships
Sources: .c8rc.json1-8
The c8 tool generates coverage reports in five different formats, each serving a specific purpose:
| Reporter | Format | Purpose |
|---|---|---|
lcovonly | LCOV tracefile | Standard format for coverage data, compatible with most coverage viewers |
cobertura | Cobertura XML | Used by some CI systems and coverage tools for parsing |
v8 | V8 coverage format | Raw V8 coverage data in text format |
v8-json | V8 JSON format | Raw V8 coverage data in JSON format for programmatic access |
codecov | Codecov format | Optimized format for Codecov upload |
These reporters are configured in .c8rc.json2 as an array of reporter names.
Sources: .c8rc.json2
The coverage system tracks two categories of files:
src/**): Original TypeScript source files in the repositorybuilt/local/**): Compiled JavaScript files that are actually executed during testsThis dual coverage approach ensures that:
The src property .c8rc.json3 designates the source directory, while the include array .c8rc.json4 specifies the exact patterns to match.
Sources: .c8rc.json3-4
The coverage system excludes **/node_modules/** from coverage reporting .c8rc.json5 This prevents third-party dependencies from being counted in coverage metrics, ensuring the metrics reflect only the TypeScript codebase itself.
Sources: .c8rc.json5
The mergeAsync: true option .c8rc.json6 enables asynchronous merging of coverage data from multiple processes. This is crucial for the TypeScript test suite, which may spawn child processes during test execution. The async merge ensures that coverage from all processes is properly aggregated into a single report.
Sources: .c8rc.json6
The following diagram maps the CI coverage job steps to the specific workflow definitions and tool invocations.
Sources: .github/workflows/ci.yml132-164 .c8rc.json1-8
The coverage job in .github/workflows/ci.yml132-164 has several notable properties:
| Property | Value | Reason |
|---|---|---|
| Runner | Self-hosted, 1ES.Pool=TypeScript-1ES-GitHub-Large, azure-linux-3 | Larger machine needed for full test suite with coverage overhead |
| Trigger condition | github.event_name != 'merge_group' | Coverage is skipped for merge queue runs to reduce latency |
| Node.js version | lts/* | Uses LTS for coverage consistency |
| Permissions | id-token: write, contents: read | OIDC token required for Codecov authentication |
The codecov/codecov-action uses OIDC (use_oidc: true) for authentication on non-fork PRs. OIDC is disabled for fork pull requests because the forked repository does not have access to the repository's OIDC token:
use_oidc: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }}
Coverage reports are uploaded as a GitHub Actions artifact named coverage from the coverage/ directory .github/workflows/ci.yml154-158 This allows downloading coverage data from any CI run without going through Codecov.
Only ./coverage/codecov.json is sent to Codecov (disable_search: true, files: ./coverage/codecov.json), preventing accidental upload of other report formats .github/workflows/ci.yml160-164
The Codecov service behavior is further configured through .github/codecov.yml1-15 (separate from the CI workflow):
| Setting | Value | Effect |
|---|---|---|
comment | false | No automatic PR comments from Codecov |
coverage.precision | 5 | Coverage reported to 5 decimal places |
coverage.status.patch.default.informational | true | Patch coverage does not block PR merges |
coverage.status.project.default.informational | true | Overall coverage drop does not block PR merges |
github_checks.annotations | false | No inline file annotations in Files Changed view |
Sources: .github/workflows/ci.yml132-164 .github/codecov.yml1-15
Both patch and project coverage checks are configured as informational: true in .github/codecov.yml6-11 This means:
This reflects that some legitimate changes (error handling paths, rarely-exercised branches) are difficult to cover mechanically, and coverage quality is better evaluated in code review than by a threshold.
Sources: .github/codecov.yml6-11
| Property | Type | Value | Purpose |
|---|---|---|---|
reporter | Array | ["lcovonly", "cobertura", "v8", "v8-json", "codecov"] | Output formats for coverage reports |
src | String | "src" | Source directory for coverage mapping |
include | Array | ["src/**", "built/local/**"] | File patterns to include in coverage |
exclude | Array | ["**/node_modules/**"] | File patterns to exclude from coverage |
mergeAsync | Boolean | true | Enable async merging of multi-process coverage |
Sources: .c8rc.json1-8
| Property | Type | Value | Purpose |
|---|---|---|---|
comment | Boolean | false | Disable PR comments |
coverage.precision | Integer | 5 | Decimal places for coverage percentages |
coverage.status.patch.default.informational | Boolean | true | Make patch coverage non-blocking |
coverage.status.project.default.informational | Boolean | true | Make project coverage non-blocking |
github_checks.annotations | Boolean | false | Disable inline annotations |
Sources: .github/codecov.yml1-15
The coverage reporting system is integrated into the main CI pipeline (see Main CI Pipeline). During CI execution:
c8 instrumentation enabledc8 generates reports in all configured formatsThis automated flow ensures that coverage data is collected and reported consistently for every CI run, providing continuous visibility into test coverage without requiring manual intervention.
Sources: .c8rc.json1-8 .github/codecov.yml1-15
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.