From 45a8172f7556757165ec3329de6d530cec0b311e Mon Sep 17 00:00:00 2001 From: Bala Sakabattula Date: Tue, 2 Jun 2026 15:25:32 +0530 Subject: [PATCH 1/3] assignment fixes --- sync2jira/downstream_issue.py | 21 +++++++++----- tests/test_downstream_issue.py | 53 +++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/sync2jira/downstream_issue.py b/sync2jira/downstream_issue.py index 036cabe5..86b291d0 100644 --- a/sync2jira/downstream_issue.py +++ b/sync2jira/downstream_issue.py @@ -1230,7 +1230,7 @@ def _update_assignee(client, existing, issue, overwrite): """ us_exists = bool( - issue.assignee and issue.assignee[0] and issue.assignee[0].get("fullname") + issue.assignee and issue.assignee[0] and issue.assignee[0].get("login") ) assignee = existing.fields.assignee ds_exists = bool(assignee) and _jira_user_display_label(assignee) is not None @@ -1239,14 +1239,19 @@ def _update_assignee(client, existing, issue, overwrite): # Let assign_user() figure out what to do. update = True elif us_exists: - # Overwrite the downstream assignment only if it is different from - # the upstream one. - un = issue.assignee[0]["fullname"] - dn = _jira_user_display_label(assignee) - update = un != dn and remove_diacritics(un) != dn + un = issue.assignee[0].get("fullname") + if un: + # Overwrite the downstream assignment only if it is different + # from the upstream one. + dn = _jira_user_display_label(assignee) + update = un != dn and remove_diacritics(un) != dn + else: + # Upstream assignee has no fullname; let assign_user() resolve + # via LDAP/email lookup using the login. + update = True else: - # Without an upstream owner, update only if the downstream is not - # assigned to the project owner. + # Without an upstream assignee, update only if the downstream is + # not assigned to the project owner. update = issue.downstream.get("owner") != _jira_user_display_label(assignee) else: # We're not overwriting, so call assign_user() only if the downstream diff --git a/tests/test_downstream_issue.py b/tests/test_downstream_issue.py index 2b32660f..5c27a840 100644 --- a/tests/test_downstream_issue.py +++ b/tests/test_downstream_issue.py @@ -1686,12 +1686,14 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (12, None), # - upstream assignee exists and assignments are different: called with remove_all=False (13, False), - # - upstream assignee has a fullname of None: called with remove_all=True - (14, True), + # - upstream assignee has login but fullname is None: called with remove_all=False + (14, False), + # - upstream assignee has login but no fullname key: called with remove_all=False + (15, False), # - upstream assignee does not exist: called with remove_all=True - (15, True), - # - upstream assignee is an empty list: called with remove_all=True (16, True), + # - upstream assignee is an empty list: called with remove_all=True + (17, True), # - downstream assignee is owner # - upstream assignee exists and assignments are different: called with remove_all=False (21, False), @@ -1699,12 +1701,14 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (22, False), # - upstream assignee exists and assignments are different: called with remove_all=False (23, False), - # - upstream assignee has a fullname of None: not called (already assigned to owner) - (24, None), + # - upstream assignee has login but fullname is None: called with remove_all=False + (24, False), + # - upstream assignee has login but no fullname key: called with remove_all=False + (25, False), # - upstream assignee does not exist: not called (already assigned to owner) - (25, None), - # - upstream assignee is an empty list: not called (already assigned to owner) (26, None), + # - upstream assignee is an empty list: not called (already assigned to owner) + (27, None), # - downstream assignee does not exist # - upstream assignee exists: called with remove_all=False (31, False), @@ -1714,10 +1718,12 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (33, False), # - upstream assignee has a fullname of None: called with remove_all=False (34, False), - # - upstream assignee does not exist: called with remove_all=False + # - upstream assignee has login but no fullname key: called with remove_all=False (35, False), - # - upstream assignee is an empty list: called with remove_all=False + # - upstream assignee does not exist: called with remove_all=False (36, False), + # - upstream assignee is an empty list: called with remove_all=False + (37, False), # - overwrite = False # - downstream assignee is set: # - upstream assignee exists and assignments are equal: not called @@ -1728,10 +1734,12 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (43, None), # - upstream assignee has a fullname of None: not called (44, None), - # - upstream assignee does not exist: not called + # - upstream assignee has login but no fullname key: not called (45, None), - # - upstream assignee is an empty list: not called + # - upstream assignee does not exist: not called (46, None), + # - upstream assignee is an empty list: not called + (47, None), # - downstream assignee is owner # - upstream assignee exists and assignments are different: not called (51, None), @@ -1741,10 +1749,12 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (53, None), # - upstream assignee has a fullname of None: not called (54, None), - # - upstream assignee does not exist: not called + # - upstream assignee has login but no fullname key: not called (55, None), - # - upstream assignee is an empty list: not called + # - upstream assignee does not exist: not called (56, None), + # - upstream assignee is an empty list: not called + (57, None), # - downstream assignee does not exist # - upstream assignee exists: called with remove_all=False (61, False), @@ -1754,10 +1764,12 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (63, False), # - upstream assignee has a fullname of None: called with remove_all=False (64, False), - # - upstream assignee does not exist: called with remove_all=False + # - upstream assignee has login but no fullname key: called with remove_all=False (65, False), - # - upstream assignee is an empty list: called with remove_all=False + # - upstream assignee does not exist: called with remove_all=False (66, False), + # - upstream assignee is an empty list: called with remove_all=False + (67, False), ) ) match = "Erik" @@ -1772,10 +1784,11 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): setattr(self.mock_downstream.fields.assignee, "name", ds) for us in ( - [{"fullname": match}], - [{"fullname": "Èŕìḱ"}], - [{"fullname": "Bob"}], - [{"fullname": None}], + [{"login": "erik", "fullname": match}], + [{"login": "erik", "fullname": "Èŕìḱ"}], + [{"login": "bob", "fullname": "Bob"}], + [{"login": "anon", "fullname": None}], + [{"login": "jdoe"}], None, [], ): From 07425dfcee0e46c9db46e5897010d9b51ae3f099 Mon Sep 17 00:00:00 2001 From: Bala Sakabattula Date: Wed, 3 Jun 2026 16:05:10 +0530 Subject: [PATCH 2/3] fixes --- sync2jira/downstream_issue.py | 2 +- tests/test_downstream_issue.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sync2jira/downstream_issue.py b/sync2jira/downstream_issue.py index 86b291d0..e0b4261c 100644 --- a/sync2jira/downstream_issue.py +++ b/sync2jira/downstream_issue.py @@ -1244,7 +1244,7 @@ def _update_assignee(client, existing, issue, overwrite): # Overwrite the downstream assignment only if it is different # from the upstream one. dn = _jira_user_display_label(assignee) - update = un != dn and remove_diacritics(un) != dn + update = un != dn and remove_diacritics(un) != remove_diacritics(dn) else: # Upstream assignee has no fullname; let assign_user() resolve # via LDAP/email lookup using the login. diff --git a/tests/test_downstream_issue.py b/tests/test_downstream_issue.py index 5c27a840..41684c5a 100644 --- a/tests/test_downstream_issue.py +++ b/tests/test_downstream_issue.py @@ -1716,7 +1716,7 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (32, False), # - upstream assignee exists: called with remove_all=False (33, False), - # - upstream assignee has a fullname of None: called with remove_all=False + # - upstream assignee has login but fullname is None: called with remove_all=False (34, False), # - upstream assignee has login but no fullname key: called with remove_all=False (35, False), @@ -1732,7 +1732,7 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (42, None), # - upstream assignee exists and assignments are different: not called (43, None), - # - upstream assignee has a fullname of None: not called + # - upstream assignee has login but fullname is None: not called (44, None), # - upstream assignee has login but no fullname key: not called (45, None), @@ -1747,7 +1747,7 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (52, None), # - upstream assignee exists and assignments are different: not called (53, None), - # - upstream assignee has a fullname of None: not called + # - upstream assignee has login but fullname is None: not called (54, None), # - upstream assignee has login but no fullname key: not called (55, None), @@ -1762,7 +1762,7 @@ def test_update_assignee_all(self, mock_client, mock_assign_user): (62, False), # - upstream assignee exists: called with remove_all=False (63, False), - # - upstream assignee has a fullname of None: called with remove_all=False + # - upstream assignee has login but fullname is None: called with remove_all=False (64, False), # - upstream assignee has login but no fullname key: called with remove_all=False (65, False), From c2c0ff66d7ade1e881bec087b8db5c8af6d6ce4b Mon Sep 17 00:00:00 2001 From: Bala Sakabattula Date: Wed, 3 Jun 2026 19:22:43 +0530 Subject: [PATCH 3/3] fixes for PR coming in path of issue --- sync2jira/upstream_issue.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sync2jira/upstream_issue.py b/sync2jira/upstream_issue.py index 76d9d51c..19872a19 100644 --- a/sync2jira/upstream_issue.py +++ b/sync2jira/upstream_issue.py @@ -215,7 +215,8 @@ def handle_github_message(body, config, is_pr=False): headers, github_client = get_github_client(config) reformat_github_issue(issue, upstream, github_client) - add_project_values(issue, upstream, headers, config) + updates_key = "pr_updates" if is_pr else "issue_updates" + add_project_values(issue, upstream, headers, config, updates_key) return i.Issue.from_github(upstream, issue, config)