Share a Maven site report

mvn site is the most underused command in the Maven toolchain. Point the report plugins at a project and it builds a single cross-linked site: Surefire test results, JaCoCo coverage, Checkstyle and SpotBugs findings, Javadoc, dependency analysis — all of it navigable from one index.

Then it writes the whole thing to target/site/ and the story ends. The official next step, mvn site-deploy, wants a configured distributionManagement site repository and credentials, which is a real amount of setup for an artifact most teams want per-branch and read once.

Build it

<reporting>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-report-plugin</artifactId>
    </plugin>
    <plugin>
      <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
    </plugin>
  </plugins>
</reporting>
mvn -Dmaven.test.failure.ignore=true site
# → target/site/index.html

-Dmaven.test.failure.ignore=true is the Maven equivalent of || true: without it a failing test ends the build before site runs, and the run you most want a report for produces none.

Drop the folder in

Drag target/site/ (or a zip) into Comma:

  • index.html becomes the report body — the page carrying the comment layer.
  • surefire-report.html, jacoco/, checkstyle.html, the dependency pages and the stylesheets upload alongside it, with relative references rewritten to the uploaded copies.
  • The cross-links between reports keep working, which is the specific thing that makes the Maven site worth publishing as a unit rather than as four separate files.

Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the sortable tables and collapsible sections behave.

From CI

mvn -Dmaven.test.failure.ignore=true site

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html target/site/index.html \
        --arg title "Project report — $(git rev-parse --short HEAD)" \
        '{title: $title, html: $html}')"

The API is JSON-only, so the sub-report pages go up through POST /api/v1/reports/$REPORT_ID/assets as base64 — one call per file, worth scripting once. See the API reference and publishing from CI.

PATCHing one saved id gives the project a permanent URL with a revision per build, so the link in the README resolves to the current state and any two builds are diffable.

Watch the asset count

This is the constraint that bites. A report holds 500 assets, and mvn site with the Javadoc report attached generates one page per class — past the limit on any non-trivial project.

Split it:

  • One report id for the build report — Surefire, JaCoCo, static analysis. That's the one people read per build.
  • A separate report id for Javadoc, published on release rather than per commit. See share Javadoc.

Or drop the Javadoc report from <reporting> and generate it separately, which most teams end up doing anyway.

Multi-module builds

mvn site on a reactor produces a site per module, cross-linked from the parent. Publishing the parent's target/site/ gives you the aggregate entry point; the module sites are separate directories, so either publish the modules under active review or use site:stage to assemble a single staged tree first:

mvn site site:stage -DstagingDirectory=$PWD/target/staging

Then publish target/staging/.

What the URL changes

  • One link covers the build. Tests, coverage and findings in one place, rather than four artifact paths in a wiki page.
  • Findings get argued with in place. Select the Checkstyle violation or the uncovered branch, leave a thread, and it stays anchored across builds. See commenting on HTML.
  • Revision diffs show the trend honestly — which tests and which violations actually changed.

Who can see it

Per report: private, your team, any signed-in user with the link, or public. The site quotes source and names internal packages, so team is the usual default. Domain-gating, password gates and expiring links are Enterprise. See sharing & access control.

Limits

  • Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total — the binding constraint here; split Javadoc out.
  • Scripts run, sandboxed — no same-origin access.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a Maven site →

Related