diff --git a/.ansible-lint b/.ansible-lint index 9213bbeafc..4e92c017ee 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -122,3 +122,7 @@ task_name_prefix: "{stem} | " # Limit the depth of the nested blocks: # max_block_depth: 20 + +# Also recognize these versions of Ansible as supported: +# supported_ansible_also: +# - "2.14" diff --git a/src/ansiblelint/cli.py b/src/ansiblelint/cli.py index 9e6ec582f8..ce8d9ecde7 100644 --- a/src/ansiblelint/cli.py +++ b/src/ansiblelint/cli.py @@ -499,6 +499,7 @@ def merge_config(file_config: dict[Any, Any], cli_config: Options) -> Options: "enable_list": [], "only_builtins_allow_collections": [], "only_builtins_allow_modules": [], + "supported_ansible_also": [], # do not include "write_list" here. See special logic below. } diff --git a/src/ansiblelint/config.py b/src/ansiblelint/config.py index c73e4c5ce3..b0b791a84e 100644 --- a/src/ansiblelint/config.py +++ b/src/ansiblelint/config.py @@ -174,6 +174,9 @@ class Options: # pylint: disable=too-many-instance-attributes ignore_file: Path | None = None max_tasks: int = 100 max_block_depth: int = 20 + # Refer to https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix + _default_supported = ["2.15.", "2.16.", "2.17."] + supported_ansible_also: list[str] = field(default_factory=list) @property def nodeps(self) -> bool: @@ -186,6 +189,11 @@ def __post_init__(self) -> None: if self.nodeps: self.offline = True + @property + def supported_ansible(self) -> list[str]: + """Returns list of ansible versions that are considered supported.""" + return sorted([*self._default_supported, *self.supported_ansible_also]) + options = Options() diff --git a/src/ansiblelint/rules/meta_runtime.md b/src/ansiblelint/rules/meta_runtime.md index b3741f1662..3e05c595a4 100644 --- a/src/ansiblelint/rules/meta_runtime.md +++ b/src/ansiblelint/rules/meta_runtime.md @@ -1,15 +1,21 @@ # meta-runtime -This rule checks the meta/runtime.yml `requires_ansible` key against the list of currently supported versions of ansible-core. +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 as: -- `meta-runtime[unsupported-version]` - `requires_ansible` key must refer to a currently supported version such as: >=2.14.0, >=2.15.0, >=2.16.0 -- `meta-runtime[invalid-version]` - `requires_ansible` is not a valid requirement specification +- `meta-runtime[unsupported-version]` - `requires_ansible` key must refer to a + currently supported version such as: >=2.14.0, >=2.15.0, >=2.16.0 +- `meta-runtime[invalid-version]` - `requires_ansible` is not a valid + requirement specification -Please note that the linter will allow only a full version of Ansible such `2.16.0` and not allow their short form, like `2.16`. This is a safety measure -for asking authors to mention an explicit version that they tested with. Over the years we spotted multiple problems caused by the use of the short versions, users -ended up trying an outdated version that was never tested against by the collection maintainer. +Please note that the linter will allow only a full version of Ansible such +`2.16.0` and not allow their short form, like `2.16`. This is a safety measure +for asking authors to mention an explicit version that they tested with. Over +the years we spotted multiple problems caused by the use of the short versions, +users ended up trying an outdated version that was never tested against by the +collection maintainer. ## Problematic code @@ -19,7 +25,6 @@ ended up trying an outdated version that was never tested against by the collect requires_ansible: ">=2.9" ``` - ```yaml # runtime.yml --- @@ -33,3 +38,15 @@ requires_ansible: "2.15" --- requires_ansible: ">=2.15.0" ``` + +## Configuration + +In addition to the internal list of supported Ansible versions, users can +configure additional values. This allows those that want to maintain content +that requires a version of ansible-core that is already out of support. + +```yaml +# Also recognize these versions of Ansible as supported: +supported_ansible_also: + - "2.14" +``` diff --git a/src/ansiblelint/rules/meta_runtime.py b/src/ansiblelint/rules/meta_runtime.py index be0e6985e1..b6d6d3c3c7 100644 --- a/src/ansiblelint/rules/meta_runtime.py +++ b/src/ansiblelint/rules/meta_runtime.py @@ -30,12 +30,8 @@ class CheckRequiresAnsibleVersion(AnsibleLintRule): tags = ["metadata"] version_added = "v6.11.0 (last update)" - # Refer to https://access.redhat.com/support/policy/updates/ansible-automation-platform - # Also add devel to this list - supported_ansible = ["2.15.", "2.16.", "2.17."] - supported_ansible_examples = [f">={x}0" for x in supported_ansible] _ids = { - "meta-runtime[unsupported-version]": f"'requires_ansible' key must refer to a currently supported version such as: {', '.join(supported_ansible_examples)}", + "meta-runtime[unsupported-version]": "'requires_ansible' key must refer to a currently supported version", "meta-runtime[invalid-version]": "'requires_ansible' is not a valid requirement specification", } @@ -50,22 +46,26 @@ def matchyaml(self, file: Lintable) -> list[MatchError]: if file.kind != "meta-runtime": return [] - version_required = file.data.get("requires_ansible", None) + requires_ansible = file.data.get("requires_ansible", None) - if version_required: - if not any( - version in version_required for version in self.supported_ansible + if requires_ansible: + if self.options and not any( + version in requires_ansible + for version in self.options.supported_ansible ): + supported_ansible = [f">={x}0" for x in self.options.supported_ansible] + msg = f"'requires_ansible' key must refer to a currently supported version such as: {', '.join(supported_ansible)}" + results.append( self.create_matcherror( - message=self._ids["meta-runtime[unsupported-version]"], + message=msg, tag="meta-runtime[unsupported-version]", filename=file, ), ) try: - SpecifierSet(version_required) + SpecifierSet(requires_ansible) except ValueError: results.append( self.create_matcherror(