Skip to content

chore: migrate from nyc to c8 and enhance coverage reporting#3553

Open
eablack wants to merge 21 commits intov11.0.0from
eb/migrate-to-c8
Open

chore: migrate from nyc to c8 and enhance coverage reporting#3553
eablack wants to merge 21 commits intov11.0.0from
eb/migrate-to-c8

Conversation

@eablack
Copy link
Contributor

@eablack eablack commented Mar 3, 2026

Summary

Migrates test coverage tooling from nyc to c8 and significantly enhances coverage reporting in CI/CD workflows with automated PR comments showing coverage changes.

Type of Change

Patch Updates (patch semver update)

  • chore: Change that does not affect production code

Changes

Coverage Tool Migration

  • Replaced nyc with c8 for test coverage
  • Set .c8rc.json configuration file with 60% coverage thresholds for statements, branches, functions, and lines
  • Removed legacy nyc-config.js
  • Updated test scripts to use npx c8 with appropriate flags
  • CI tests use --all --check-coverage to enforce coverage thresholds across the entire codebase
  • Local test:file script provides focused coverage on individual test files

CI/CD Workflow Improvements

Separate Linting Job

  • Moved linting to its own parallel CI job for better performance
  • Runs once on ubuntu-latest + Node 22.x instead of 6 times across the matrix
  • Provides faster, clearer feedback on lint failures

Enhanced Coverage Reporting

  • Coverage Artifacts: Upload HTML coverage reports on PR runs (30-day retention)
  • Job Summary: Formatted coverage table displayed in GitHub Actions UI
  • Separate Coverage Workflow: Runs independently after main tests complete
    • Downloads coverage artifact from test run
    • Runs tests on base branch to establish baseline
    • Calculates coverage differences
    • Posts PR comment with comparison table
    • Visual indicators (🟢 for improvements, 🔴 for decreases)

Corporate Compliance

  • All coverage reporting uses native GitHub tooling (gh CLI, GitHub Actions)
  • No third-party actions required
  • Complies with corporate GitHub Actions policy

Benefits

  1. Faster CI execution - Linting and coverage reporting run in parallel
  2. Better visibility - Coverage metrics prominently displayed in Actions UI and PR comments
  3. Coverage tracking - Easy to see if PRs improve or degrade test coverage
  4. Efficient resource usage - Artifacts only uploaded on PR runs
  5. Non-blocking - Coverage comparison runs independently without slowing down main test feedback

Testing

Steps:

  1. Passing CI suffices
  2. Verify coverage artifacts are uploaded on PR runs
  3. Verify coverage summary appears in job summary
  4. Verify coverage workflow triggers and posts PR comment with comparison

Screenshots (if applicable)

N/A - Coverage reporting will be visible on this PR once CI completes

Related Issues

N/A

eablack added 6 commits March 3, 2026 10:20
- Replace nyc with c8 for better ESM and TypeScript support
- c8 uses native V8 coverage instead of instrumentation
- Remove @istanbuljs/nyc-config-typescript dependency
- Update test:unit:justTest:ci script to use c8

c8 provides more accurate coverage and better compatibility with
modern JavaScript (ESM) and TypeScript.
- Replace nyc-config.js with .c8rc.json for proper c8 configuration
- Update test scripts to use npx c8 with appropriate flags
- Add --all and --check-coverage flags to CI test script
- Configure test:file script for focused coverage on individual tests
- Move linting to separate CI job for better parallelization
- Add coverage artifact uploads and job summaries to CI
- Add automatic PR comments with coverage changes via lcov-reporter-action
Replace romeovs/lcov-reporter-action with custom script using gh CLI
to comply with corporate GitHub Actions policy. The script provides
the same functionality: posts coverage report as PR comment and
automatically deletes old comments.
Show coverage changes compared to base branch in PR comments.
Includes visual indicators (🟢/🔴) to highlight improvements
or decreases in coverage metrics.
Move PR coverage comments to a separate workflow that runs after
the main test workflow completes. This keeps the test workflow fast
while still providing detailed coverage comparison in PR comments.

