Skip to content

Commit 7dd4d3d

Browse files
committed
Merge branch 'master' into joshferge/aiml-1432-add-analytics-for-rca-reruns-and-micro-chat-interactions
2 parents 5402232 + 32c22de commit 7dd4d3d

File tree

1,155 files changed

+198908
-15299
lines changed

Some content is hidden

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

1,155 files changed

+198908
-15299
lines changed

.cursor/mcp.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
22
"mcpServers": {
33
"sentry": {
4-
"command": "npx",
5-
"args": ["-y", "mcp-remote@latest", "https://mcp.sentry.dev/sse"]
4+
"url": "https://mcp.sentry.dev/mcp"
65
}
76
}
87
}

AGENTS.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ class OrganizationDetailsTest(APITestCase):
290290
assert response.data["id"] == str(org.id)
291291
```
292292

293+
Notes:
294+
295+
- Tests should ALWAYS be procuderal with NO branching logic. It is very rare
296+
that you will need an if statement as part of a Frontend Jest test or backend
297+
pytest.
298+
293299
## Common Patterns
294300

295301
### Feature Flags
@@ -431,6 +437,17 @@ def my_function():
431437
...
432438
```
433439

440+
## Exception Handling
441+
442+
- Avoid blanket exception handling (`except Exception:` or bare `except:`)
443+
- Only catch specific exceptions when you have a meaningful way to handle them
444+
- We have global exception handlers in tasks and endpoints that automatically log errors and report them to Sentry
445+
- Let exceptions bubble up unless you need to:
446+
- Add context to the error
447+
- Perform cleanup operations
448+
- Convert one exception type to another with additional information
449+
- Recover from expected error conditions
450+
434451
## Performance Considerations
435452

436453
1. Use database indexing appropriately

