Skip to content

Commit ac3d409

Browse files
committed
Split default with status and assignee into smaller bits
1 parent c03d5fd commit ac3d409

File tree

2 files changed

+109
-99
lines changed

2 files changed

+109
-99
lines changed

jbi/actions/default_with_assignee_and_status.py

Lines changed: 105 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,20 @@ def on_create_issue(
5353
"resolution_map": self.resolution_map,
5454
},
5555
)
56-
return self._update_issue(log_context, bug, event, issue_key, is_new=True)
56+
57+
if bug.is_assigned():
58+
try:
59+
assign_jira_user(log_context, issue_key, bug.assigned_to)
60+
except ValueError as exc:
61+
logger.debug(str(exc), extra=log_context.dict())
62+
63+
jira_resolution = self.resolution_map.get(bug.resolution)
64+
update_issue_resolution(log_context, issue_key, jira_resolution)
65+
66+
# We use resolution if one exists or status otherwise.
67+
bz_status = bug.resolution or bug.status
68+
jira_status = self.status_map.get(bz_status)
69+
update_issue_status(log_context, issue_key, jira_status)
5770

5871
def on_update_issue(
5972
self,
@@ -70,106 +83,99 @@ def on_update_issue(
7083
"resolution_map": self.resolution_map,
7184
},
7285
)
73-
return self._update_issue(log_context, bug, event, issue_key, is_new=False)
7486

75-
def _update_issue( # pylint: disable=too-many-arguments
76-
self,
77-
log_context: ActionLogContext,
78-
bug: BugzillaBug,
79-
event: BugzillaWebhookEvent,
80-
linked_issue_key: str,
81-
is_new: bool,
82-
):
8387
changed_fields = event.changed_fields() or []
8488

