Skip to content

Tags

Tags

v26.11.0

Toggle v26.11.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(security): clear Dependabot uv.lock advisories and CodeQL smoke c…

…heckout (#611)

* fix(security): refresh uv.lock and resolve CodeQL workflow alerts

Add uv constraint floors for patched transitive deps, raise requires-python
to 3.11 so the lock resolves, and scope smoke workflow checkout to trusted
refs on non-pull_request triggers.

* fix(ci): align tox matrix and ruff with Python 3.11 floor

Set min_python for the reusable tox workflow and drop obsolete PERF203
noqa so prek lint leaves a clean tree under CI.

v26.10.0

Toggle v26.10.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(impact_file): add scope-file interface for content-plugin-finder…

… ImpactReport (#607)

* feat(impact_file): add scope-file interface for content-plugin-finder ImpactReport

Implements AAP-94164: Add impact_file configuration option that consumes
ImpactReport JSON from content-plugin-finder. This enables scoped testing
by filtering molecule and integration environments based on changed content.

Features:
- impact_file configurable via CLI (--impact-file PATH), INI ([ansible]
  impact_file = ...), and TOML ([tool.tox-ansible] impact_file = "...")
- TOML-over-INI, CLI-over-config precedence preserved
- Validates ImpactReport JSON without runtime dependency on content-plugin-finder
- Rejects malformed JSON, invalid field types, absolute paths, path traversal,
  collection-name mismatches, and unsafe target/scenario names (shell injection)
- When molecule_scenarios is empty/absent, all molecule-* environments omitted
- When integration_targets is empty/absent, all integration-* environments omitted
- Molecule commands scoped to only listed scenario paths/names
- Integration commands scoped using ansible-test only when targets/ directories exist
- Falls back to pytest for pytest-style integration tests
- Unit, sanity, and galaxy environments unaffected by scope file
- Unscoped behavior (no impact_file) fully preserved

Security:
- Shell injection protection via strict alphanumeric name validation
- Defense-in-depth with shlex.quote for command generation

Tests:
- 42 new unit tests covering TOML, INI, CLI configuration
- Path validation (absolute paths, traversal, relative paths)
- Name validation (shell injection, unsafe characters)
- ImpactReport validation (malformed JSON, missing fields, type errors)
- Matrix output filtering
- Command generation for scoped molecule and integration
- Pytest fallback for missing ansible-test targets
- Integration tests (skipped until plugin installed with feature)

Documentation:
- Complete configuration guide with CI workflow example
- ImpactReport JSON schema documentation

Closes: AAP-94164
Related: tox-ansible #603, content-plugin-finder #1
Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(impact_file): add scope-file interface for content-plugin-finder ImpactReport

Implements AAP-94164: Add impact_file configuration option that consumes
ImpactReport JSON from content-plugin-finder. This enables scoped testing
by filtering molecule and integration environments based on changed content.

Features:
- impact_file configurable via CLI (--impact-file PATH), INI ([ansible]
  impact_file = ...), and TOML ([tool.tox-ansible] impact_file = "...")
- TOML-over-INI, CLI-over-config precedence preserved
- Validates ImpactReport JSON without runtime dependency on content-plugin-finder
- Rejects malformed JSON, invalid field types, absolute paths, path traversal,
  collection-name mismatches, and unsafe target/scenario names (shell injection)
- When molecule_scenarios is empty/absent, all molecule-* environments omitted
- When integration_targets is empty/absent, all integration-* environments omitted
- Molecule commands scoped to only listed scenario paths/names
- Integration commands scoped using ansible-test only when targets/ directories exist
- Falls back to pytest for pytest-style integration tests
- Unit, sanity, and galaxy environments unaffected by scope file
- Unscoped behavior (no impact_file) fully preserved

Security:
- Shell injection protection via strict alphanumeric name validation
- Defense-in-depth with shlex.quote for command generation

Refactoring:
- Extracted impact report handling to src/tox_ansible/impact.py module
- Keeps plugin.py under 1600 line limit

Tests:
- 42 new unit tests covering TOML, INI, CLI configuration
- Path validation (absolute paths, traversal, relative paths)
- Name validation (shell injection, unsafe characters)
- ImpactReport validation (malformed JSON, missing fields, type errors)
- Matrix output filtering
- Command generation for scoped molecule and integration
- Pytest fallback for missing ansible-test targets
- Integration tests (skipped until plugin installed with feature)

Documentation:
- Complete configuration guide with CI workflow example
- ImpactReport JSON schema documentation

Closes: AAP-94164
Related: tox-ansible #603, content-plugin-finder #1
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(impact): resolve pydoclint docstring errors

- Remove 'Raises' section from load_impact_report (DOC502) since it
  uses sys.exit() not raise statements
- Remove docstrings from simple test methods that only need fixture
  annotations (DOC101/DOC103)
- Add missing Args/Returns sections to integration test helpers

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(impact): add coverage for tox_add_env_config impact_file loading

Test the code path where impact_file is loaded in tox_add_env_config
and passed to conf_commands for molecule command generation.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(impact): improve error handling and add fallback warnings

- Handle directory, permission, and encoding errors when reading impact file
- Use is_file() instead of exists() to detect directories
- Catch OSError and UnicodeDecodeError for better error messages
- Log warning for each missing ansible-test integration target
- Log warning when falling back to pytest due to no valid targets
- Document the fallback behavior in configuration.md

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(impact): use project_dir instead of cwd for integration targets

- Add project_dir parameter to conf_commands and conf_commands_for_integration
- Use project_dir instead of Path.cwd() to resolve integration targets
- Add PLR0912 to noqa for load_impact_report (too many branches)
- Add tests for directory and unreadable file error handling
- Update tests to pass project_dir parameter

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(impact): add coverage for fallback warning when targets missing

Verify that warnings are logged when integration targets from the
impact report don't exist and the command falls back to pytest.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(impact): remove unreachable branch in fallback warning

The 'if missing_targets:' check was unreachable - when we reach that
point, missing_targets is guaranteed non-empty because:
1. We entered the outer if with at least one integration target
2. If any target was found, we'd have returned early
3. Therefore all targets must be missing

Removes the unnecessary condition to eliminate coverage branch gap.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(impact): add coverage for UTF-8 and FIFO error handling

- test_invalid_utf8_file: covers UnicodeDecodeError handling
- test_fifo_as_path: covers 'not a regular file' error (line 192)

Achieves 100% coverage for src/tox_ansible/impact.py

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(lint): add mkfifo to cspell dictionary

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(impact): reduce cognitive complexity and fix log injection

impact.py:
- Extract _resolve_impact_path() - path resolution + file existence check
- Extract _read_impact_file() - try/except JSON parsing block
- Removes C901/PLR0912 suppression from load_impact_report (no longer needed)
- Fix log injection in _validate_impact_collection: use %s format args
  instead of embedding user input in the format string (S5145)

plugin.py:
- Extract _resolve_ansible_test_targets() - reduces conf_commands_for_integration
- Extract _filter_env_list() - reduces add_ansible_matrix

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(impact): resolve SonarQube S5145 and S5864 in impact.py

S5145 (log injection): sanitize user-controlled collection name before
logging by stripping newline and carriage-return characters (CWE-117).

S5864 (confusing type check): after isinstance guard, rebind to an
explicit dict[str, Any] variable so static analysers don't confuse
post-guard access with the pre-guard object type.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: validate integration_targets prefix in load_impact_report

Paths in integration_targets must start with
'tests/integration/targets/'. Reject entries that don't match this
prefix with a critical log message and sys.exit(1), consistent with
the other validation helpers.

Add unit test test_integration_target_wrong_prefix to cover the new
branch.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

v26.9.0

Toggle v26.9.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore(deps): update pep621 (#605)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

v26.8.0

Toggle v26.8.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
docs: fix expression injection in CI/CD pipeline example (#594)

Pass matrix.env.name via an env var rather than interpolating it
directly into the run: shell script, preventing expression injection.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

v26.7.1

Toggle v26.7.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(deps): exclude ansible-core 2.17.x (CVE-2026-11332) (#588)

ansible-core 2.17 is EOL and will never receive the fix for
CVE-2026-11332 (argument injection in ansible-galaxy role install,
CVSS 7.8). Exclude the entire 2.17.x range so the resolver picks
2.16.19 (patched) for Python 3.10 or 2.18+ for Python 3.11+.

v26.7.0

Toggle v26.7.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix: drop milestone from Python 3.12 matrix (#576)

v26.6.1

Toggle v26.6.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix: bump cryptography and cairosvg constraint floors for CVE remedia…

…tion (#575)

Raise cryptography constraint from >=43 to >=49.0.0 to address
CVE-2026-39892 (buffer overflow), CVE-2026-26007 (subgroup attack),
and GHSA-537c-gmf6-5ccf (vulnerable OpenSSL in wheels).
Add cairosvg>=2.9.0 constraint to prevent resolution to versions
vulnerable to CVE-2026-31899 (exponential DoS via recursive <use>).

v26.6.0

Toggle v26.6.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore(deps): update all dependencies to df4cb1c (#560)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Sudhir Verma <9924513+sudhirverma@users.noreply.github.com>

v26.3.0

Toggle v26.3.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore: update test deps (#537)

v26.2.2

Toggle v26.2.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix: handle tox 4.47+ conflicting version factors in env names (#535)

* fix: set ignore_base_python_conflict to resolve tox 4.47+ version factor conflicts

* fix: explicitly set base_python to prevent tox 4.47+ version conflicts

tox 4.47.1 treats bare version numbers like 2.16 as Python versions,
causing environment names like sanity-py3.10-2.16 to fail with
"conflicting factors py3.10, 2.16" error.

The previous fix (ignore_base_python_conflict=True) suppressed the error
but caused tox to fall back to the default Python (3.10), which fails
when ansible-core requires a newer Python version.

This fix explicitly sets base_python for each environment based on the
Python version factor (e.g., py3.11 → base_python=py3.11), ensuring tox
uses the correct Python interpreter.

Made-with: Cursor

* fix: use expected_factors constant to satisfy linter

Made-with: Cursor

* fix: shorten lines to satisfy 100 char limit

Made-with: Cursor

* fix: exclude empty base_python from loader to avoid config failures

When base_python is empty (e.g., for the galaxy environment which
doesn't follow the {test_type}-py{version}-{ansible} naming pattern),
including it in the MemoryLoader causes tox to fail finding a Python
interpreter. Only include base_python when we have a specific version.

Made-with: Cursor

* test: add coverage for galaxy env without base_python

Add test case for environments like 'galaxy' that don't follow the
standard {test_type}-py{version}-{ansible} naming pattern. This
ensures base_python is excluded from the loader when not applicable.

Made-with: Cursor

* chore: trigger CI

Made-with: Cursor

* ensure we use correct tox versions

---------

Co-authored-by: anushka-shukla-03 <anshukla@redhat.com>
Co-authored-by: Sorin Sbarnea <sorin.sbarnea@gmail.com>