diff --git a/examples/rules/rules.yaml b/examples/rules/rules.yaml index e5afeb2..91742c1 100644 --- a/examples/rules/rules.yaml +++ b/examples/rules/rules.yaml @@ -12,6 +12,7 @@ subtasks: - jira_issue: add_beta_repos template: "add_beta_repos.yaml.j2" + when: "major >= 10" - jira_issue: notify_team fields: project: diff --git a/src/retasc/models/prerequisites/jira_issue.py b/src/retasc/models/prerequisites/jira_issue.py index 7b8011e..2e34354 100644 --- a/src/retasc/models/prerequisites/jira_issue.py +++ b/src/retasc/models/prerequisites/jira_issue.py @@ -264,6 +264,20 @@ class JiraIssueTemplate(PrerequisiteBase): " current status are skipped automatically." ), ) + when: str = Field( + default="true", + description=( + "Condition expression. The issue is only created/updated" + " when it evaluates to true. Defaults to 'true' (always created)." + ), + ) + + def _want_update(self, context): + if context.template.evaluate(self.when): + return True + + context.report.set("skipped", True) + return False def _update_issue_data( self, @@ -388,6 +402,10 @@ def update_state(self, context) -> ReleaseRuleState: context.template.params["jira_template_file"] = self.template jira_issue_id = context.template.render(self.jira_issue) context.report.set("jira_issue", jira_issue_id) + + if not self._want_update(context): + return ReleaseRuleState.Completed + issue = self._update_issue(jira_issue_id, context=context) if issue is None: return ReleaseRuleState.InProgress @@ -400,6 +418,8 @@ def update_state(self, context) -> ReleaseRuleState: subtask_id = context.template.render(subtask.jira_issue) with context.report.section("subtasks", type="Subtask", name=subtask_id): context.report.set("jira_issue", subtask_id) + if not subtask._want_update(context): + continue subtask._update_issue( subtask_id, context, diff --git a/tests/factory.py b/tests/factory.py index 314c573..e1eda50 100644 --- a/tests/factory.py +++ b/tests/factory.py @@ -47,10 +47,12 @@ def new_jira_template_file(self, jira_issue: str, template: str) -> str: return str(tmp) - def new_jira_subtask(self, template: str) -> JiraIssueTemplate: + def new_jira_subtask( + self, template: str, *, when: str = "true" + ) -> JiraIssueTemplate: jira_issue = self.new_jira_issue_id() file = self.new_jira_template_file(jira_issue, template) - return JiraIssueTemplate(jira_issue=jira_issue, template=file) + return JiraIssueTemplate(jira_issue=jira_issue, template=file, when=when) def new_jira_issue_prerequisite( self, @@ -59,6 +61,7 @@ def new_jira_issue_prerequisite( fields: dict[str, Any] | None = None, jira_issue: str = "", subtasks=[], + when: str = "true", ): jira_issue_ = jira_issue or self.new_jira_issue_id() @@ -72,4 +75,5 @@ def new_jira_issue_prerequisite( template=file, fields=fields or {}, subtasks=subtasks, + when=when, ) diff --git a/tests/test_run.py b/tests/test_run.py index ace3c8f..a72f734 100644 --- a/tests/test_run.py +++ b/tests/test_run.py @@ -401,6 +401,97 @@ def test_run_rule_jira_issue_create_subtasks(factory): } +def test_run_rule_jira_issue_when_false(factory, mock_jira): + jira_issue_prereq = factory.new_jira_issue_prerequisite(DUMMY_ISSUE, when="false") + rule = factory.new_rule(prerequisites=[jira_issue_prereq]) + report = call_run() + assert report.data == { + "inputs": [ + { + "type": "ProductPagesReleases", + "release": "rhel-10.0", + "rules": [ + { + "rule": rule.name, + "prerequisites": [ + { + "type": "JiraIssue", + "jira_issue": "test_jira_template_1", + "skipped": True, + } + ], + "state": "Completed", + } + ], + } + ] + } + mock_jira.create_issue.assert_not_called() + mock_jira.search_issues.assert_not_called() + + +def test_run_rule_jira_issue_subtask_when_false(factory, mock_jira): + subtasks = [ + factory.new_jira_subtask(DUMMY_ISSUE, when="false"), + factory.new_jira_subtask(DUMMY_ISSUE), + ] + jira_issue_prereq = factory.new_jira_issue_prerequisite( + DUMMY_ISSUE, subtasks=subtasks + ) + rule = factory.new_rule(prerequisites=[jira_issue_prereq]) + report = call_run() + assert report.data == { + "inputs": [ + { + "type": "ProductPagesReleases", + "release": "rhel-10.0", + "rules": [ + { + "rule": rule.name, + "prerequisites": [ + { + "type": "JiraIssue", + "jira_issue": "test_jira_template_3", + "issue_data": { + "summary": "test", + "labels": [ + "retasc-id-test_jira_template_3-rhel-10.0" + ], + }, + "issue_status": "created", + "issue_id": "TEST-1", + "state": "InProgress", + "subtasks": [ + { + "type": "Subtask", + "jira_issue": "test_jira_template_1", + "skipped": True, + }, + { + "type": "Subtask", + "jira_issue": "test_jira_template_2", + "issue_data": { + "summary": "test", + "labels": [ + "retasc-id-test_jira_template_2-rhel-10.0" + ], + "parent": {"key": "TEST-1"}, + }, + "issue_status": "created", + "issue_id": "TEST-2", + }, + ], + }, + ], + "state": "InProgress", + } + ], + } + ] + } + assert mock_jira.create_issue.call_count == 2 + + def test_run_rule_jira_issue_in_progress(factory, mock_jira): jira_issue_prereq = factory.new_jira_issue_prerequisite(DUMMY_ISSUE) rule = factory.new_rule(prerequisites=[jira_issue_prereq])