Skip to content

fix: node coverage#2904

Open
mitchspano wants to merge 2 commits into
aspect-build:mainfrom
mitchspano:fix/node_coverage
Open

fix: node coverage#2904
mitchspano wants to merge 2 commits into
aspect-build:mainfrom
mitchspano:fix/node_coverage

Conversation

@mitchspano

Copy link
Copy Markdown

Fixes #2901: bazel coverage reported 0% (empty coverage.dat) for JS tests whenever coverage postprocessing ran as its own action (--experimental_split_coverage_postprocessing, which is typical with remote execution).

The V8 -> lcov conversion ran in the _lcov_merger action, whose runfiles contain only the merger and node, not the instrumented sources, so c8 emitted LF:0 for every file. The conversion now runs at the end of the test action, where the V8 data and sources coexist; the report is stashed in $COVERAGE_DIR and the merger simply publishes it, falling back to the old behavior when no stash exists. Adding the sources to the merger action was considered instead, but the V8 URLs still point at the test's sandbox paths and would need fragile rewriting.


Changes are visible to end-users: yes

  • Searched for relevant documentation and updated as needed: no docs cover the coverage merger; none needed
  • Breaking change (forces users to change their own code or config): no
  • Suggested release notes appear below: yes

fix: bazel coverage no longer reports 0% for JS tests when coverage postprocessing runs as a separate action (#2901)

Test plan

  • New test cases added: e2e/coverage/test.sh runs bazel coverage in both the default and split-postprocessing modes and asserts the lcov report attributes hits and misses to lib.js. Fails against pre-fix sources (coverage.dat is missing or empty), passes with the fix.

Disclaimer: This is my first contribution on this project. I've read the code of conduct and the contributing guidelines, but if I made a mistake in the creation of this PR, please let me know! I'm happy to change the target branch or anything else that is required.

@CLAassistant

CLAassistant commented Jul 8, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b0ab821194

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

# the report produced here.
# ==============================================================================
if [ "${COVERAGE_DIR:-}" ] && [ "${COVERAGE_OUTPUT_FILE:-}" ]; then
js_coverage_report=$(find "$JS_BINARY__RUNFILES" -path '*/js/private/coverage/coverage.js' 2>/dev/null | head -1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a single-match search for the coverage tool

When a covered js_test has more than one runfile matching */js/private/coverage/coverage.js (for example, the application also has a file at that path in its data), this find | head -1 pipeline can fail even after finding a match: the launcher runs with set -o pipefail, so head closing the pipe may make find exit with SIGPIPE/141, and the assignment then exits the wrapper under set -e before it returns the test result or writes coverage. Use find ... -print -quit or a known merger runfile path instead.

Useful? React with 👍 / 👎.

Comment on lines +496 to +497
"$JS_BINARY__NODE_BINARY" "$js_coverage_report" ||
logf_error "coverage report generation failed"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fail coverage when report generation fails

If the in-test c8 conversion fails here (bad manifest/source path, missing tool, or a tool crash), the launcher only logs the error and still exits with the test's original status. In split coverage postprocessing, the later merger is exactly the action that lacks the instrumented sources, so this can turn a coverage-generation failure back into a successful bazel coverage run with empty or stale coverage instead of surfacing the failure as the old merger path did.

Useful? React with 👍 / 👎.


# --- begin runfiles.bash initialization v3 ---
# Copy-pasted from the Bazel Bash runfiles library v3.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this need to change?

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.

[Bug]: bazel coverage reports 0% for jest_test on rules_js 3.x (works on 1.x)

3 participants