Skip to content

fix: address review feedback on lost-lines feature - #5

Draft
Zadjil-AR with Copilot wants to merge 44 commits into
mainfrom
copilot/feat-report-line-coverage-loss
Draft

Zadjil-AR with Copilot wants to merge 44 commits into
mainfrom
copilot/feat-report-line-coverage-loss

Conversation

Copilot AI commented Mar 12, 2026 •

Copy link
Copy Markdown
  • Fix src/utils.ts: use default value when setting is not supplied, not a number, or less than 1 (for both lostLinesMergeBaseSearchSteps and lostLinesMergeBaseMaxDepth)
  • Fix src/functions.ts: only show lost_coverage when lostCount > 0 (not for zero-loss files from buildLostLinesByFile)
  • Fix src/functions.ts: correct prettier formatting on formatLostCoverage call (indentation)
  • Fix src/reports/cobertura/parser/index.ts: only parse @_number when covered_lines !== undefined AND inside the hits > 0 block
  • Update Plans/lost-lines-feature.md: fresh PR description covering the final state of changes vs main
  • Rebuild dist/index.js
  • Add 8 new tests in __tests__/utils.test.ts covering default-value logic for lostLinesMergeBaseSearchSteps and lostLinesMergeBaseMaxDepth
Original prompt

This section details on the original issue you should resolve

<issue_title>Feat: Report of line coverage lost</issue_title>
<issue_description>## Aim
This code provides an action that is run in other repos when working on prs.

When producing the code coverage of a PR where the target branch has a baseline code coverage artifact, the pr's new code coverage report and artifact should include a list of all the lines that used to be covered and are no longer covered.

Details

To determine if a line was previously covered, the artifact of the target will have a list of either all of the lines covered by tests or all the lines not covered. The option used should keep the amount of data to a minimum and the amount of processing to a minimum. Consider using ranges of line numbers.

In the action code that this repo provides to others, use the git diff between the pr and the target branch. Ensure to follow moved files. Make sure any parameters used in the command are validated and/or escaped.
Make use of the information in the diff of each file to establish the new line numbers for all the lines that existed in the code on the target.
With the mapping of the line numbers from target to current pr code it's possible to establish any line that was covered and is no longer covered.

Do not consider permanently deleted lines as loss in cover.

Report the loss of lines as a negative percentage of lines originally covered. This should be done per class or file and overall. Use the existing tables rather than new tables.

If there are lost lines, list the first 5 blocks/ranges and make sure that all blocks/ranges are stored in the artifacts.

Use a flag to enable the lost lines feature. If not set then the action should behave as it would before this feature was introduced. This is both the base artifact and the pr comparison.

Before making a change get existing code coverage. Ensure that code coverage doesn't go down with new code. Aim for 100% coverage.

Where practical encapsulate functionality into methods rather than have long methods doing many things. These smaller methods should have unit tests.

Task

Create a folder called "Plans".
Create a markdown file for this issue.
Update the file with the plan to achieve the aim above.
Validate the plan with a different model than used to make it.
Make no changes to existing code until asked for in the PR review.
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Copilot AI changed the title [WIP] Add report of line coverage lost for PRs feat: track and report lines that lost test coverage across PRs Mar 12, 2026
Comment thread templates/with-base-coverage.hbs Resolved
Comment thread Plans/lost-lines-feature.md Resolved
Comment thread Plans/lost-lines-feature.md Resolved
…ix top-dir template

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Copilot AI requested a review from Zadjil-AR March 12, 2026 22:21
Comment thread templates/with-base-coverage.hbs Resolved
Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Copilot AI changed the title feat: track and report lines that lost test coverage across PRs revert: restore Lost Lines format to 🔴 5% (3 lines) Mar 13, 2026
Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Copilot AI changed the title revert: restore Lost Lines format to 🔴 5% (3 lines) revert: restore Lost Lines format to 🔴 5% (3 lines) and compact snapshots Mar 14, 2026
Copilot AI requested a review from Zadjil-AR March 14, 2026 09:38
@Zadjil-AR
Zadjil-AR requested a review from Copilot March 14, 2026 10:36

Copilot AI 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.

Pull request overview

Adds an optional “lost covered lines” regression report to the action by persisting per-file covered line numbers in artifacts, diffing base vs PR head line mappings via git diff, and surfacing results in the existing markdown tables (plus compacted Jest snapshots).

Changes:

  • Introduces track_lost_lines input, covered-lines artifact (coverage-lines.json), and lost-lines computation (git diff parsing + line mapping).
  • Extends Cobertura/Clover parsing to capture covered_lines, and updates markdown template/context to render a “Lost Lines” column and details block.
  • Adds a Jest snapshot serializer to compact large number[] arrays and regenerates snapshots/tests accordingly.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
