Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
085bd28
feat(seer): Convert structured LLMContext JSON to markdown for on_pag…
Mihir-Mavalankar Apr 3, 2026
a8a8009
feat(github): Handle installation_repositories webhook (#111864)
wedamija Apr 3, 2026
8348ba9
fix(billing): fix flaky paymentForm test by awaiting button enabled s…
hubertdeng123 Apr 3, 2026
773a39c
feat(occurrences on eap): Implement tagstore EAP query for release ta…
shashjar Apr 3, 2026
5c597cb
feat(seer): Improve the loading state of the Seer SCM overview area (…
ryan953 Apr 3, 2026
34d7465
feat(notifications): Hook into the platform in the slack send_alert s…
Christinarlong Apr 3, 2026
c16202b
fix(aci): Preselect current detector type when clicking create monito…
malwilley Apr 3, 2026
b9820f7
ref(cells): clean up remaining instances of SENTRY_REGION_CONFIG and …
lynnagara Apr 3, 2026
814605c
ref(seer): Refactor hooks related to the preferred agent option (#112…
ryan953 Apr 3, 2026
ed8df88
fix(supergroups): Use placeholder data to avoid loading flash on grou…
scttcper Apr 3, 2026
371be3f
fix(github): Add `sync_repos_on_install_change` to TASKWORKER_IMPORTS…
wedamija Apr 3, 2026
ef0e343
fix(vulnerability): Update action-add-labels version (#112207)
Jeffreyhung Apr 3, 2026
a50ff75
fix(autofix): Only write handoff.auto_create_pr ProjectOption if not …
srest2021 Apr 3, 2026
76eaf72
feat(seer): Send structured LLMContext JSON as on_page_context (#112200)
Mihir-Mavalankar Apr 3, 2026
167e0ea
fix(typing): Type post-process (#112203)
thetruecpaul Apr 3, 2026
cf435d4
ref(utils): Remove dead execute() function (#112199)
gricha Apr 3, 2026
b4f2897
fix(webhooks): Split out the metric alert action to be in a task (#11…
Christinarlong Apr 3, 2026
f2148f4
feat(occurrences on eap): Implement tagstore EAP query for group list…
shashjar Apr 3, 2026
ca7fcd4
Revert "feat(github): Handle installation_repositories webhook (#111…
getsentry-bot Apr 3, 2026
05bf2cb
Revert "fix(github): Add `sync_repos_on_install_change` to TASKWORKER…
getsentry-bot Apr 3, 2026
ea0c749
feat(seer): Implement the dropdown to save defaultAutomatedRunStoppin…
ryan953 Apr 3, 2026
68f4a48
chore: bump sentry-protos 0.8.10 (#112225)
brendanhsentry Apr 3, 2026
8a0a9a0
Revert "fix(webhooks): Split out the metric alert action to be in a t…
getsentry-bot Apr 3, 2026
aed886a
feat(scraps): Add slot component (#112032)
JonasBa Apr 3, 2026
931bcfa
feat(np): Adds Discord issue renderer, updates Slack renderer tagging…
GabeVillalobos Apr 3, 2026
b14f5ba
ref(billing): Unify category mappings shared by billing services (#11…
brendanhsentry Apr 3, 2026
dd54a06
bug(snapshots): Fix bug in snapshots status check where approval not …
rbro112 Apr 3, 2026
02db802
feat(seer): Fall back to contextvar ViewerContext for Seer requests (…
gricha Apr 3, 2026
246508e
feat(occurrences on eap): Implement tagstore EAP query for group tag …
shashjar Apr 3, 2026
5299126
ref(cmdk) fix space input (#112231)
JonasBa Apr 3, 2026
22867f0
feat(seer): Add preamble to structured page context markdown (#112235)
Mihir-Mavalankar Apr 3, 2026
4f3f61b
feat(repos): Add routings for github `installation_repositories` webh…
wedamija Apr 3, 2026
5b0d6ef
ref(cmdk) fix panel container (#112236)
JonasBa Apr 3, 2026
8cafbe2
ref(cmdk): implement async actions (#112173)
JonasBa Apr 3, 2026
e6e831c
ci: skip flaky tests/acceptance/test_proxy.py::EndToEndAPIProxyTest::…
joshuarli Apr 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
## Frontend
/static/app/components/analyticsArea.spec.tsx @getsentry/app-frontend
/static/app/components/analyticsArea.tsx @getsentry/app-frontend
/static/app/components/loading/ @getsentry/app-frontend
/static/app/components/events/interfaces/ @getsentry/app-frontend
/static/app/components/forms/ @getsentry/app-frontend
/static/app/locale.tsx @getsentry/app-frontend
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/label-pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ jobs:
filters: .github/file-filters.yml

- name: Add frontend label
uses: getsentry/action-add-labels@54d0cba498c1eaf8bd34985d715504d1b6e2935f
uses: getsentry/action-add-labels@ca568508c6e91387909cb3661e4cd965aa2f3a89
if: steps.changes.outputs.frontend_all == 'true'
with:
labels: 'Scope: Frontend'

- name: Add backend label
uses: getsentry/action-add-labels@54d0cba498c1eaf8bd34985d715504d1b6e2935f
uses: getsentry/action-add-labels@ca568508c6e91387909cb3661e4cd965aa2f3a89
if: steps.changes.outputs.backend_src == 'true'
with:
labels: 'Scope: Backend'
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ dependencies = [
"sentry-forked-email-reply-parser>=0.5.12.post1",
"sentry-kafka-schemas>=2.1.27",
"sentry-ophio>=1.1.3",
"sentry-protos>=0.8.8",
"sentry-protos>=0.8.10",
"sentry-redis-tools>=0.5.0",
"sentry-relay>=0.9.25",
"sentry-sdk[http2]>=2.47.0",
Expand Down Expand Up @@ -683,6 +683,7 @@ module = [
"sentry.tasks.codeowners.*",
"sentry.tasks.commit_context",
"sentry.tasks.on_demand_metrics",
"sentry.tasks.post_process",
"sentry.tasks.reprocessing2",
"sentry.tasks.seer.delete_seer_grouping_records",
"sentry.tasks.store",
Expand Down
67 changes: 67 additions & 0 deletions src/sentry/billing/platform/services/category_mapping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from __future__ import annotations

from sentry_protos.billing.v1.data_category_pb2 import DataCategory as ProtoDataCategory

from sentry.constants import DataCategory
from sentry.utils import metrics

SENTRY_TO_PROTO_CATEGORY: dict[int, int] = {
int(DataCategory.ERROR): ProtoDataCategory.DATA_CATEGORY_ERROR,
int(DataCategory.TRANSACTION): ProtoDataCategory.DATA_CATEGORY_TRANSACTION,
int(DataCategory.ATTACHMENT): ProtoDataCategory.DATA_CATEGORY_ATTACHMENT,
int(DataCategory.PROFILE): ProtoDataCategory.DATA_CATEGORY_PROFILE,
int(DataCategory.REPLAY): ProtoDataCategory.DATA_CATEGORY_REPLAY,
int(DataCategory.MONITOR): ProtoDataCategory.DATA_CATEGORY_MONITOR,
int(DataCategory.SPAN): ProtoDataCategory.DATA_CATEGORY_SPAN,
int(DataCategory.USER_REPORT_V2): ProtoDataCategory.DATA_CATEGORY_USER_REPORT_V2,
int(DataCategory.PROFILE_DURATION): ProtoDataCategory.DATA_CATEGORY_PROFILE_DURATION,
int(DataCategory.LOG_BYTE): ProtoDataCategory.DATA_CATEGORY_LOG_BYTE,
int(DataCategory.PROFILE_DURATION_UI): ProtoDataCategory.DATA_CATEGORY_PROFILE_DURATION_UI,
int(DataCategory.SEER_AUTOFIX): ProtoDataCategory.DATA_CATEGORY_SEER_AUTOFIX,
int(DataCategory.SEER_SCANNER): ProtoDataCategory.DATA_CATEGORY_SEER_SCANNER,
int(DataCategory.SIZE_ANALYSIS): ProtoDataCategory.DATA_CATEGORY_SIZE_ANALYSIS,
int(DataCategory.INSTALLABLE_BUILD): ProtoDataCategory.DATA_CATEGORY_INSTALLABLE_BUILD,
int(DataCategory.TRACE_METRIC): ProtoDataCategory.DATA_CATEGORY_TRACE_METRIC,
int(DataCategory.DEFAULT): ProtoDataCategory.DATA_CATEGORY_DEFAULT,
int(DataCategory.SECURITY): ProtoDataCategory.DATA_CATEGORY_SECURITY,
int(DataCategory.PROFILE_CHUNK): ProtoDataCategory.DATA_CATEGORY_PROFILE_CHUNK,
int(DataCategory.PROFILE_CHUNK_UI): ProtoDataCategory.DATA_CATEGORY_PROFILE_CHUNK_UI,
}


PROTO_TO_SENTRY_CATEGORY: dict[int, int] = {v: k for k, v in SENTRY_TO_PROTO_CATEGORY.items()}


def proto_to_sentry_category(proto_category: int) -> int:
"""Convert a proto DataCategory to its Sentry equivalent.

For categories with a known mapping, returns the sentry int value.
For unmapped categories, passes through the original int value and
emits a metric so we can track how often this happens.
"""
result = PROTO_TO_SENTRY_CATEGORY.get(proto_category)
if result is None:
metrics.incr(
"billing.proto_category_mapping.unmapped_reverse",
tags={"proto_category": str(proto_category)},
)
return proto_category
return result


def sentry_to_proto_category(category: int | DataCategory) -> ProtoDataCategory.ValueType:
"""Convert a Sentry DataCategory to its proto equivalent.

For categories with a known mapping, returns the proto enum value.
For unmapped categories, passes through the original int value and
emits a metric so we can track how often this happens.
"""
cat_int = int(category)
result = SENTRY_TO_PROTO_CATEGORY.get(cat_int)
if result is None:
metrics.incr(
"billing.proto_category_mapping.unmapped",
tags={"sentry_category": str(cat_int)},
)
return ProtoDataCategory.ValueType(cat_int)
return ProtoDataCategory.ValueType(result)
50 changes: 0 additions & 50 deletions src/sentry/billing/platform/services/usage/_category_mapping.py

This file was deleted.

4 changes: 2 additions & 2 deletions src/sentry/billing/platform/services/usage/_outcomes_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
)
from snuba_sdk.orderby import Direction

from sentry.billing.platform.services.usage._category_mapping import proto_to_relay_category
from sentry.billing.platform.services.category_mapping import proto_to_sentry_category
from sentry.snuba.referrer import Referrer
from sentry.utils import metrics
from sentry.utils.outcomes import Outcome
Expand Down Expand Up @@ -58,7 +58,7 @@ def query_outcomes_usage(request: GetUsageRequest) -> GetUsageResponse:
end = _timestamp_to_datetime(request.end) + timedelta(days=1)
# Proto categories use different int values from Relay/ClickHouse
# (e.g., proto ATTACHMENT=3 vs Relay ATTACHMENT=4). Convert before querying.
categories = [proto_to_relay_category(c) for c in request.categories]
categories = [proto_to_sentry_category(c) for c in request.categories]

snuba_request = _build_query(org_id, start, end, categories, total_outcomes=_BILLABLE_OUTCOMES)
result = raw_snql_query(snuba_request, referrer=_REFERRER)
Expand Down
3 changes: 0 additions & 3 deletions src/sentry/conf/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3273,9 +3273,6 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]:
]
SENTRY_MONOLITH_REGION = SENTRY_CELLS[0]["name"]

# TODO(cells): remove after getsentry updated
SENTRY_REGION_CONFIG = SENTRY_CELLS

# Cross region RPC authentication
RPC_SHARED_SECRET = [
"a-long-value-that-is-shared-but-also-secret",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from rest_framework.request import Request
from rest_framework.response import Response

Expand All @@ -15,8 +17,11 @@
from sentry.plugins.base import plugins
from sentry.sentry_apps.services.app import app_service

if TYPE_CHECKING:
from django.utils.functional import _StrPromise


def get_provider_name(provider_type: str, provider_slug: str) -> str | None:
def get_provider_name(provider_type: str, provider_slug: str) -> str | _StrPromise | None:
"""
The things that users think of as "integrations" are actually three
different things: integrations, plugins, and sentryapps. A user requesting
Expand Down
7 changes: 5 additions & 2 deletions src/sentry/integrations/github/webhook_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ class GithubWebhookType(StrEnum):


# Event type strings (X-GitHub-Event header values) that the cell webhook endpoint processes.
# INSTALLATION is handled in control only.
# INSTALLATION and INSTALLATION_REPOSITORIES are handled in control only.
_CONTROL_ONLY_EVENTS = frozenset(
{GithubWebhookType.INSTALLATION, GithubWebhookType.INSTALLATION_REPOSITORIES}
)
CELL_PROCESSED_GITHUB_EVENTS = frozenset(
t.value for t in GithubWebhookType if t != GithubWebhookType.INSTALLATION
t.value for t in GithubWebhookType if t not in _CONTROL_ONLY_EVENTS
)
4 changes: 2 additions & 2 deletions src/sentry/middleware/integrations/parsers/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
get_github_external_id,
)
from sentry.integrations.github.webhook_types import (
_CONTROL_ONLY_EVENTS,
CELL_PROCESSED_GITHUB_EVENTS,
GITHUB_WEBHOOK_TYPE_HEADER,
GithubWebhookType,
)
from sentry.integrations.middleware.hybrid_cloud.parser import BaseRequestParser
from sentry.integrations.models.integration import Integration
Expand Down Expand Up @@ -77,7 +77,7 @@ def get_mailbox_identifier(
def should_route_to_control_silo(
self, parsed_event: Mapping[str, Any], request: HttpRequest
) -> bool:
return request.META.get(GITHUB_WEBHOOK_TYPE_HEADER) == GithubWebhookType.INSTALLATION
return request.META.get(GITHUB_WEBHOOK_TYPE_HEADER) in _CONTROL_ONLY_EVENTS

@control_silo_function
def get_integration_from_request(self) -> Integration | None:
Expand Down
Loading
Loading