Skip to content

Put your Gradle test reports on a URL

Gradle's HTML test report already has everything a reviewer needs: which tests failed, their stdout, the stack traces. It's a website — serve it like one, straight from your workflow.

Drop your Gradle test report here — get a live link

free, no account, live for 30 days.

Shipping…

The artifact dead-end

When a Gradle build goes red, the log output is a wall of text and the useful report is zipped in artifacts. Reviewers either download it (they won't) or re-run locally (they really won't).

The report exists at build/reports/tests/test/ — a complete static site. The only thing missing between it and your team is a URL.

Two lines to a live link

Build your output like you already do, then hand the folder to the action:

Generate the report

./gradlew test

.github/workflows/ci.yml

- uses: bitgate/ship-page-action@v1
  if: always()
  with:
    engine: gradle-test

Or with plain curl — no account needed

cd build/reports/tests/test && zip -qr - . | curl -fsS -X POST https://ship.page/deploy   -H "Content-Type: application/zip"   --data-binary @- | jq -r .url

engine: gradle-test makes the action find build/reports/tests/test/ on its own — prefer explicit? path: build/reports/tests/test/ does the same thing. Omit both and every known report gets probed; two or more matches land behind one URL with a built-in switcher. The link goes in the job summary — add comment: true and it lands on the pull request too.

What you get

  • Failed-test pages, standard output and stack traces all render — the folder is served as-is
  • if: always() means the failing run is the one that publishes — the report you need most is never skipped
  • Multi-module builds: deploy each module's report folder, or omit path and let auto-detect find build/reports/tests/test/
  • Distributed and parallel builds are covered — every test task writes its own report folder, so each module can ship as its own named drop
  • The URL is the access control — viewers need no GitHub account or repo access, slugs are unguessable, and there's no public index

Questions

Does it handle multi-module projects?

Deploy the aggregate report, or run the action once per module with a name per module — each gets its own stable URL.

What about build scans?

Gradle build scans are great but require the Develocity/Gradle enterprise backend and send your build data there. This keeps the report on infrastructure you chose.

How long do links live?

Anonymous drops expire after 30 days. On a paid plan you control ttl — or set it to never expire.

Does this work with distributed or parallel Gradle builds?

Yes. Each test task writes its own report under build/reports/tests/ — run one action step per module with a distinct name (for example name: tests-${{ matrix.module }}) and every slice of the build gets its own stable URL. No test-distribution backend needed.

How do I get the report link onto the pull request?

Set comment: true on the step and the action posts the URL as a sticky PR comment, updated in place on every push.

Related recipes

Try it on your next run

Anonymous deploys need no account and no key — paste the step, get a link. When you want stable URLs that redeploy in place, an API key and a name are all it takes.

Need to share the report with someone outside GitHub? How to share a GitHub Actions artifact without a login.