Skip to content

Commit ecb0ff8

Browse files
Merge branch 'master'
2 parents 38d0e8b + 266c9b6 commit ecb0ff8

File tree

170 files changed

+5148
-2193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

170 files changed

+5148
-2193
lines changed

.github/workflows/frontend-snapshots.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: '[NOT REQUIRED] frontend-snapshots'
1+
name: 'frontend-snapshots'
22

33
on:
44
push:

src/sentry/api/serializers/models/rule.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -551,12 +551,10 @@ def _fetch_sentry_app_installations_by_uuid(
551551
sentry_app_installations_by_uuid: Mapping[str, RpcSentryAppComponentContext] = {}
552552
if self.prepare_component_fields:
553553
sentry_app_uuids = [
554-
sentry_app_uuid
555-
for sentry_app_uuid in (
556-
action_to_action_data[action].get("sentryAppInstallationUuid")
557-
for action in actions_with_handlers
558-
)
559-
if sentry_app_uuid is not None
554+
action_to_action_data[action]["sentryAppInstallationUuid"]
555+
for action in actions_with_handlers
556+
if action_to_action_data.get(action)
557+
and action_to_action_data[action].get("sentryAppInstallationUuid") is not None
560558
]
561559
install_contexts = app_service.get_component_contexts(
562560
filter={"uuids": sentry_app_uuids, "organization_id": workflow.organization_id},
@@ -640,12 +638,16 @@ def get_attrs(self, item_list: Sequence[Workflow], user, **kwargs):
640638
except Exception:
641639
continue # just keep iterating through the actions in case we have valid ones in there
642640
actions_with_handlers = list(action_to_handler.keys())
643-
action_to_action_data = {
644-
action: action_to_handler[action].build_rule_action_blob(
645-
action, workflow.organization_id
646-
)
647-
for action in actions_with_handlers # skip over actions w/o handlers
648-
}
641+
642+
action_to_action_data = {}
643+
for action in actions_with_handlers:
644+
try:
645+
action_to_action_data[action] = action_to_handler[
646+
action
647+
].build_rule_action_blob(action, workflow.organization_id)
648+
except ValueError:
649+
# if we have a missing sentry app installation but the action is still connected to the sentry app, we skip so we can return the rest of the rule
650+
continue
649651

650652
sentry_app_installations_by_uuid = self._fetch_sentry_app_installations_by_uuid(
651653
workflow, action_to_action_data, actions_with_handlers
@@ -660,7 +662,10 @@ def get_attrs(self, item_list: Sequence[Workflow], user, **kwargs):
660662
}
661663
)
662664
for action in actions_with_handlers:
663-
action_data = action_to_action_data[action]
665+
action_data = action_to_action_data.get(action)
666+
if not action_data:
667+
continue
668+
664669
action_data["name"] = action_to_handler[action].render_label(
665670
workflow.organization_id, action_data
666671
)

src/sentry/api/urls.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,6 @@
563563
from sentry.seer.supergroups.endpoints.organization_supergroup_details import (
564564
OrganizationSupergroupDetailsEndpoint,
565565
)
566-
from sentry.seer.supergroups.endpoints.organization_supergroups import (
567-
OrganizationSupergroupsEndpoint,
568-
)
569566
from sentry.seer.supergroups.endpoints.organization_supergroups_by_group import (
570567
OrganizationSupergroupsByGroupEndpoint,
571568
)
@@ -2439,11 +2436,6 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
24392436
OrganizationSeerExplorerUpdateEndpoint.as_view(),
24402437
name="sentry-api-0-organization-seer-explorer-update",
24412438
),
2442-
re_path(
2443-
r"^(?P<organization_id_or_slug>[^/]+)/seer/supergroups/$",
2444-
OrganizationSupergroupsEndpoint.as_view(),
2445-
name="sentry-api-0-organization-supergroups",
2446-
),
24472439
re_path(
24482440
r"^(?P<organization_id_or_slug>[^/]+)/seer/supergroups/by-group/$",
24492441
OrganizationSupergroupsByGroupEndpoint.as_view(),

src/sentry/audit_log/events.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,38 @@ def render(self, audit_log_entry: AuditLogEntry) -> str:
384384
return "updated repository settings for {repository_count} repositories".format(
385385
repository_count=data.get("repository_count", 0),
386386
)
387+
388+
389+
def _render_repo_event(action: str, audit_log_entry: AuditLogEntry) -> str:
390+
data = audit_log_entry.data
391+
actor = audit_log_entry.actor_label or "unknown"
392+
repo_name = data.get("repo_name", "unknown")
393+
source = data.get("source", "")
394+
msg = f"{actor} {action} repository {repo_name}"
395+
if source:
396+
msg += f" (via {source})"
397+
return msg
398+
399+
400+
class RepoAddedAuditLogEvent(AuditLogEvent):
401+
def __init__(self) -> None:
402+
super().__init__(event_id=1170, name="REPO_ADDED", api_name="repo.added")
403+
404+
def render(self, audit_log_entry: AuditLogEntry) -> str:
405+
return _render_repo_event("added", audit_log_entry)
406+
407+
408+
class RepoDisabledAuditLogEvent(AuditLogEvent):
409+
def __init__(self) -> None:
410+
super().__init__(event_id=1171, name="REPO_DISABLED", api_name="repo.disabled")
411+
412+
def render(self, audit_log_entry: AuditLogEntry) -> str:
413+
return _render_repo_event("disabled", audit_log_entry)
414+
415+
416+
class RepoEnabledAuditLogEvent(AuditLogEvent):
417+
def __init__(self) -> None:
418+
super().__init__(event_id=1172, name="REPO_ENABLED", api_name="repo.enabled")
419+
420+
def render(self, audit_log_entry: AuditLogEntry) -> str:
421+
return _render_repo_event("enabled", audit_log_entry)

src/sentry/audit_log/register.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,3 +695,6 @@
695695
template="updated autofix automation settings for {project_count} projects",
696696
)
697697
)
698+
default_manager.add(events.RepoAddedAuditLogEvent())
699+
default_manager.add(events.RepoDisabledAuditLogEvent())
700+
default_manager.add(events.RepoEnabledAuditLogEvent())

