Skip to main content

JUnit XML output

vulkro-sf antipatterns --format=junit emits a JUnit-style XML report. Every finding becomes a <testcase> with a <failure> child. CI runners that already collect JUnit XML (the GitHub Actions test reporter, GitLab CI's artifacts.reports.junit, Jenkins's JUnit plugin, CircleCI's store_test_results) surface each finding as a failed test without any extra glue.

Shape

<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="vulkro-sf.antipatterns" tests="1" failures="1" errors="0">
<testcase classname="AP-013" name="AP-013 SOQL without WHERE or LIMIT (force-app/main/default/classes/Foo.cls:42)">
<failure type="AP-013" message="A SELECT query at line 42 has no WHERE or LIMIT...">
Add a WHERE clause that bounds the result set, or LIMIT it...
</failure>
</testcase>
</testsuite>

The fields:

  • classname is the detector ID (AP-013), so CI dashboards group findings per detector.
  • name combines the detector ID, the human title, and file:line, so the failed-test row tells you exactly where to look.
  • failure.message is the finding's detail text (with < > & " ' XML-escaped).
  • failure body is the finding's remediation guidance.

CI examples

GitHub Actions

- name: vulkro-sf antipatterns (JUnit)
run: vulkro-sf antipatterns . --format junit > vulkro-sf-junit.xml
- name: Surface findings as failed tests
if: always()
uses: dorny/test-reporter@v1
with:
name: Vulkro for Salesforce
path: vulkro-sf-junit.xml
reporter: java-junit

GitLab CI

vulkro-sf:
script:
- vulkro-sf antipatterns . --format junit > vulkro-sf-junit.xml
artifacts:
when: always
reports:
junit: vulkro-sf-junit.xml

Jenkins (Pipeline)

sh 'vulkro-sf antipatterns . --format junit > vulkro-sf-junit.xml'
junit testResults: 'vulkro-sf-junit.xml', allowEmptyResults: true

Exit codes

The exit-code contract is unchanged from the other output formats:

  • 0 - no findings (<testsuite tests="0">)
  • 1 - findings reported (CI runner shows the failed tests)
  • 2 - internal error (CI runner shows the job as errored, not failed)

Where to go next

  • SARIF output - structured format for the GitHub Security tab, SonarQube, Codacy.
  • vulkro-sf antipatterns - the full flag reference including --format, --exclude-namespace, --compliance, and the cache flags.