Skip to content

Commit 69b6217

Browse files
grichaclaude
andauthored
feat(integrations): Propagate ViewerContext in Jira Server webhook (#112411)
## Summary - Wraps the per-org iteration in `handle_status_change` with `webhook_viewer_context` so downstream code has access to the current organization identity via the ViewerContext contextvar. - Gated behind the `viewer-context.enabled` option (no-op when disabled). - Part of the ViewerContext RFC rollout for webhook handlers. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 18f7c5e commit 69b6217

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/sentry/integrations/jira_server/utils/api.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from sentry.integrations.services.integration.model import RpcIntegration
88
from sentry.integrations.services.integration.service import integration_service
99
from sentry.integrations.utils.sync import sync_group_assignee_inbound
10+
from sentry.integrations.utils.webhook_viewer_context import webhook_viewer_context
1011

1112
if TYPE_CHECKING:
1213
from sentry.integrations.models.integration import Integration
@@ -76,9 +77,10 @@ def handle_status_change(
7677
providers=[integration.provider],
7778
)
7879
for oi in org_integrations:
79-
installation = integration.get_installation(oi.organization_id)
80+
with webhook_viewer_context(oi.organization_id):
81+
installation = integration.get_installation(oi.organization_id)
8082

81-
if hasattr(installation, "sync_status_inbound"):
82-
installation.sync_status_inbound(
83-
issue_key, {"changelog": changelog, "issue": data["issue"]}
84-
)
83+
if hasattr(installation, "sync_status_inbound"):
84+
installation.sync_status_inbound(
85+
issue_key, {"changelog": changelog, "issue": data["issue"]}
86+
)

tests/sentry/integrations/jira_server/test_webhooks.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
from sentry.integrations.services.integration.serial import serialize_integration
1010
from sentry.silo.base import SiloMode
1111
from sentry.testutils.cases import APITestCase
12+
from sentry.testutils.helpers.options import override_options
1213
from sentry.testutils.silo import assume_test_silo_mode
14+
from sentry.viewer_context import ActorType, get_viewer_context
1315

1416
from . import EXAMPLE_PAYLOAD, get_integration, link_group
1517

@@ -94,6 +96,27 @@ def test_post_update_status(self, mock_sync: MagicMock) -> None:
9496
},
9597
)
9698

99+
@override_options({"viewer-context.enabled": True})
100+
@patch.object(JiraServerIntegration, "sync_status_inbound")
101+
def test_post_update_status_sets_viewer_context(self, mock_sync: MagicMock) -> None:
102+
captured_contexts: list = []
103+
104+
def capture_context(*args: object, **kwargs: object) -> None:
105+
captured_contexts.append(get_viewer_context())
106+
107+
mock_sync.side_effect = capture_context
108+
109+
project = self.create_project()
110+
self.create_group(project=project)
111+
112+
self.get_success_response(self.jwt_token, **EXAMPLE_PAYLOAD)
113+
114+
assert len(captured_contexts) == 1
115+
vc = captured_contexts[0]
116+
assert vc is not None
117+
assert vc.organization_id == self.organization.id
118+
assert vc.actor_type == ActorType.INTEGRATION
119+
97120
@responses.activate
98121
def test_post_update_status_token_error(self) -> None:
99122
responses.add(

0 commit comments

Comments
 (0)