src/sentry/conf/server.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -771,10 +771,6 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
771771
# Mapping of localities (e.g. "us", "de") to their constituent cells (e.g. "us1", "us2")
772772
SENTRY_LOCALITIES: list[LocalityConfig] = []
773773

774-
# TODO(cells): Superceded by SENTRY_LOCAL_CELL and SENTRY_CELLS. Remove once migration is complete.
775-
SENTRY_REGION = os.environ.get("SENTRY_REGION", None)
776-
SENTRY_REGION_CONFIG: list[CellConfig] = []
777-
778774
# Shared secret used to sign cross-region RPC requests.
779775
RPC_SHARED_SECRET: list[str] | None = None
780776

@@ -882,6 +878,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
882878
"sentry.integrations.github.tasks.codecov_account_unlink",
883879
"sentry.integrations.github.tasks.link_all_repos",
884880
"sentry.integrations.github.tasks.pr_comment",
881+
"sentry.integrations.github.tasks.sync_repos",
885882
"sentry.integrations.github.tasks.sync_repos_on_install_change",
886883
"sentry.integrations.gitlab.tasks",
887884
"sentry.integrations.jira.tasks",
@@ -1016,6 +1013,10 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
10161013
"task": "workflow_engine:sentry.workflow_engine.tasks.workflows.schedule_delayed_workflows",
10171014
"schedule": timedelta(seconds=15),
10181015
},
1016+
"prune-old-open-period-activity": {
1017+
"task": "workflow_engine:sentry.workflow_engine.tasks.cleanup.prune_old_open_period_activity",
1018+
"schedule": timedelta(minutes=2),
1019+
},
10191020
"resolve-stale-sourcemap-detectors": {
10201021
"task": "workflow_engine:sentry.processing_errors.tasks.resolve_stale_sourcemap_detectors",
10211022
"schedule": crontab("*/5", "*", "*", "*", "*"),
@@ -1250,6 +1251,10 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
12501251
"task": "sdk.control:sentry.tasks.release_registry.fetch_release_registry_data_control",
12511252
"schedule": crontab("*/5", "*", "*", "*", "*"),
12521253
},
1254+
"github-repo-sync-beat": {
1255+
"task": "integrations.control:sentry.integrations.github.tasks.sync_repos.github_repo_sync_beat",
1256+
"schedule": timedelta(minutes=1),
1257+
},
12531258
}
12541259

