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
fileattribute, so GitLab links each finding to the source file. - Suite
tests/failurescounts reflect the actual findings (summary lines and blanks are ignored). - No longer depends on
ansible-lintitself — only its text output — so it installs cleanly alongside any ansible-lint version (the only dependency isdefusedxml). - ANSI colour codes are stripped from the input, so forgetting
--nocolordoesn't silently produce an empty report. --fail-on-findingslets 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
-dfor 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 likefile:line: messageare kept with a genericansible-lintclassname.
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)
| File | Size | Uploaded | |
|---|---|---|---|
| ansible_lint2junit-1.2.0.tar.gz | 12.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|