85-
jira_client = jira.get_client()
86-
87-
def clear_assignee():
88-
# New tickets already have no assignee.
89-
if not is_new:
90-
logger.debug("Clearing assignee", extra=log_context.dict())
91-
jira_client.update_issue_field(
92-
key=linked_issue_key, fields={"assignee": None}
93-
)
94-
95-
# If this is a new issue or if the bug's assignee has changed then
96-
# update the assignee.
97-
if is_new or "assigned_to" in changed_fields:
98-
if bug.assigned_to == "[email protected]":
99-
clear_assignee()
89+
if "assigned_to" in changed_fields:
90+
if not bug.is_assigned():
91+
clear_assignee(log_context, issue_key)
10092
else:
101-
logger.debug(
102-
"Attempting to update assignee",
103-
extra=log_context.dict(),
104-
)
105-
# Look up this user in Jira
106-
users = jira_client.user_find_by_user_string(query=bug.assigned_to)
107-
if len(users) == 1:
108-
try:
109-
# There doesn't appear to be an easy way to verify that
110-
# this user can be assigned to this issue, so just try
111-
# and do it.
112-
jira_client.update_issue_field(
113-
key=linked_issue_key,
114-
fields={"assignee": {"accountId": users[0]["accountId"]}},
115-
)
116-
except IOError as exception:
117-
logger.debug(
118-
"Setting assignee failed: %s",
119-
exception,
120-
extra=log_context.dict(),
121-
)
122-
# If that failed then just fall back to clearing the
123-
# assignee.
124-
clear_assignee()
125-
else:
126-
logger.debug(
127-
"No assignee found",
128-
extra=log_context.update(operation=Operation.IGNORE).dict(),
129-
)
130-
clear_assignee()
131-
132-
# If this is a new issue or if the bug's status or resolution has
133-
# changed then update the issue status.
134-
if is_new or "status" in changed_fields or "resolution" in changed_fields:
135-
# If action has configured mappings for the issue resolution field, update it.
136-
bz_resolution = bug.resolution
137-
jira_resolution = self.resolution_map.get(bz_resolution)
138-
if jira_resolution:
139-
logger.debug(
140-
"Updating Jira resolution to %s",
141-
jira_resolution,
142-
extra=log_context.dict(),
143-
)
144-
jira_client.update_issue_field(
145-
key=linked_issue_key,
146-
fields={"resolution": jira_resolution},
147-
)
148-
else:
149-
logger.debug(
150-
"Bug resolution was not in the resolution map.",
151-
extra=log_context.update(
152-
operation=Operation.IGNORE,
153-
).dict(),
154-
)
155-
156-
# We use resolution if one exists or status otherwise.
157-
bz_status = bz_resolution or bug.status
93+
try:
94+
assign_jira_user(log_context, issue_key, bug.assigned_to)
95+
except ValueError as exc:
96+
logger.debug(str(exc), extra=log_context.dict())
97+
# If that failed then just fall back to clearing the assignee.
98+
clear_assignee(log_context, issue_key)
99+
100+
if "resolution" in changed_fields:
101+
jira_resolution = self.resolution_map.get(bug.resolution)
102+
update_issue_resolution(log_context, issue_key, jira_resolution)
103+
104+
if "status" in changed_fields or "resolution" in changed_fields:
105+
bz_status = bug.resolution or bug.status
158106
jira_status = self.status_map.get(bz_status)
159-
if jira_status:
160-
logger.debug(
161-
"Updating Jira status to %s",
162-
jira_status,
163-
extra=log_context.dict(),
164-
)
165-
jira_client.set_issue_status(
166-
linked_issue_key,
167-
jira_status,
168-
)
169-
else:
170-
logger.debug(
171-
"Bug status was not in the status map.",
172-
extra=log_context.update(
173-
operation=Operation.IGNORE,
174-
).dict(),
175-
)
107+
update_issue_status(log_context, issue_key, jira_status)
108+
109+
110+
def clear_assignee(context, issue_key):
111+
"""Clear the assignee of the specified Jira issue."""
112+
logger.debug("Clearing assignee", extra=context.dict())
113+
jira.get_client().update_issue_field(key=issue_key, fields={"assignee": None})
114+
115+
116+
def find_jira_user(context, bugzilla_assignee):
117+
"""Lookup Jira users, raise an error if not exactly one found."""
118+
users = jira.get_client().user_find_by_user_string(query=bugzilla_assignee)
119+
if len(users) != 1:
120+
raise ValueError(f"User {bugzilla_assignee} not found")
121+
return users[0]
122+
123+
124+
def assign_jira_user(context, issue_key, bugzilla_assignee):
125+
"""Set the assignee of the specified Jira issue, raise if fails."""
126+
jira_user = find_jira_user(context, bugzilla_assignee)
127+
jira_user_id = jira_user["accountId"]
128+
try:
129+
# There doesn't appear to be an easy way to verify that
130+
# this user can be assigned to this issue, so just try
131+
# and do it.
132+
return jira.get_client().update_issue_field(
133+
key=issue_key,
134+
fields={"assignee": {"accountId": jira_user_id}},
135+
)
136+
except IOError as exc:
137+
raise ValueError(
138+
f"Could not assign {jira_user_id} to issue {issue_key}"
139+
) from exc
140+
141+
142+
def update_issue_status(context, issue_key, jira_status):
143+
"""Update the status of the Jira issue or no-op if None."""
144+
if jira_status:
145+
logger.debug(
146+
"Updating Jira status to %s",
147+
jira_status,
148+
extra=context.dict(),
149+
)
150+
jira.get_client().set_issue_status(
151+
issue_key,
152+
jira_status,
153+
)
154+
else:
155+
logger.debug(
156+
"Bug status was not in the status map.",
157+
extra=context.update(
158+
operation=Operation.IGNORE,
159+
).dict(),
160+
)
161+
162+
163+
def update_issue_resolution(context, issue_key, jira_resolution):
164+
"""Update the resolution of the Jira issue or no-op if None."""
165+
if jira_resolution:
166+
logger.debug(
167+
"Updating Jira resolution to %s",
168+
jira_resolution,
169+
extra=context.dict(),
170+
)
171+
jira.get_client().update_issue_field(
172+
key=issue_key,
173+
fields={"resolution": jira_resolution},
174+
)
175+
else:
176+
logger.debug(
177+
"Bug resolution was not in the resolution map.",
178+
extra=context.update(
179+
operation=Operation.IGNORE,
180+
).dict(),
181+
)

jbi/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ class BugzillaBug(BaseModel):
231231
assigned_to: Optional[str]
232232
comment: Optional[BugzillaWebhookComment]
233233

234+
def is_assigned(self) -> bool:
235+
"""Return `true` if the bug is assigned to a user."""
236+
return self.assigned_to != "[email protected]"
237+
234238
def get_whiteboard_as_list(self) -> list[str]:
235239
"""Convert string whiteboard into list, splitting on ']' and removing '['."""
236240
if self.whiteboard is not None:

0 commit comments

Comments
 (0)