12551260
if SILO_MODE == "CONTROL":

src/sentry/data_export/models.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,19 @@ def email_failure(self, message: str) -> None:
169169
error_payload=self.payload,
170170
creation_date=self.date_added,
171171
)
172-
if NotificationService.has_access(self.organization, data.source):
172+
has_access = NotificationService.has_access(self.organization, data.source)
173+
logger.info(
174+
"notification.platform.data-export-failure.has_access",
175+
extra={
176+
"organization_id": self.organization.id,
177+
"data_export_id": self.id,
178+
"data_source": data.source,
179+
"has_access": has_access,
180+
"user_email": user.email,
181+
},
182+
)
183+
184+
if has_access:
173185
NotificationService(data=data).notify_async(
174186
targets=[
175187
GenericNotificationTarget(

src/sentry/features/temporary.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,13 @@ def register_temporary_features(manager: FeatureManager) -> None:
138138
manager.add("organizations:integrations-github-copilot-agent", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
139139
manager.add("organizations:integrations-github-platform-detection", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
140140
manager.add("organizations:github-repo-auto-sync", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)
141+
manager.add("organizations:github-repo-auto-sync-apply", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)
141142
manager.add("organizations:integrations-perforce", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
142143
manager.add("organizations:integrations-slack-staging", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
143144
manager.add("organizations:scm-source-context", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
144145
# API-driven integration setup pipeline (per-provider rollout)
145146
manager.add("organizations:integration-api-pipeline-github", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
147+
manager.add("organizations:integration-api-pipeline-gitlab", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
146148
# Project Management Integrations Feature Parity Flags
147149
manager.add("organizations:integrations-github_enterprise-project-management", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
148150
manager.add("organizations:integrations-gitlab-project-management", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)

src/sentry/incidents/action_handlers.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,22 +462,15 @@ def send_alert(
462462

463463
incident_serialized_response = serialize(incident, serializer=IncidentSerializer())
464464

465-
success = send_incident_alert_notification(
465+
send_incident_alert_notification(
466466
notification_context=notification_context,
467467
alert_context=alert_context,
468468
metric_issue_context=metric_issue_context,
469469
incident_serialized_response=incident_serialized_response,
470470
organization=incident.organization,
471+
project_id=project.id,
471472
notification_uuid=notification_uuid,
472473
)
473-
if success:
474-
self.record_alert_sent_analytics(
475-
organization_id=incident.organization.id,
476-
project_id=project.id,
477-
alert_id=incident.alert_rule.id,
478-
external_id=action.sentry_app_id,
479-
notification_uuid=notification_uuid,
480-
)
481474

482475

483476
def format_duration(minutes):

src/sentry/integrations/bitbucket/webhook.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from sentry.integrations.source_code_management.webhook import SCMWebhook
2525
from sentry.integrations.types import IntegrationProviderSlug
2626
from sentry.integrations.utils.metrics import IntegrationWebhookEvent, IntegrationWebhookEventType
27+
from sentry.integrations.utils.webhook_viewer_context import webhook_viewer_context
2728
from sentry.models.commit import Commit
2829
from sentry.models.commitauthor import CommitAuthor
2930
from sentry.models.organization import Organization
@@ -258,11 +259,14 @@ def post(self, request: HttpRequest, organization_id: int) -> HttpResponse:
258259

259260
event_handler = handler()
260261

261-
with IntegrationWebhookEvent(
262-
interaction_type=event_handler.event_type,
263-
domain=IntegrationDomain.SOURCE_CODE_MANAGEMENT,
264-
provider_key=event_handler.provider,
265-
).capture():
262+
with (
263+
webhook_viewer_context(organization.id),
264+
IntegrationWebhookEvent(
265+
interaction_type=event_handler.event_type,
266+
domain=IntegrationDomain.SOURCE_CODE_MANAGEMENT,
267+
provider_key=event_handler.provider,
268+
).capture(),
269+
):
266270
event_handler(event, repo=repo, organization=organization)
267271

268272
return HttpResponse(status=204)

0 commit comments

Comments
 (0)