Benefits:
- Main test workflow completes faster
- Coverage comparison runs independently
- Base branch tests don't block PR feedback
Add github.event_name == 'pull_request' condition to artifact upload
to avoid creating unnecessary artifacts on non-PR pushes.
@eablack eablack requested a review from a team as a code owner March 3, 2026 19:25
Remove extra indentation that was causing YAML parsing errors.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:28 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:28 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:28 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:28 — with GitHub Actions Inactive
Replace direct string assignment with heredoc syntax to prevent
YAML parser from treating markdown table pipes as YAML syntax.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:32 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:32 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:32 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:32 — with GitHub Actions Inactive
Replace multiline string assignments with printf to completely
avoid YAML parser issues with pipe characters in markdown tables.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:34 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:34 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:34 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 19:34 — with GitHub Actions Inactive
Temporarily reduce coverage thresholds from 80% to 60% to allow
tests to pass while coverage is being improved.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 20:11 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 20:11 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 20:11 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 20:11 — with GitHub Actions Inactive
Switch from workflow_run to pull_request trigger to avoid GITHUB_TOKEN
limitations. The workflow now polls the test workflow completion using
the GitHub API before downloading the coverage artifact and generating
the comparison comment.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 21:19 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 21:19 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:06 — with GitHub Actions Inactive
The previous approach tried to support both pull_request and push events
but hit IP allowlist restrictions when making GitHub API calls to lookup
PR information.

This commit simplifies the workflow to only run on pull_request events,
which provides all necessary context (PR number, base branch) without
needing any API calls. Coverage reports will update on pull_request
opened/synchronize events.

This avoids the IP allowlist issue entirely while still providing
comprehensive coverage reporting for all PR activity.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:35 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:35 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:35 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:35 — with GitHub Actions Inactive
The workflow was only triggering on push events, which meant
github.event_name was never 'pull_request', causing coverage jobs
to be skipped.

This adds pull_request to the workflow triggers so it runs on both:
- push events: runs lint, test, integration, acceptance (no coverage)
- pull_request events: runs all jobs including coverage reporting

This ensures coverage reports are generated and posted to PRs.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 22:44 — with GitHub Actions Inactive
Restricts push events to only trigger on main and v11.0.0 branches.
PRs will trigger via pull_request events, avoiding duplicate test runs.

This means:
- PR branches: run once via pull_request event (includes coverage)
- Main/v11.0.0: run via push event after merge
- No duplicate runs for PR branches

Added comments to guide adding long-lived feature branches if needed.
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 23:02 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 23:02 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 23:02 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 3, 2026 23:02 — with GitHub Actions Inactive
The base branch (v11.0.0) doesn't have c8 configured yet, so the
lcov.info file is empty, causing awk to fail with parse errors.

This adds error handling to:
- Default to "0" if coverage data is missing
- Check if base coverage exists before calculating diffs
- Show a simplified report without comparison if base coverage unavailable
- Include a note explaining that base branch doesn't have coverage yet

This allows the coverage workflow to succeed even when comparing against
branches without c8 configured.
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 00:20 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 00:20 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 00:20 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 00:20 — with GitHub Actions Inactive
Renames coverage-comment to coverage-check and replaces PR comment
functionality (blocked by IP allowlist) with a job that:
- Compares PR coverage against base branch coverage
- Outputs detailed comparison to job summary
- Fails the workflow if any coverage metric (lines, functions, branches) decreases
- Passes if base branch has no coverage configured

This ensures coverage never decreases while working around IP
allowlist restrictions that prevent posting PR comments.

Also fixes integer comparison error by using bash parameter
expansion to default empty values to "0".
@eablack eablack deployed to AcceptanceTests March 4, 2026 01:25 — with GitHub Actions Active
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 01:25 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 01:25 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests March 4, 2026 01:25 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant