diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 245aeafc8e..63961089c5 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -73,7 +73,7 @@ jobs: env: # Number of expected test passes, safety measure for accidental skip of # tests. Update value if you add/remove tests. - PYTEST_REQPASS: 868 + PYTEST_REQPASS: 869 steps: - uses: actions/checkout@v4 with: diff --git a/examples/playbooks/become.yml b/examples/playbooks/become.yml index ce53f56691..bc8aadb867 100644 --- a/examples/playbooks/become.yml +++ b/examples/playbooks/become.yml @@ -12,4 +12,4 @@ become: true become_user: nobody notify: - - restart apache2 + - Restart apache2 diff --git a/examples/playbooks/name_case_notify_fail.yml b/examples/playbooks/name_case_notify_fail.yml new file mode 100644 index 0000000000..642152bd49 --- /dev/null +++ b/examples/playbooks/name_case_notify_fail.yml @@ -0,0 +1,26 @@ +--- +- name: Test Playbook + hosts: localhost + tasks: + - name: Task that always changes + ansible.builtin.debug: + msg: foo + changed_when: true + notify: my handler + + - name: Task that always changes + ansible.builtin.debug: + msg: foo + changed_when: true + notify: + - my handler + - my other handler + + handlers: + - name: My handler + ansible.builtin.debug: + msg: bar + + - name: my other handler + ansible.builtin.debug: + msg: bar diff --git a/src/ansiblelint/rules/name.py b/src/ansiblelint/rules/name.py index fe38e74995..ee417707fd 100644 --- a/src/ansiblelint/rules/name.py +++ b/src/ansiblelint/rules/name.py @@ -92,6 +92,25 @@ def matchtask( lineno=task[LINE_NUMBER_KEY], ), ) + + notify = task.get("notify") + if notify: + if isinstance(notify, str): + notify = [notify] + results.extend( + [ + self.create_matcherror( + message=f"Task notify '{handler}' should start with an uppercase letter.", + lineno=task[LINE_NUMBER_KEY], + tag="name[casing]", + filename=file, + ) + for handler in notify + if handler[0].isalpha() + and handler[0].islower() + and not handler[0].isupper() + ], + ) return results def _prefix_check( @@ -352,6 +371,23 @@ def test_rule_name_lowercase() -> None: assert errs[0].tag == "name[casing]" assert errs[0].rule.id == "name" + def test_rule_notify_lowercase() -> None: + """Negative test for a task notify that starts with lowercase.""" + collection = RulesCollection() + collection.register(NameRule()) + failure = "examples/playbooks/name_case_notify_fail.yml" + bad_runner = Runner(failure, rules=collection) + errs = bad_runner.run() + assert len(errs) == 4 + assert errs[0].tag == "name[casing]" + assert errs[1].tag == "name[casing]" + assert errs[2].tag == "name[casing]" + assert errs[3].tag == "name[casing]" + assert errs[0].rule.id == "name" + assert errs[1].rule.id == "name" + assert errs[2].rule.id == "name" + assert errs[3].rule.id == "name" + def test_name_play() -> None: """Positive test for name[play].""" collection = RulesCollection() diff --git a/test/test_transformer.py b/test/test_transformer.py index fa9530e317..b67f78a2f0 100644 --- a/test/test_transformer.py +++ b/test/test_transformer.py @@ -84,7 +84,7 @@ def fixture_runner_result( id="strings", ), pytest.param("examples/playbooks/vars/empty.yml", 1, False, True, id="empty"), - pytest.param("examples/playbooks/name-case.yml", 2, True, True, id="name_case"), + pytest.param("examples/playbooks/name-case.yml", 6, True, True, id="name_case"), pytest.param("examples/playbooks/fqcn.yml", 3, True, True, id="fqcn"), pytest.param( "examples/playbooks/multi_yaml_doc.yml",