Skip to content

Commit

Permalink
Fix updating Jira issues
Browse files Browse the repository at this point in the history
  • Loading branch information
hluk committed Jan 30, 2025
1 parent 8f5a1f0 commit 5227b4e
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 3 deletions.
6 changes: 5 additions & 1 deletion src/retasc/jira_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ def edit_issue(
"""

logger.info("Updating Jira issue %r with fields: %r", issue_key, fields)
self.jira.edit_issue(issue_key, fields, notify_users=notify_users)
base_url = self.jira.resource_url("issue")
url = f"{base_url}/{issue_key}"
self.jira.put(
url, data={"fields": fields}, params={"notifyUsers": notify_users}
)

@tracer.start_as_current_span("JiraClient.create_issue")
def create_issue(self, fields: dict) -> dict:
Expand Down
14 changes: 13 additions & 1 deletion src/retasc/models/prerequisites/jira_issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,23 @@ def _set_parent_issue(fields: dict, parent_issue_key: str | None = None):
fields["parent"] = {"key": parent_issue_key}


def _is_jira_field_up_to_date(current_value, new_value):
if isinstance(current_value, dict) and isinstance(new_value, dict):
return all(
_is_jira_field_up_to_date(current_value.get(k), v)
for k, v in new_value.items()
)

return current_value == new_value


def _edit_issue(
issue, fields, context, label: str, parent_issue_key: str | None = None
):
to_update = {
k: v for k, v in fields.items() if issue["fields"][k] != v and k != "labels"
k: v
for k, v in fields.items()
if k != "labels" and not _is_jira_field_up_to_date(issue["fields"][k], v)
}

labels = {label, *fields.get("labels", [])}
Expand Down
110 changes: 109 additions & 1 deletion tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
INPUT = "ProductPagesRelease('rhel-10.0')"


def call_run():
def call_run(*, additional_jira_fields: dict = {}):
config = parse_config("examples/config.yaml")
config.jira_fields.update(additional_jira_fields)
return run(config=config, jira_token="", dry_run=False)


Expand Down Expand Up @@ -362,6 +363,113 @@ def test_run_rule_jira_issue_update_labels(factory, mock_jira):
mock_jira.edit_issue.assert_called_once_with("TEST-1", {"labels": expected_labels})


def test_run_rule_jira_issue_update_complex_field(factory, mock_jira):
jira_issue_prereq = factory.new_jira_issue_prerequisite("""
assignee: {key: alice}
""")
rule = factory.new_rule(prerequisites=[jira_issue_prereq])
current_value = {"name": "Bob", "key": "bob"}
mock_jira.search_issues.return_value = [
{
"key": "TEST-1",
"fields": {
"assignee": current_value,
"labels": ["retasc-id-test_jira_template_1"],
"resolution": None,
},
}
]
expected_fields = {"assignee": {"key": "alice"}}
report = call_run(additional_jira_fields={"assignee": "assignee"})
assert report.data == {
INPUT: {
rule.name: {
"Jira('test_jira_template_1')": {
"issue": "TEST-1",
"update": json.dumps(expected_fields),
"state": "InProgress",
},
"state": "InProgress",
}
}
}
mock_jira.create_issue.assert_not_called()
mock_jira.edit_issue.assert_called_once_with("TEST-1", expected_fields)

current_value["key"] = "alice"
current_value["name"] = "Alice"
report = call_run(additional_jira_fields={"assignee": "assignee"})
assert report.data == {
INPUT: {
rule.name: {
"Jira('test_jira_template_1')": {
"issue": "TEST-1",
"state": "InProgress",
},
"state": "InProgress",
}
}
}
mock_jira.create_issue.assert_not_called()
mock_jira.edit_issue.assert_called_once()


def test_run_rule_jira_issue_update_complex_nested_field(factory, mock_jira):
jira_issue_prereq = factory.new_jira_issue_prerequisite("""
service:
value: gating
child:
value: waiverdb
""")
rule = factory.new_rule(prerequisites=[jira_issue_prereq])
current_value = {"value": "gating", "child": {"id": "123", "value": "greenwave"}}
mock_jira.search_issues.return_value = [
{
"key": "TEST-1",
"fields": {
"customfield_123": current_value,
"labels": ["retasc-id-test_jira_template_1"],
"resolution": None,
},
}
]
expected_fields = {
"customfield_123": {"value": "gating", "child": {"value": "waiverdb"}}
}
additional_jira_fields = {"service": "customfield_123"}
report = call_run(additional_jira_fields=additional_jira_fields)
assert report.data == {
INPUT: {
rule.name: {
"Jira('test_jira_template_1')": {
"issue": "TEST-1",
"update": json.dumps(expected_fields),
"state": "InProgress",
},
"state": "InProgress",
}
}
}
mock_jira.create_issue.assert_not_called()
mock_jira.edit_issue.assert_called_once_with("TEST-1", expected_fields)

current_value["child"]["value"] = "waiverdb"
report = call_run(additional_jira_fields=additional_jira_fields)
assert report.data == {
INPUT: {
rule.name: {
"Jira('test_jira_template_1')": {
"issue": "TEST-1",
"state": "InProgress",
},
"state": "InProgress",
}
}
}
mock_jira.create_issue.assert_not_called()
mock_jira.edit_issue.assert_called_once()


def test_run_rule_jira_issue_completed(factory, mock_jira):
jira_issue_prereq = factory.new_jira_issue_prerequisite(DUMMY_ISSUE)
rule = factory.new_rule(prerequisites=[jira_issue_prereq])
Expand Down

0 comments on commit 5227b4e

Please sign in to comment.