fixtures/github.py

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3324,3 +3324,200 @@
33243324
"site_admin": false
33253325
}
33263326
}"""
3327+
ISSUES_CLOSED_EVENT_EXAMPLE = r"""{
3328+
"action": "closed",
3329+
"issue": {
3330+
"url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2",
3331+
"repository_url": "https://api.github.com/repos/baxterthehacker/public-repo",
3332+
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/labels{/name}",
3333+
"comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/comments",
3334+
"events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/events",
3335+
"html_url": "https://github.com/baxterthehacker/public-repo/issues/2",
3336+
"id": 73464126,
3337+
"number": 2,
3338+
"title": "Spelling error in the README file",
3339+
"user": {
3340+
"login": "baxterthehacker",
3341+
"id": 6752317,
3342+
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
3343+
"gravatar_id": "",
3344+
"url": "https://api.github.com/users/baxterthehacker",
3345+
"html_url": "https://github.com/baxterthehacker",
3346+
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
3347+
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
3348+
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
3349+
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
3350+
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
3351+
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
3352+
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
3353+
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
3354+
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
3355+
"type": "User",
3356+
"site_admin": false
3357+
},
3358+
"labels": [],
3359+
"state": "closed",
3360+
"locked": false,
3361+
"assignee": null,
3362+
"assignees": [],
3363+
"milestone": null,
3364+
"comments": 0,
3365+
"created_at": "2015-05-05T23:40:28Z",
3366+
"updated_at": "2015-05-05T23:40:28Z",
3367+
"closed_at": "2015-05-05T23:40:28Z",
3368+
"body": "It looks like you accidentally spelled 'commit' with two 't's."
3369+
},
3370+
"installation": {
3371+
"id": 12345
3372+
},
3373+
"repository": {
3374+
"id": 35129377,
3375+
"name": "public-repo",
3376+
"full_name": "baxterthehacker/public-repo",
3377+
"owner": {
3378+
"login": "baxterthehacker",
3379+
"id": 6752317,
3380+
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
3381+
"gravatar_id": "",
3382+
"url": "https://api.github.com/users/baxterthehacker",
3383+
"html_url": "https://github.com/baxterthehacker",
3384+
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
3385+
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
3386+
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
3387+
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
3388+
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
3389+
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
3390+
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
3391+
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
3392+
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
3393+
"type": "User",
3394+
"site_admin": false
3395+
},
3396+
"private": false,
3397+
"html_url": "https://github.com/baxterthehacker/public-repo",
3398+
"description": "",
3399+
"fork": false,
3400+
"url": "https://api.github.com/repos/baxterthehacker/public-repo",
3401+
"created_at": "2015-05-05T23:40:12Z",
3402+
"updated_at": "2015-05-05T23:40:12Z",
3403+
"pushed_at": "2015-05-05T23:40:27Z"
3404+
},
3405+
"sender": {
3406+
"login": "baxterthehacker",
3407+
"id": 6752317,
3408+
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
3409+
"gravatar_id": "",
3410+
"url": "https://api.github.com/users/baxterthehacker",
3411+
"html_url": "https://github.com/baxterthehacker",
3412+
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
3413+
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
3414+
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
3415+
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
3416+
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
3417+
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
3418+
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
3419+
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
3420+
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
3421+
"type": "User",
3422+
"site_admin": false
3423+
}
3424+
}"""
3425+
3426+
ISSUES_REOPENED_EVENT_EXAMPLE = r"""{
3427+
"action": "reopened",
3428+
"issue": {
3429+
"url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2",
3430+
"repository_url": "https://api.github.com/repos/baxterthehacker/public-repo",
3431+
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/labels{/name}",
3432+
"comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/comments",
3433+
"events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/events",
3434+
"html_url": "https://github.com/baxterthehacker/public-repo/issues/2",
3435+
"id": 73464126,
3436+
"number": 2,
3437+
"title": "Spelling error in the README file",
3438+
"user": {
3439+
"login": "baxterthehacker",
3440+
"id": 6752317,
3441+
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
3442+
"gravatar_id": "",
3443+
"url": "https://api.github.com/users/baxterthehacker",
3444+
"html_url": "https://github.com/baxterthehacker",
3445+
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
3446+
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
3447+
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
3448+
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
3449+
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
3450+
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
3451+
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
3452+
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
3453+
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
3454+
"type": "User",
3455+
"site_admin": false
3456+
},
3457+
"labels": [],
3458+
"state": "open",
3459+
"locked": false,
3460+
"assignee": null,
3461+
"assignees": [],
3462+
"milestone": null,
3463+
"comments": 0,
3464+
"created_at": "2015-05-05T23:40:28Z",
3465+
"updated_at": "2015-05-05T23:40:28Z",
3466+
"closed_at": null,
3467+
"body": "It looks like you accidentally spelled 'commit' with two 't's."
3468+
},
3469+
"installation": {
3470+
"id": 12345
3471+
},
3472+
"repository": {
3473+
"id": 35129377,
3474+
"name": "public-repo",
3475+
"full_name": "baxterthehacker/public-repo",
3476+
"owner": {
3477+
"login": "baxterthehacker",
3478+
"id": 6752317,
3479+
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
3480+
"gravatar_id": "",
3481+
"url": "https://api.github.com/users/baxterthehacker",
3482+
"html_url": "https://github.com/baxterthehacker",
3483+
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
3484+
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
3485+
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
3486+
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
3487+
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
3488+
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
3489+
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
3490+
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
3491+
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
3492+
"type": "User",
3493+
"site_admin": false
3494+
},
3495+
"private": false,
3496+
"html_url": "https://github.com/baxterthehacker/public-repo",
3497+
"description": "",
3498+
"fork": false,
3499+
"url": "https://api.github.com/repos/baxterthehacker/public-repo",
3500+
"created_at": "2015-05-05T23:40:12Z",
3501+
"updated_at": "2015-05-05T23:40:12Z",
3502+
"pushed_at": "2015-05-05T23:40:27Z"
3503+
},
3504+
"sender": {
3505+
"login": "baxterthehacker",
3506+
"id": 6752317,
3507+
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
3508+
"gravatar_id": "",
3509+
"url": "https://api.github.com/users/baxterthehacker",
3510+
"html_url": "https://github.com/baxterthehacker",
3511+
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
3512+
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
3513+
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
3514+
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
3515+
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
3516+
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
3517+
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
3518+
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
3519+
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
3520+
"type": "User",
3521+
"site_admin": false
3522+
}
3523+
}"""

migrations_lockfile.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ notifications: 0002_notificationmessage_jsonfield
2525

2626
preprod: 0018_add_preprod_artifact_app_icon_id_field
2727

28-
prevent: 0001_create_prevent_ai_configuration
28+
prevent: 0002_alter_integration_id_not_null
2929

30-
releases: 0001_release_models
30+
releases: 0002_delete_dual_written_commit_tables
3131

3232
replays: 0006_add_bulk_delete_job
3333

34-
sentry: 1000_add_project_distribution_scope
34+
sentry: 1001_prevent_grouphistory_infinte_recursion
3535

3636
social_auth: 0003_social_auth_json_field
3737

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ dependencies = [
8080
# [end] jsonschema format validators
8181
"sentry-arroyo>=2.30.0",
8282
"sentry-forked-email-reply-parser>=0.5.12.post1",
83-
"sentry-kafka-schemas>=2.1.11",
83+
"sentry-kafka-schemas>=2.1.13",
8484
"sentry-ophio>=1.1.3",
8585
"sentry-protos>=0.4.2",
8686
"sentry-redis-tools>=0.5.0",
8787
"sentry-relay>=0.9.17",
88-
"sentry-sdk[http2]>=2.42.0",
88+
"sentry-sdk[http2]>=2.43.0",
8989
"sentry-usage-accountant>=0.0.10",
9090
# remove once there are no unmarked transitive dependencies on setuptools
9191
"setuptools>=70.0.0",

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
from sentry.models.team import Team, TeamStatus
7878
from sentry.organizations.absolute_url import generate_organization_url
7979
from sentry.organizations.services.organization import RpcOrganizationSummary
80-
from sentry.types.prevent_config import PREVENT_AI_CONFIG_GITHUB_DEFAULT
8180
from sentry.users.models.user import User
8281
from sentry.users.services.user.model import RpcUser
8382
from sentry.users.services.user.service import user_service
@@ -555,7 +554,6 @@ class DetailedOrganizationSerializerResponse(_DetailedOrganizationSerializerResp
555554
streamlineOnly: bool
556555
defaultAutofixAutomationTuning: str
557556
defaultSeerScannerAutomation: bool
558-
preventAiConfigGithub: dict[str, Any]
559557
enablePrReviewTestGeneration: bool
560558
enableSeerEnhancedAlerts: bool
561559
enableSeerCoding: bool
@@ -697,10 +695,6 @@ def serialize( # type: ignore[override]
697695
"sentry:default_seer_scanner_automation",
698696
DEFAULT_SEER_SCANNER_AUTOMATION_DEFAULT,
699697
),
700-
"preventAiConfigGithub": obj.get_option(
701-
"sentry:prevent_ai_config_github",
702-
PREVENT_AI_CONFIG_GITHUB_DEFAULT,
703-
),
704698
"enablePrReviewTestGeneration": bool(
705699
obj.get_option(
706700
"sentry:enable_pr_review_test_generation",
@@ -781,7 +775,6 @@ def serialize( # type: ignore[override]
781775
"streamlineOnly",
782776
"ingestThroughTrustedRelaysOnly",
783777
"enabledConsolePlatforms",
784-
"preventAiConfigGithub",
785778
]
786779
)
787780
class DetailedOrganizationSerializerWithProjectsAndTeamsResponse(

src/sentry/api/urls.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@
220220
TeamAlertsTriggeredTotalsEndpoint,
221221
)
222222
from sentry.insights.endpoints.starred_segments import InsightsStarredSegmentsEndpoint
223+
from sentry.integrations.api.endpoints.data_forwarding_details import DataForwardingDetailsEndpoint
223224
from sentry.integrations.api.endpoints.data_forwarding_index import DataForwardingIndexEndpoint
224225
from sentry.integrations.api.endpoints.doc_integration_avatar import DocIntegrationAvatarEndpoint
225226
from sentry.integrations.api.endpoints.doc_integration_details import DocIntegrationDetailsEndpoint
@@ -439,6 +440,7 @@
439440
from sentry.prevent.endpoints.organization_github_repos import (
440441
OrganizationPreventGitHubReposEndpoint,
441442
)
443+
from sentry.prevent.endpoints.pr_review_github_config import OrganizationPreventGitHubConfigEndpoint
442444
from sentry.releases.endpoints.organization_release_assemble import (
443445
OrganizationReleaseAssembleEndpoint,
444446
)
@@ -514,6 +516,9 @@
514516
from sentry.seer.endpoints.organization_seer_explorer_chat import (
515517
OrganizationSeerExplorerChatEndpoint,
516518
)
519+
from sentry.seer.endpoints.organization_seer_explorer_runs import (
520+
OrganizationSeerExplorerRunsEndpoint,
521+
)
517522
from sentry.seer.endpoints.organization_seer_explorer_update import (
518523
OrganizationSeerExplorerUpdateEndpoint,
519524
)
@@ -1165,6 +1170,17 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
11651170
SyncReposEndpoint.as_view(),
11661171
name="sentry-api-0-repositories-sync",
11671172
),
1173+
# Prevent AI endpoints
1174+
re_path(
1175+
r"^ai/github/config/(?P<git_organization_name>[^/]+)/$",
1176+
OrganizationPreventGitHubConfigEndpoint.as_view(),
1177+
name="sentry-api-0-organization-prevent-github-config",
1178+
),
1179+
re_path(
1180+
r"^ai/github/repos/$",
1181+
OrganizationPreventGitHubReposEndpoint.as_view(),
1182+
name="sentry-api-0-organization-prevent-github-repos",
1183+
),
11681184
]
11691185

11701186
USER_URLS = [
@@ -1424,6 +1440,11 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
14241440
DataForwardingIndexEndpoint.as_view(),
14251441
name="sentry-api-0-organization-forwarding",
14261442
),
1443+
re_path(
1444+
r"^(?P<organization_id_or_slug>[^/]+)/forwarding/(?P<data_forwarder_id>[^/]+)/$",
1445+
DataForwardingDetailsEndpoint.as_view(),
1446+
name="sentry-api-0-organization-forwarding-details",
1447+
),
14271448
re_path(
14281449
r"^(?P<organization_id_or_slug>[^/]+)/codeowners-associations/$",
14291450
OrganizationCodeOwnersAssociationsEndpoint.as_view(),
@@ -2153,12 +2174,6 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
21532174
OrganizationRepositoryCommitsEndpoint.as_view(),
21542175
name="sentry-api-0-organization-repository-commits",
21552176
),
2156-
# Prevent AI endpoints
2157-
re_path(
2158-
r"^(?P<organization_id_or_slug>[^/]+)/prevent/github/repos/$",
2159-
OrganizationPreventGitHubReposEndpoint.as_view(),
2160-
name="sentry-api-0-organization-prevent-github-repos",
2161-
),
21622177
re_path(
21632178
r"^(?P<organization_id_or_slug>[^/]+)/plugins/$",
21642179
OrganizationPluginsEndpoint.as_view(),
@@ -2290,6 +2305,11 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
22902305
OrganizationSeerExplorerChatEndpoint.as_view(),
22912306
name="sentry-api-0-organization-seer-explorer-chat",
22922307
),
2308+
re_path(
2309+
r"^(?P<organization_id_or_slug>[^/]+)/seer/explorer-runs/$",
2310+
OrganizationSeerExplorerRunsEndpoint.as_view(),
2311+
name="sentry-api-0-organization-seer-explorer-runs",
2312+
),
22932313
re_path(
22942314
r"^(?P<organization_id_or_slug>[^/]+)/seer/explorer-update/(?P<run_id>[^/]+)/$",
22952315
OrganizationSeerExplorerUpdateEndpoint.as_view(),

0 commit comments

Comments
 (0)