# Share a Checkstyle, PMD or SpotBugs Report

Canonical: https://commareports.com/share-checkstyle-report
Published: 2026-08-29

> Java static analysis writes HTML into build/reports and stops there. Publish it from CI so reviewers read findings at a URL — and argue with the rule on the finding, not in a Slack thread.

# Share a Checkstyle, PMD or SpotBugs report

Java static analysis has a distribution problem shaped exactly like Java
test reports. The tools produce readable HTML —
`build/reports/checkstyle/main.html` and friends — and that HTML is
visible to precisely one machine.

In CI it becomes an artifact zip. In practice, the whole apparatus
collapses down to a red X on a build, and the finding itself is never
read.

## Getting the HTML out

Under Gradle:

```groovy
checkstyle { toolVersion = '10.17.0' }

// SpotBugs writes XML by default — HTML has to be asked for.
tasks.withType(com.github.spotbugs.snom.SpotBugsTask) {
  reports {
    html.required = true
    xml.required = false
  }
}
```

```bash
./gradlew checkstyleMain pmdMain spotbugsMain || true
# → build/reports/checkstyle/main.html
# → build/reports/pmd/main.html
# → build/reports/spotbugs/main.html
```

Under Maven, the site lifecycle collects all three into `target/site/`.

Note the `|| true`. These tasks fail the build on violations, which is
usually what you want and always breaks a publish step that comes after
them.

## Publish it

```bash
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$CHECKSTYLE_REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html build/reports/checkstyle/main.html \
        --arg title "Checkstyle — $(git rev-parse --short HEAD)" \
        '{title: $title, html: $html}')"
```

Each of these is a **single self-contained file**, which is the shape that
publishes in one call — no assets to upload. Use a
[scoped token](/docs/api-tokens) (`reports:write`) from CI secrets, and
`PATCH` a saved id per tool so each keeps one permanent URL with a
revision per build. Make the step unconditional — `if: always()` in GitHub
Actions, `post { always { … } }` in Jenkins. See
[publishing from CI](/docs/ci).

For the Maven route, drop the whole `target/site/` folder into
[the app](https://commareports.com/) and the cross-links between the three
reports keep resolving.

## The part that actually matters: arguing with the rule

Failing a build on an agreed rule is fine and needs no report. The
findings that need a report are the other kind:

- **The rule that's wrong for this codebase.** Somebody has to say so
  once, with a reason, somewhere the next person will find it.
- **The legacy module with 400 violations** you're burning down over a
  quarter. That's a shared document with a trend, not a gate.
- **The finding a reviewer thinks is a false positive.** Suppress with a
  justification, or fix — either way the decision should be attached to
  the finding.

Published to a URL, all three happen **on the report**. Select the
violation, leave a thread, and it stays anchored there across builds. See
[commenting on HTML](/comment-on-html).

Revision diffs give the burndown honestly: two revisions, one diff, which
violations actually cleared.

## Who can see it

Per report: private, your team, anyone signed in at your domain, or anyone
with the link. A findings report names file paths and often quotes source
lines, so team or private is usually the right default (domain-gating is
Enterprise). See
[sharing & access control](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** A module with thousands of violations can exceed
  that — scope the report to changed files or to the higher severities,
  which is what gets read anyway. Assets: 25 MB per file, 250 MB and 500
  files total.
- **Scripts run, sandboxed** (`allow-scripts`, no `allow-same-origin`), so
  the reports' collapsible sections keep working.
- **60 requests/minute per token.**

## Try it

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

**[Publish a findings report →](https://commareports.com/)**

### Related

- [Share a SonarQube report](/share-sonarqube-report) · [Share a Semgrep report](/share-semgrep-report)
- [Share an ESLint report](/share-eslint-report) — the JS equivalent
- [Share a JaCoCo report](/share-jacoco-report) · [Share a Gradle test report](/share-gradle-test-report)
- [Publish from CI](/docs/ci) · [Jenkins HTML reports](/ci/jenkins-html-report)
