Skip to content

🐛 fix[gitlab]: sync assignees by external id#115356

Draft
iamrajjoshi wants to merge 1 commit into
masterfrom
raj--gitlab--assignee-sync-lifecycle
Draft

🐛 fix[gitlab]: sync assignees by external id#115356
iamrajjoshi wants to merge 1 commit into
masterfrom
raj--gitlab--assignee-sync-lifecycle

Conversation

@iamrajjoshi
Copy link
Copy Markdown
Collaborator

@iamrajjoshi iamrajjoshi commented May 12, 2026

Description

i am not fully certain this is the root cause of the GitLab assignment sync failures yet and haven't been able to repro

The leading hypothesis is that inbound assignment is sometimes trying to match by GitLab username when the stable mapped GitLab user ID is available, and outbound assignment can currently fail to resolve a GitLab assignee while still looking successful in lifecycle metrics.

This change updates GitLab assignee sync to prefer mapped GitLab user IDs, fall back to exact username matching, and halt outbound assignment sync when no valid GitLab assignee can be resolved.

Incase my hypothesis is wrong , i also added lifecycle extras around inbound and outbound assignment matching to debug more.

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 12, 2026
If assign=True, we're assigning the issue. Otherwise, deassign.
"""
client = self.get_client()
lifecycle = kwargs.get("lifecycle")
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temporary shim so i can try to get some more context

@iamrajjoshi iamrajjoshi force-pushed the raj--gitlab--assignee-sync-lifecycle branch from dd53ec7 to d3b924f Compare May 12, 2026 04:04
logger = logging.getLogger("sentry.integrations.gitlab.issue_sync")


def _add_lifecycle_extras(lifecycle: Any, extras: Mapping[str, Any]) -> None:
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temp should be thrown away

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

Backend Test Failures

Failures on d50f0f5 in this run:

tests/sentry/models/test_groupassignee.py::GroupAssigneeTestCase::test_assignee_sync_outbound_unassignlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/models/test_groupassignee.py:286: in test_assignee_sync_outbound_unassign
    mock_sync_assignee_outbound.assert_called_with(
/opt/hostedtoolcache/Python/3.13.1/x64/lib/python3.13/unittest/mock.py:977: in assert_called_with
    raise AssertionError(_error_message()) from cause
E   AssertionError: expected call not found.
E   Expected: sync_assignee_outbound(<ExternalIssue at 0x7f76cf166a50: id=9, organization_id=4558123004526624, integration_id=44, key='APP-123'>, None, assign=False, assignment_source=None)
E     Actual: sync_assignee_outbound(<ExternalIssue at 0x7f76daf9a4e0: id=9, organization_id=4558123004526624, integration_id=44, key='APP-123'>, None, assign=False, assignment_source=None, lifecycle=<sentry.integrations.utils.metrics.IntegrationEventLifecycle object at 0x7f76ee91d8d0>)
tests/sentry/models/test_groupassignee.py::GroupAssigneeTestCase::test_assignee_sync_outbound_assignlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/models/test_groupassignee.py:165: in test_assignee_sync_outbound_assign
    mock_sync_assignee_outbound.assert_called_with(
/opt/hostedtoolcache/Python/3.13.1/x64/lib/python3.13/unittest/mock.py:977: in assert_called_with
    raise AssertionError(_error_message()) from cause
E   AssertionError: expected call not found.
E   Expected: sync_assignee_outbound(<ExternalIssue at 0x7fcb192aa0d0: id=18, organization_id=4558123004854288, integration_id=39, key='APP-123'>, RpcUser(id=98, pk=98, name='', email='admin@localhost', username='admin@localhost', actor_id=None, display_name='admin@localhost', label='admin@localhost', is_superuser=True, is_authenticated=True, is_anonymous=False, is_active=True, is_staff=True, is_unclaimed=False, last_active=datetime.datetime(2026, 5, 12, 4, 11, 56, 666949, tzinfo=datetime.timezone.utc), is_sentry_app=False, password_usable=True, is_password_expired=False, is_suspended=False, roles=frozenset(), permissions=frozenset(), avatar=None, emails=frozenset({'admin@localhost'}), useremails=[RpcUserEmail(id=96, email='admin@localhost', is_verified=True)], authenticators=[]), assign=True, assignment_source=None)
E     Actual: sync_assignee_outbound(<ExternalIssue at 0x7fcb192a7070: id=18, organization_id=4558123004854288, integration_id=39, key='APP-123'>, RpcUser(id=98, pk=98, name='', email='admin@localhost', username='admin@localhost', actor_id=None, display_name='admin@localhost', label='admin@localhost', is_superuser=True, is_authenticated=True, is_anonymous=False, is_active=True, is_staff=True, is_unclaimed=False, last_active=datetime.datetime(2026, 5, 12, 4, 11, 56, 666949, tzinfo=datetime.timezone.utc), is_sentry_app=False, password_usable=True, is_password_expired=False, is_suspended=False, roles=frozenset(), permissions=frozenset(), avatar=None, emails=frozenset({'admin@localhost'}), useremails=[RpcUserEmail(id=96, email='admin@localhost', is_verified=True)], authenticators=[]), assign=True, assignment_source=None, lifecycle=<sentry.integrations.utils.metrics.IntegrationEventLifecycle object at 0x7fcb194d5bd0>)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant