Skip to content

Fix empty modified-lines REST API by making exported beans public - #786

Merged
uhafner merged 1 commit into
jenkinsci:mainfrom
jeppeman:fix/modified-lines-api-empty-files
Jul 24, 2026
Merged

Fix empty modified-lines REST API by making exported beans public#786
uhafner merged 1 commit into
jenkinsci:mainfrom
jeppeman:fix/modified-lines-api-empty-files

Conversation

@jeppeman

Copy link
Copy Markdown
Contributor

The modified-lines coverage REST API (.../coverage/modified/api/json) returns a response
with no files array on recent Jenkins cores, even though the coverage data is computed
and stored correctly:

{"_class":"io.jenkins.plugins.coverage.metrics.restapi.ModifiedLinesCoverageApi"}

Root cause: the classes backing this endpoint — ModifiedLinesCoverageApi,
FileWithModifiedLines, ModifiedLinesBlock, and the LineCoverageType enum — and their
@Exported getters are package-private. Recent Stapler releases only export @Exported
members that are public, so ModelBuilder finds zero exported properties and the
files property is silently dropped. Older Stapler reflected non-public members, which is
why this regressed on a Jenkins core upgrade without any change to the plugin:

Jenkins core Bundled Stapler files in response
2.511 1983.v93c53e94b_c04 present ✅
2.555.3 2076.v1b_ac12445eb_e missing ❌

The visibility was reduced in cc8cdbd7 ("visibility changes in restapi package"); the
defect stayed latent until Stapler's behavior tightened.

Fix: make the four types and their @Exported accessors public.

Fixes #785

Testing done

Added ModifiedLinesCoverageApiTest#shouldExportModifiedLinesAsJson, which serializes the
bean through the same Stapler export path the endpoint uses (ModelBuilder +
Flavor.JSON) and asserts a non-empty files array. Verified it fails on the
package-private code and passes with the visibility fix:

  • Unpatched (package-private): Different value found in node "files", expected: <array> but was: <missing>
  • Patched (public): all 4 tests in the class pass

The existing integration test that exercises this endpoint
(GitForensicsITest#verifyModifiedLinesCoverageApi) is currently @Disabled, so this
path had no active coverage — which is why the regression wasn't caught.

Also manually reproduced end-to-end: on Jenkins 2.555.3 with coverage
3.3278.va_04d3e352354, a build whose stored coverage data contains modified lines
(confirmed via filterByModifiedLines().getAllFileNodes()) returned an empty response
from /coverage/modified/api/json; after installing a locally built plugin with this fix,
the same build returned the fully populated files array.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and
    not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests that demonstrate the feature works or the issue is
    fixed

@github-actions
github-actions Bot requested a review from uhafner July 20, 2026 07:37
@jeppeman
jeppeman force-pushed the fix/modified-lines-api-empty-files branch from 42e53db to 4d1905e Compare July 20, 2026 07:45
The modified-lines coverage REST API (.../coverage/modified/api/json)
returns a response without the `files` array on recent Jenkins cores,
even though the coverage data is computed and stored correctly.

The classes backing the endpoint in the restapi package
(ModifiedLinesCoverageApi, FileWithModifiedLines, ModifiedLinesBlock and
the LineCoverageType enum) and their @exported getters were
package-private. Recent Stapler releases only export @exported members
that are public, so ModelBuilder finds zero exported properties and the
`files` property is silently dropped. Older Stapler reflected non-public
members, which is why this regressed on a core upgrade without any change
to the plugin.

Make the four types and their @exported accessors public, and add a
serialization-level regression test that exercises the Stapler export
layer (the existing endpoint integration test in GitForensicsITest is
@disabled, so this path was untested).

Fixes jenkinsci#785
@jeppeman
jeppeman force-pushed the fix/modified-lines-api-empty-files branch from 4d1905e to 0aa9417 Compare July 23, 2026 13:06
@github-actions

Copy link
Copy Markdown

☀️   Quality Monitor

Tests

   JUnit   Unit Tests: ✅ successful — 221 passed $\color{green}{\textsf{(+1)}}$
   🚀   Integration Tests: ✅ successful — 157 passed $\textsf{(±0)}$, 7 skipped $\textsf{(±0)}$
   ⛔   Architecture Tests: ✅ successful — 15 passed $\textsf{(±0)}$

Coverage for New Code

   〰️   Line Coverage: 100.00% — perfect 🎉
   ➰   Branch Coverage: 100.00% — perfect 🎉

Coverage for Whole Project

   〰️   Line Coverage: 77.00% $\textsf{(±0)}$ — 714 missed lines
   ➰   Branch Coverage: 67.38% $\textsf{(±0)}$ — 288 missed branches

Style

   CheckStyle   CheckStyle: No warnings $\textsf{(±0)}$
   PMD   PMD: No warnings $\textsf{(±0)}$
   ☕   Java Compiler: No warnings $\textsf{(±0)}$

Bugs

   SpotBugs   SpotBugs: No bugs $\textsf{(±0)}$
   🐛   Error Prone: No bugs $\textsf{(±0)}$

Vulnerabilities

   🛡️   OWASP Dependency Check: 255 vulnerabilities $\color{green}{\textsf{(+255)}}$ — error: 17, high: 78, normal: 151, low: 9

Software Metrics

   🌀   Cyclomatic Complexity: 1039 (total)
   💭   Cognitive Complexity: 569 (total)
   ➿   N-Path Complexity: 1394 (total)
   📏   Lines of Code: 12175 (total)
   📝   Non Commenting Source Statements: 4106 (total)
   🔗   Class Cohesion: 100.00% (maximum)
   ⚖️   Weight of Class: 100.00% (maximum)

📌 Reference Results

Delta reports computed against the reference results of 0181950 in workflow run 29743580601.

🚦 Quality Gates

Overall Status: ✅ SUCCESS

✅ Passed Gates

  • ✅ Overall Tests Success Rate: 100.00 >= 100.00
  • ✅ Line Coverage in New Code: 100.00 >= 90.00
  • ✅ Branch Coverage in New Code: 100.00 >= 90.00
  • ✅ Potential Bugs in Whole Project: 0.00 <= 0.00
  • ✅ Style Violation in Whole Project: 0.00 <= 0.00

Created by Quality Monitor v4.15.0 (#82d77af). More details are shown in the GitHub Checks Result.

@uhafner uhafner added the bug Bugs or performance problems label Jul 24, 2026

@uhafner uhafner left a comment

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.

Thanks!

@uhafner
uhafner merged commit f8df161 into jenkinsci:main Jul 24, 2026
31 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bugs or performance problems

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Modified lines coverage REST API (/coverage/modified/api/json) returns empty "files" on recent Jenkins cores

2 participants