Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add meta-unsupported-ansible rule for checking requires_ansible values #2770

Merged
merged 5 commits into from
Dec 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
WSLENV: FORCE_COLOR:PYTEST_REQPASS:TOXENV
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests.
PYTEST_REQPASS: 725
PYTEST_REQPASS: 728

steps:
- name: Activate WSL1
Expand Down
1 change: 0 additions & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import subprocess
import sys
from typing import Any

# checking if user is running pytest without installing test dependencies:
missing = []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
requires_ansible: ">=2.15.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
requires_ansible: ">=2.9.0,<2.20"
2 changes: 2 additions & 0 deletions examples/meta_runtime_version_checks/pass/meta/runtime.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
requires_ansible: ">=2.13.0"
1 change: 1 addition & 0 deletions src/ansiblelint/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def main():
FileType = Literal[
"playbook",
"meta", # role meta
"meta-runtime",
"tasks", # includes pre_tasks, post_tasks
"handlers", # very similar to tasks but with some specifics
# https://docs.ansible.com/ansible/latest/galaxy/user_guide.html#installing-roles-and-collections-from-the-same-requirements-yml-file
Expand Down
31 changes: 31 additions & 0 deletions src/ansiblelint/rules/meta_unsupported_ansible.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# meta-unsupported-ansible

This rule checks the meta/runtime.yml `requires_ansible` key against the list of currently supported versions of ansible-core.

This rule can produce messages such:

- `requires_ansible` key must be set to a supported version.

Currently supported versions of ansible-core are:

- `2.9.10`
- `2.11.x`
- `2.12.x`
- `2.13.x`
- `2.14.x`

## Problematic code

```yaml
# runtime.yml
---
requires_ansible: ">=2.9"
```

## Correct code

```yaml
# runtime.yml
---
requires_ansible: ">=2.9.10"
```
98 changes: 98 additions & 0 deletions src/ansiblelint/rules/meta_unsupported_ansible.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""Implementation of meta-unsupported-ansible rule."""
from __future__ import annotations

import sys
from typing import TYPE_CHECKING

from ansiblelint.rules import AnsibleLintRule

# Copyright (c) 2018, Ansible Project


if TYPE_CHECKING:
from typing import Any

from ansiblelint.errors import MatchError
from ansiblelint.file_utils import Lintable

META_TAG_VALID = """
galaxy_info:
galaxy_tags: ['database', 'my s q l', 'MYTAG']
categories: 'my_category_not_in_a_list'
"""


class CheckRequiresAnsibleVersion(AnsibleLintRule):
"""Required ansible version in meta/runtime.yml must be a supported version."""

id = "meta-unsupported-ansible"
description = (
"The ``requires_ansible`` key in runtime.yml must specify "
"a supported platform version of ansible-core."
)
severity = "VERY_HIGH"
tags = ["metadata", "opt-in", "experimental"]
version_added = "v6.8.6 (last update)"

supported_ansible = ["2.9.10", "2.11", "2.12", "2.13", "2.14"]

def matchyaml(self, file: Lintable) -> list[MatchError]:
"""Find violations inside meta files."""
if file.kind != "meta-runtime":
return []

version_required = file.data.get("requires_ansible", None)

print(version_required)

if version_required:
if not any(
version in version_required for version in self.supported_ansible
):
return [
self.create_matcherror(
message="requires_ansible key must be set to a supported version.",
filename=file,
)
]

return []


# testing code to be loaded only with pytest or when executed the rule file
if "pytest" in sys.modules:

import pytest

from ansiblelint.rules import RulesCollection # pylint: disable=ungrouped-imports
from ansiblelint.runner import Runner # pylint: disable=ungrouped-imports

@pytest.mark.parametrize(
("test_file", "failures"),
(
pytest.param(
"examples/meta_runtime_version_checks/pass/meta/runtime.yml",
0,
id="pass",
),
pytest.param(
"examples/meta_runtime_version_checks/fail_0/meta/runtime.yml",
1,
id="fail0",
),
pytest.param(
"examples/meta_runtime_version_checks/fail_1/meta/runtime.yml",
1,
id="fail1",
),
),
)
def test_loop_var_prefix(
default_rules_collection: RulesCollection, test_file: str, failures: int
) -> None:
"""Test rule matches."""
default_rules_collection.register(CheckRequiresAnsibleVersion())
results = Runner(test_file, rules=default_rules_collection).run()
for result in results:
assert result.rule.id == CheckRequiresAnsibleVersion().id
assert len(results) == failures
1 change: 1 addition & 0 deletions src/ansiblelint/schemas/ansible-lint-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"meta-incorrect",
"meta-no-info",
"meta-no-tags",
"meta-unsupported-ansible",
"meta-video-links",
"name",
"no-changed-when",
Expand Down
2 changes: 1 addition & 1 deletion test/test_rules_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,5 @@ def test_rules_id_format() -> None:
rule.help != "" or rule.description or rule.__doc__
), f"Rule {rule.id} must have at least one of: .help, .description, .__doc__"
assert "yaml" in keys, "yaml rule is missing"
assert len(rules) == 48 # update this number when adding new rules!
assert len(rules) == 49 # update this number when adding new rules!
assert len(keys) == len(rules), "Duplicate rule ids?"