Uploading reports to Check Run Reporter requires no dependencies beyond a means of uploading files. These docs will use cURL, but any tool you're comfortable with will work.

curl "" \
  --user token:88888888-4444-4444-4444-aaaaaaaaaaaa \
  -X POST \
  -F report=@"./reports/junit.xml" \
  -F label="Unit Tests" \
  -F sha="$CIRCLE_SHA1" \
  -F root="$(pwd)"

CI Integrations

While cURL has served us well since we launched Check Run Reporter, shelling out to bash can tedious in CI systems with complex DSLs. We've added plugins for CI systems to make working with them more natural.


Since we use Buildkite ourselves, it was naturally the first integration we wrote. Head on over to the plugin's GitHub repo for instructions.


Report uploads are authorized using basic authorization. The user should always be "token". Each repository has its own token. You can find your repository tokens on the Repositories page.


Path to the report file. A single submission may contain multiple files.
Label used in the GitHub UI to describe this submission. Common lables might be "Unit Tests", "ESLint", etc.
The commit corresponding to this Check Run. This is available as an environment variable in most CI systems. For example, its $CIRCLE_SHA1 on CircleCI and $BUILDKITE_COMMIT on Buildkite.
Stacktraces and (often) test reports contain the full filesystem path to failed test files or thrown exceptions. In order to annotate GitHub Pull Requests, we need those paths to be relative to the repository root. The root parameter should be the filesystem path to the checkout directory. Often, this can simply be "$(pwd)".

Special Cases

Most testing tools, style checkers, and static analysis tools can output some form of JUnit, but we support a few tools (with many more on the way) where we can do better.


ESLint can produce JUnit (and we support it!) but its native JSON with Metadata format allows for much more details reporting

eslint --format json-with-metadata --output-file ./reports/eslint.json
curl "" \ --user token:88888888-4444-4444-4444-aaaaaaaaaaaa \ -X POST \ -F report=@"./reports/eslint.json" \ -F label="Style" \ -F sha="$CIRCLE_SHA1" \ -F root="$(pwd)"


SwiftLint can produce JUnit but it's one of the JUnit dialects farther from the standard, make it rather difficult to pull out the relevant bits. We may add support for it at some point, but you should really just use its JSON outputter


TypeScript doesn't have a formal report format. In fact, it doesn't even have a built-in means for storing report files. Instead, use shell redirection to capture its output

tsc > ./reports/tsc.log
curl "" \ --user token:88888888-4444-4444-4444-aaaaaaaaaaaa \ -X POST \ -F report=@"./reports/tsc.log" \ -F label="Unit Tests" \ -F sha="$CIRCLE_SHA1" \ -F root="$(pwd)"

Consider using tee to store the log file while still outputting it to your CI systems log.

tsc | tee ./reports/tsc.log
curl "" \ --user token:88888888-4444-4444-4444-aaaaaaaaaaaa \ -X POST \ -F report=@"./reports/tsc.log" \ -F label="Static Analysis" \ -F sha="$CIRCLE_SHA1" \ -F root="$(pwd)"