templates/with-base-coverage.hbs Adds “Lost Lines” column and a details section to the base-coverage report template.
src/utils.ts Adds trackLostLines input + covered-lines JSON read/write helpers and constants.
src/reports/cobertura/parser/index.ts Collects per-file covered line numbers from Cobertura line hits.
src/reports/clover/parser/index.ts Collects per-file covered line numbers from Clover <line> elements.
src/lost-lines.ts New module: git diff execution/parsing, line mapping, and lost-lines report computation.
src/interfaces.ts Adds covered_lines and new Lost Lines report interfaces + handlebars context fields.
src/functions.ts Wires the feature into action flow, artifact upload, markdown generation, and formatting.
jest.config.js Registers a custom snapshot serializer.
action.yml Adds the track_lost_lines action input.
tests/utils.test.ts Adds tests for covered-lines map + JSON round-trip and input parsing.
tests/run.test.ts Adds run-path tests for track_lost_lines behavior and mocks lost-lines module.
tests/number-array-serializer.js New serializer intended to render number[] with 20 items per line.
tests/lost-lines.test.ts Adds unit tests for diff parsing, mapping, and lost-lines computations.
tests/functions.test.ts Updates/extends markdown tests for lost-lines display and helper formatting.
tests/snapshots/utils.test.ts.snap Regenerates snapshots to include covered_lines (and compact formatting).
Plans/lost-lines-feature.md Documents the intended design/plan for the lost-lines feature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread templates/with-base-coverage.hbs Resolved
Comment thread src/reports/clover/parser/index.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/reports/clover/parser/index.ts Resolved
Comment thread src/lost-lines.ts Resolved
Comment thread src/lost-lines.ts Resolved
Comment thread __tests__/number-array-serializer.js Resolved
Comment thread __tests__/functions.test.ts Resolved
Comment thread __tests__/lost-lines.test.ts Resolved
Comment thread src/reports/cobertura/parser/index.ts Resolved
Copilot AI and others added 15 commits March 17, 2026 10:00
…n baseRef not in history

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
… changes

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…build dist

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…ld dist

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
… Number.parseInt

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…ch check to hasMergeBase

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…erge-base resolution

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…ote-tracking refs

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…es from remote-tracking refs

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…ront guard and first logGitDebugInfo

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…ent, rebuild dist

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
… directly (#6)

This change eliminates the intermediate coverage-lines.json file and uses
the Coverage object directly for better performance and simpler code.

Changes:
- Removed writeCoveredLinesFile, readCoveredLinesFile, and COVERED_LINES_FILENAME from utils.ts
- Removed coveredLinesToRangesTuples, rangeTuplesToLines, and isValidRangeTuples helper functions
- Removed CoveredLinesFile interface
- Updated computePrLostLinesReport to accept baseCoverage instead of artifactPath
- Updated computePrLostLinesReport to use buildCoveredLinesMap(baseCoverage) directly
- Removed coverage-lines.json upload sections for both PR head branch and push/schedule events
- Updated tests to remove mock references to deleted functions
- Removed 8 test cases for deleted file I/O functions
- Updated 4 test cases to use buildCoveredLinesMap instead of readCoveredLinesFile
- Removed 2 test cases for writeCoveredLinesFile (no longer needed)
- Built dist folder with updated code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
…omments, code tidying, rebuild dist

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
…st, rebuild dist

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
@sonarqubecloud

Copy link
Copy Markdown

… when trackLostLines enabled

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Zadjil-AR/code-coverage-report-action/sessions/863537ef-0399-4367-9c19-70fbe4289540

Copilot AI 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.

Pull request overview

Copilot reviewed 22 out of 26 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lost-lines.ts Resolved
Comment thread action.yml Resolved
Comment thread __tests__/run.test.ts Resolved
Comment thread __tests__/lost-lines.test.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/lost-lines.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/functions.ts Resolved

@Zadjil-AR Zadjil-AR left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot @copilot Ensure that the pr description is not changed. Update the dist folder.

Comment thread action.yml Resolved
Comment thread __tests__/run.test.ts Resolved
Comment thread __tests__/lost-lines.test.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/lost-lines.ts Resolved
Comment thread src/functions.ts Resolved
…nator fix, test improvements

Co-authored-by: Zadjil-AR <64791169+Zadjil-AR@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Zadjil-AR/code-coverage-report-action/sessions/d593ab6e-3cd9-4c7f-abca-b42b2c4856b5

Copilot AI 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.

Pull request overview

Copilot reviewed 22 out of 26 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/functions.ts Resolved
Comment thread src/functions.ts Resolved
Comment thread src/lost-lines.ts Resolved
Comment thread src/lost-lines.ts Resolved
@github-actions

Copy link
Copy Markdown

Code Coverage Report

Code Coverage

Package Base Coverage New Coverage Difference
functions.ts 🟢 94.67% 🟢 95.46% 🟢 0.79%
lost-lines.ts 🔴 0% 🟢 99.61% 🟢 99.61%
reports/clover/index.ts 🟢 100% 🟢 100% ⚪ 0%
reports/clover/parser/index.ts 🟢 96.34% 🟢 96.64% 🟢 0.3%
reports/clover/types/index.ts 🟢 100% 🟢 100% ⚪ 0%
reports/cobertura/index.ts 🟢 100% 🟢 100% ⚪ 0%
reports/cobertura/parser/index.ts 🟢 76.47% 🟢 87.02% 🟢 10.55%
reports/cobertura/types/index.ts 🟢 100% 🟢 100% ⚪ 0%
utils.ts 🟢 94.23% 🟢 94% 🔴 -0.23%
Overall Coverage 🟢 93.24% 🟢 95.25% 🟢 2.01%

Minimum allowed coverage is 70%, this run produced 95.25%

Copilot AI 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.

Pull request overview

Copilot reviewed 22 out of 26 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/reports/cobertura/parser/index.ts Outdated
Comment on lines +124 to +131
const num = Number.parseInt(
(line as { '@_number'?: string })['@_number'] ?? '0',
10
);
if (hits > 0) {
lines_covered += 1;
if (covered_lines !== undefined && num > 0) {
covered_lines.push(num);

Copilot AI Mar 22, 2026

Copy link

Choose a reason for hiding this comment

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

countLines() parses the line @_number for every entry even when trackLostLines is false. This adds per-line work even with the feature flag disabled; consider only parsing @_number (and only for hits > 0) when trackLostLines is enabled.

Suggested change
const num = Number.parseInt(
(line as { '@_number'?: string })['@_number'] ?? '0',
10
);
if (hits > 0) {
lines_covered += 1;
if (covered_lines !== undefined && num > 0) {
covered_lines.push(num);
if (hits > 0) {
lines_covered += 1;
if (covered_lines !== undefined) {
const num = Number.parseInt(
(line as { '@_number'?: string })['@_number'] ?? '0',
10
);
if (num > 0) {
covered_lines.push(num);
}

Copilot uses AI. Check for mistakes.
Comment thread src/functions.ts Outdated
Comment on lines +398 to +400
lost_coverage: lostEntry
? formatLostCoverage(lostEntry.lostCount, lostEntry.lostPercentage)
: undefined

Copilot AI Mar 22, 2026

Copy link

Choose a reason for hiding this comment

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

buildLostLinesByFile() now adds zero-loss entries to support correct directory denominators, but here the per-file row renders lost_coverage for any lostEntry (including lostCount=0). This will show misleading values like "🔴 -0% (0 lines)" for files with no lost lines. Only set lost_coverage when lostEntry.lostCount > 0 (or when lostPercentage > 0).

Suggested change
lost_coverage: lostEntry
? formatLostCoverage(lostEntry.lostCount, lostEntry.lostPercentage)
: undefined
lost_coverage:
lostEntry &&
(lostEntry.lostCount > 0 || lostEntry.lostPercentage > 0)
? formatLostCoverage(
lostEntry.lostCount,
lostEntry.lostPercentage
)
: undefined

Copilot uses AI. Check for mistakes.
Comment thread src/utils.ts Resolved
Comment thread src/utils.ts Resolved

@Zadjil-AR Zadjil-AR left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot Apply the comments in the review

Comment thread src/utils.ts Outdated
Comment on lines +563 to +577
const lostLinesMergeBaseSearchSteps = Math.max(
1,
Number.parseInt(
core.getInput('lost_lines_merge_base_search_steps') || '10',
10
) || 10
);

const lostLinesMergeBaseMaxDepth = Math.max(
lostLinesMergeBaseSearchSteps,
Number.parseInt(
core.getInput('lost_lines_merge_base_max_depth') || '512',
10
) || 512
);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Update the logic so that the default value is used when: 1) the setting is not supplied. 2) the setting supplied is not a number. 3) the setting supplied is less than 1.

Comment thread src/functions.ts Outdated
Comment on lines +398 to +400
lost_coverage: lostEntry
? formatLostCoverage(lostEntry.lostCount, lostEntry.lostPercentage)
: undefined

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The output should show a empty space if there are no lines lost for the entry. It should not show a zero value. See the comment #5 (comment)

Comment thread src/reports/cobertura/parser/index.ts Outdated
Comment on lines 124 to 133
const num = Number.parseInt(
(line as { '@_number'?: string })['@_number'] ?? '0',
10
);
if (hits > 0) {
lines_covered += 1;
if (covered_lines !== undefined && num > 0) {
covered_lines.push(num);
}
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Follow the comments in #5 (comment)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Create a brand new description for the PR to add the final changes that came to resolve the feature #4. Ignore all the intermediate changes and revisions. ONLY consider the final set of code in relation to the code in the main branch. Do not assume reader has access to the issue. Structure the description with what it is trying to achieve, how the feature is used by others, any implications of the change and key aspects of the code change.

Comment thread dist/index.js

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Update the dist folder

Comment thread __tests__/utils.test.ts

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Increase the test coverage on utils.ts

@sonarqubecloud

Copy link
Copy Markdown

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.

Feat: Report of line coverage lost

4 participants