Skip to content

feat: add checkstyle, junit, sarif, gitlab-codequality and github-actions reports - #15

Merged
floriankraemer merged 3 commits into
mainfrom
feat/reports-b
Nov 12, 2026
Merged

floriankraemer merged 3 commits into
mainfrom
feat/reports-b

Conversation

@floriankraemer

Copy link
Copy Markdown
Owner

Summary

Adds five report types to analyse --report-type for CI tools and code hosts: checkstyle, junit, sarif, gitlab-codequality and github-actions.
Each one lists the methods whose score is above scoreThreshold.

  • Checkstyle XML (8.0), one file element per file, severity error at twice the threshold or more.
  • JUnit XML, every method a test case, methods above the threshold as failures.
  • SARIF 2.1.0 with the rule cognitive-complexity, levels error and warning, and a primaryLocationLineHash fingerprint.
  • GitLab Code Quality JSON, severity by ratio: blocker from 3, critical from 2, major from 1.5, minor otherwise.
  • GitHub Actions workflow commands, escaped as the runner expects.

Paths are relative to the working directory with / separators when the file is below it, and absolute otherwise.
Nothing is stripped from a path, which fixes the leading-character bug of the PHP implementation (PHP #79).

The shared pieces live in ReportSupport: path normalisation, the violation filter, severity ratio checks, the issue message, the fingerprint, the JSON printer (now also used by JsonReport) and the XML serialiser.

Decisions

  • The fingerprint hashes the reported path, not the raw path as given.
    The reported path is stable across checkouts, so the fingerprint identifies a finding across CI machines.
  • The SARIF tool name is cognitive-analysis, the name of the command and the jar.
  • The version in the SARIF driver comes from jcca-build.properties and is left out when the build did not filter it in.
  • The GitLab info severity was dropped, because only violations reach the severity mapping and those are always above the threshold.

Test plan

  • Golden files for every format: violations at warning and error levels, no violations, and escaping of <, &, ", |, backslashes and non-ASCII names.
  • GitHub Actions escaping of %, line feeds, commas and colons in the file and the message.
  • Severity boundaries at exactly 1x, just above 1x, 1.5x, just below 2x, exactly 2x and exactly 3x of the threshold, in every format, plus a threshold of 0.3 where 0.3 * 3 is not exact.
  • Path normalisation: inside and outside the working directory, sibling directories with a common name prefix, ./ and dot-directory names, relative paths leaving the directory, and Windows-style separators.
  • SARIF structure parsed back with Jackson: schema, version, driver, rule, result fields, fingerprint as SHA-256 of path:line:class::method, and movement of the fingerprint when the line changes.
  • CLI end to end for every new type through App, with golden files, and the error message for an unknown type lists all names.
  • ./mvnw -B verify is green: JaCoCo line and branch coverage at or above 90%, PIT mutation score 99% on the configured packages.
  • The report package has 96.8% line and 95.9% branch coverage.

Docs: docs/Reports.md describes each format, and the README lists the report types.

…ions reports

CI tools and code hosts read violations in their own formats, so the analyse
command can now write them next to the existing JSON, CSV, HTML and Markdown.
Each format lists the methods whose score is above scoreThreshold.

Paths are relative to the working directory with / separators when the file
is below it, and absolute otherwise. Nothing is stripped from a path, which
fixes the leading-character bug of the PHP implementation.

Fingerprints are SHA-256 over the reported path, line, class and method, so
they identify a finding across runs on different machines. The SARIF tool
name is the product name cognitive-analysis, as in the command and the jar.
…ng PIT survivors

The help of --report-type listed a hardcoded subset of the formats. It now
completes from ReportType.commandNames(), so a new format shows up without an
edit to the command.

The SARIF goldens contained the build version of the tool driver, so every
version bump changed them. The version is masked before the comparison.

The null-message fallback in ReportWriter is a single expression now, so the
conditional PIT mutated is gone without changing the behaviour. The interrupt
path of the git wait is covered by a test that keeps the interrupt flag.
SARIF reads artifactLocation.uri as an RFC 3986 URI reference. Paths were
written raw, so a space, # or % in a directory name produced an invalid
location, and an absolute path was not a file URI.

Paths inside the working directory are now percent-encoded per segment
against the %SRCROOT% base, which run.originalUriBaseIds points at the
working directory as a file URI. Absolute paths outside it are file URIs,
Windows drive letters included, converted from the string so the result is
the same on every platform. The other formats keep the plain path.

A method line below one is reported as one, since the issue formats cannot
express a line before the first, which SARIF and GitLab reject.
@floriankraemer
floriankraemer merged commit 7e382fb into main Nov 12, 2026
1 check passed
@floriankraemer
floriankraemer deleted the feat/reports-b branch November 12, 2026 19:27
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