Skip to main content

ansible-lint2junit

Converts ansible-lint output into JUnit XML, so lint findings show up as test results in CI — in particular in GitLab's test report UI.

This is a fork of wasilak/ansible-lint-junit (MIT licensed), renamed and modernised for GitLab (Python 3.9+):

  • Testcases carry a stable identity (classname = ansible-lint rule ID, name = file:line message), so GitLab can track newly-failed/resolved findings between pipeline runs.
  • Testcases carry a file attribute, so GitLab links each finding to the source file.
  • Suite tests/failures counts reflect the actual findings (summary lines and blanks are ignored).
  • No longer depends on ansible-lint itself — only its text output — so it installs cleanly alongside any ansible-lint version (the only dependency is defusedxml).
  • ANSI colour codes are stripped from the input, so forgetting --nocolor doesn't silently produce an empty report.
  • --fail-on-findings lets one CI step both publish the report and fail the job.

Installation

From PyPI:

pip install ansible-lint2junit

or from this project's GitLab package registry:

pip install ansible-lint2junit --index-url https://gitlab.surrey.ac.uk/api/v4/projects/sm0049%2Fansible-lint2junit/packages/pypi/simple

Usage

Pipe ansible-lint -p output in:

ansible-lint playbook.yml -p --nocolor | ansible-lint2junit -o ansible-lint.xml

or go via a file (multiple input files are concatenated):

ansible-lint -p --nocolor playbook.yml > ansible-lint.txt
ansible-lint2junit ansible-lint.txt -o ansible-lint.xml

Options:

Option Description
-o FILE output file (default ansible-lint2junit.xml); use -o - to write to stdout
-v also print the XML to stdout
-d emit a single dummy testcase when there are no findings, for CI parsers that reject empty suites
-f, --fail-on-findings exit with status 1 when there is at least one finding
--version print version

If the input is non-empty but no line matches the file:line: message format, a warning is printed to stderr — usually a sign the input wasn't produced with -p.

GitLab CI example

ansible-lint:
  image: python:3.13
  script:
    - pip install ansible-lint
    - pip install ansible-lint2junit --index-url https://gitlab.surrey.ac.uk/api/v4/projects/sm0049%2Fansible-lint2junit/packages/pypi/simple
    - ansible-lint -p --nocolor . > ansible-lint.txt || true
    - ansible-lint2junit ansible-lint.txt -o ansible-lint.xml --fail-on-findings
  artifacts:
    when: always
    reports:
      junit: ansible-lint.xml

The || true keeps the job running so the report is always generated; --fail-on-findings then fails the job when there are findings, after the report exists. Drop it if lint findings should not fail the pipeline.

Output

  • Findings become JUnit <failure> testcases, grouped by ansible-lint rule.
  • Clean input still produces a valid (empty) JUnit XML file, so JUnit parsers that fail on a missing report (e.g. Bamboo) keep working. Use -d for parsers that also reject suites with zero tests.
  • Both modern ansible-lint (rule-id[subrule] message) and legacy ([E301] message) output formats are recognised; unrecognised lines that still look like file:line: message are kept with a generic ansible-lint classname.

Development

pip install -e '.[test]'
pytest                  # tests (with coverage in CI)
ruff check . && ruff format --check .   # lint/format (pip install ruff)
mypy                    # type check (pip install mypy)

License

Distributed under the MIT license, as is the original project by Piotr Boruc.

Metadata

Release files for ansible-lint2junit 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ansible-lint2junit 1.2.0
File Size Uploaded
ansible_lint2junit-1.2.0.tar.gz 12.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ansible-lint2junit 1.2.0
File Interpreter ABI Platform
ansible_lint2junit-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.4 kB

Release files / ansible_lint2junit-1.2.0.tar.gz

Download URL ansible_lint2junit-1.2.0.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8655ab96ab8cab1c21889682f5d77f68cb4bfb78b7b66256e7a7e312d5d3367c
BLAKE2b-256 checksum
How to use checksums
577b867e24c1c5a278254d4245560a68ede0603ca0fbb38e00ff293ba4570c29
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release files / ansible_lint2junit-1.2.0-py3-none-any.whl

Download URL ansible_lint2junit-1.2.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
43fee170e19285042d71a2f67c40864d4dbf18dca7d98fabf177f10ca0bf5b7d
BLAKE2b-256 checksum
How to use checksums
9138df4b52cb9c34541170222d8a8ccc36b6548ed72b6c83650e8e83677c1192
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page