-
Notifications
You must be signed in to change notification settings - Fork 26
feat(ecosystem): Implement cross-system issue synchronization #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: ecosystem-sync-integration-before
Are you sure you want to change the base?
feat(ecosystem): Implement cross-system issue synchronization #7
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Summary
This PR implements a comprehensive cross-system issue synchronization feature for Sentry's integration ecosystem. The changes introduce assignment source tracking to prevent infinite sync loops when multiple integrations are connected to the same Sentry organization.
The core implementation adds a new AssignmentSource dataclass that tracks which integration initiated an assignment change. This source information flows through the entire sync pipeline:
-
New AssignmentSource Service: A frozen dataclass with serialization methods (
to_dict/from_dict) and factory methods (from_integration) for creating assignment sources from integration objects -
Enhanced Sync Logic: The
should_syncmethod inIssueBasicMixinnow accepts an optionalsync_sourceparameter and prevents syncing when the source integration matches the target integration -
Model Layer Updates: The
GroupAssignee.assign()anddeassign()methods now accept an optionalassignment_sourceparameter that gets passed to sync operations -
Task Integration: The
sync_assignee_outboundtask processes assignment source dictionaries and passes the parsed source to sync methods -
Utility Function Updates: Sync utility functions in
sync.pynow handle assignment source tracking for both inbound and outbound operations
The implementation maintains backward compatibility by making all new parameters optional and preserves existing sync behavior for single-integration scenarios. The changes are well-tested with comprehensive unit tests covering various scenarios including edge cases and the critical sync loop prevention logic.
PR Description Notes:
- The PR body only contains "Test 7" which doesn't provide meaningful context about the changes
Confidence score: 4/5
- Safe to merge with minor attention needed for the test file typo
- High confidence due to comprehensive test coverage, backward compatibility, and well-structured implementation
tests/sentry/integrations/services/test_assignment_source.pyneeds attention for the typo in test method name ('inalid' should be 'invalid')
7 files reviewed, 3 comments
| result = AssignmentSource.from_dict(data) | ||
| assert result is None | ||
|
|
||
| def test_from_dict_inalid_data(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
syntax: Typo in method name: 'inalid' should be 'invalid'
| def test_from_dict_inalid_data(self): | |
| def test_from_dict_invalid_data(self): |
|
|
||
|
|
||
| class TestAssignmentSource(TestCase): | ||
| def test_from_dict_empty_array(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Method name says 'empty_array' but tests empty dict - consider renaming to 'test_from_dict_empty_dict' for clarity
| def test_from_dict_empty_array(self): | |
| def test_from_dict_empty_dict(self): |
| class AssignmentSource: | ||
| source_name: str | ||
| integration_id: int | ||
| queued: datetime = timezone.now() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Using timezone.now() as a default creates a timestamp at class definition time, not instance creation time. Consider using field(default_factory=timezone.now) for proper per-instance timestamps.
| queued: datetime = timezone.now() | |
| queued: datetime = field(default_factory=timezone.now) |
Review Summary🏷️ Draft Comments (7)
|
Test 7