diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 45edc4dc321..c82a865eaf4 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -70,7 +70,7 @@ jobs: env: # Number of expected test passes, safety measure for accidental skip of # tests. Update value if you add/remove tests. - PYTEST_REQPASS: 832 + PYTEST_REQPASS: 833 steps: - uses: actions/checkout@v4 with: diff --git a/examples/roles/role_with_handler/handlers/main.yml b/examples/roles/role_with_handler/handlers/main.yml new file mode 100644 index 00000000000..9ca1ab169e0 --- /dev/null +++ b/examples/roles/role_with_handler/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: Debug + loop: "{{ _something_done.results }}" + loop_control: + label: "{{ item.item.name }}" + when: item.changed + ansible.builtin.debug: + msg: "{{ item.item.name }} changed" diff --git a/examples/roles/role_with_handler/tasks/main.yml b/examples/roles/role_with_handler/tasks/main.yml new file mode 100644 index 00000000000..362dc78948d --- /dev/null +++ b/examples/roles/role_with_handler/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Get info + delegate_to: localhost + register: collected_info + ansible.builtin.debug: + msg: test + +- name: Do something + delegate_to: localhost + loop: "{{ collected_info['some_list'] }}" + loop_control: + label: "{{ item.name }}" + notify: + - Debug + register: _something_done + ansible.builtin.debug: + msg: test2 diff --git a/src/ansiblelint/rules/no_handler.py b/src/ansiblelint/rules/no_handler.py index 8cbb111578e..0e4374eb8e9 100644 --- a/src/ansiblelint/rules/no_handler.py +++ b/src/ansiblelint/rules/no_handler.py @@ -69,7 +69,11 @@ def matchtask( task: Task, file: Lintable | None = None, ) -> bool | str: - if task["__ansible_action_type__"] != "task" or task.is_handler(): + if ( + task["__ansible_action_type__"] != "task" + or task.is_handler() + or (file is not None and "handlers" in file.name) + ): return False when = task.get("when") @@ -89,6 +93,7 @@ def matchtask( # pylint: disable=ungrouped-imports from ansiblelint.rules import RulesCollection from ansiblelint.runner import Runner + from ansiblelint.testing import run_ansible_lint @pytest.mark.parametrize( ("test_file", "failures"), @@ -107,3 +112,10 @@ def test_no_handler( assert len(results) == failures for result in results: assert result.tag == "no-handler" + + def test_role_with_handler() -> None: + """Test role with handler.""" + role_path = "examples/roles/role_with_handler" + + results = run_ansible_lint("-v", role_path) + assert "no-handler" not in results.stdout