Skip to content

Commit 3f33d1f

Browse files
authored
Merge branch 'master' into cmanallen/release-optimize-another-query
2 parents 1866851 + 7ad8261 commit 3f33d1f

File tree

85 files changed

+1265
-547
lines changed

Some content is hidden

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

85 files changed

+1265
-547
lines changed

.github/file-filters.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ typecheckable_rules_changed: &typecheckable_rules_changed
3131
# Trigger to apply the 'Scope: Frontend' label to PRs
3232
frontend_all: &frontend_all
3333
- added|modified: '**/*.{ts,tsx,js,jsx,mjs}'
34-
- added|modified: 'static/**/*.{less,json,yml,md}'
34+
- added|modified: 'static/**/*.{less,json,yml,md,mdx}'
3535
- added|modified: '{.volta,vercel,tsconfig,biome,package}.json'
3636

3737
# Also used in `getsentry-dispatch.yml` to dispatch backend tests on getsentry

migrations_lockfile.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ ahead of you.
55
To resolve this, rebase against latest master and regenerate your migration. This file
66
will then be regenerated, and you should be able to merge without conflicts.
77

8-
discover: 0001_move_discover_models
8+
discover: 0002_link_migrated_explore_query_in_discover
99

10-
explore: 0005_explore_django_json_field
10+
explore: 0006_add_changed_reason_field_explore
1111

1212
feedback: 0001_squashed_0004_index_together
1313

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ module = [
8888
"confluent_kafka.*",
8989
"cssselect.*",
9090
"django_zero_downtime_migrations.backends.postgres.schema.*",
91-
"docker.*",
9291
"fido2.*",
9392
"google.auth.*",
9493
"google.cloud.*",

requirements-dev-frozen.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ trio==0.25.0
217217
trio-websocket==0.11.1
218218
types-beautifulsoup4==4.11.6
219219
types-cachetools==5.3.0.5
220+
types-docker==7.1.0.20250705
220221
types-jsonschema==4.16.1
221222
types-oauthlib==3.2.0.8
222223
types-parsimonious==0.10.0.8

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ msgpack-types>=0.2.0
4646
mypy>=1.15
4747
types-beautifulsoup4
4848
types-cachetools
49+
types-docker
4950
types-jsonschema
5051
types-oauthlib
5152
types-parsimonious

src/sentry/api/urls.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,20 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
10541054
),
10551055
]
10561056

1057+
PREVENT_URLS = [
1058+
re_path(
1059+
r"^owner/(?P<owner>[^/]+)/repository/(?P<repository>[^/]+)/test-results/$",
1060+
TestResultsEndpoint.as_view(),
1061+
name="sentry-api-0-test-results",
1062+
),
1063+
re_path(
1064+
r"^owner/(?P<owner>[^/]+)/repository/(?P<repository>[^/]+)/test-results-aggregates/$",
1065+
TestResultsAggregatesEndpoint.as_view(),
1066+
name="sentry-api-0-test-results-aggregates",
1067+
),
1068+
]
1069+
1070+
10571071
USER_URLS = [
10581072
re_path(
10591073
r"^$",
@@ -2395,6 +2409,10 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
23952409
OrganizationInsightsTreeEndpoint.as_view(),
23962410
name="sentry-api-0-organization-insights-tree",
23972411
),
2412+
re_path(
2413+
r"^(?P<organization_id_or_slug>[^/]+)/prevent/",
2414+
include(PREVENT_URLS),
2415+
),
23982416
*workflow_urls.organization_urlpatterns,
23992417
]
24002418

@@ -3296,19 +3314,6 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
32963314
*preprod_urls.preprod_internal_urlpatterns,
32973315
]
32983316

3299-
PREVENT_URLS = [
3300-
re_path(
3301-
r"^owner/(?P<owner>[^/]+)/repository/(?P<repository>[^/]+)/test-results/$",
3302-
TestResultsEndpoint.as_view(),
3303-
name="sentry-api-0-test-results",
3304-
),
3305-
re_path(
3306-
r"^owner/(?P<owner>[^/]+)/repository/(?P<repository>[^/]+)/test-results-aggregates/$",
3307-
TestResultsAggregatesEndpoint.as_view(),
3308-
name="sentry-api-0-test-results-aggregates",
3309-
),
3310-
]
3311-
33123317
urlpatterns = [
33133318
# Relay
33143319
re_path(
@@ -3374,11 +3379,6 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]:
33743379
r"^broadcasts/",
33753380
include(BROADCAST_URLS),
33763381
),
3377-
# Prevent
3378-
re_path(
3379-
r"^prevent/",
3380-
include(PREVENT_URLS),
3381-
),
33823382
#
33833383
#
33843384
#

src/sentry/codecov/endpoints/TestResults/test_results.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from sentry.api.api_publish_status import ApiPublishStatus
88
from sentry.api.base import region_silo_endpoint
99
from sentry.apidocs.constants import RESPONSE_BAD_REQUEST, RESPONSE_FORBIDDEN, RESPONSE_NOT_FOUND
10-
from sentry.apidocs.parameters import PreventParams
10+
from sentry.apidocs.parameters import GlobalParams, PreventParams
1111
from sentry.codecov.base import CodecovEndpoint
1212
from sentry.codecov.client import CodecovApiClient
1313
from sentry.codecov.endpoints.TestResults.query import query
@@ -29,8 +29,9 @@ def has_pagination(self, response):
2929
return True
3030

3131
@extend_schema(
32-
operation_id="Retrieve paginated list of test results for repository and owner",
32+
operation_id="Retrieve paginated list of test results for repository, owner, and organization",
3333
parameters=[
34+
GlobalParams.ORG_ID_OR_SLUG,
3435
PreventParams.OWNER,
3536
PreventParams.REPOSITORY,
3637
PreventParams.TEST_RESULTS_SORT_BY,
@@ -49,7 +50,9 @@ def has_pagination(self, response):
4950
404: RESPONSE_NOT_FOUND,
5051
},
5152
)
52-
def get(self, request: Request, owner: str, repository: str, **kwargs) -> Response:
53+
def get(
54+
self, request: Request, organization_id_or_slug: str, owner: str, repository: str, **kwargs
55+
) -> Response:
5356
"""Retrieves the list of test results for a given repository and owner. Also accepts a number of query parameters to filter the results."""
5457

5558
sort_by = request.query_params.get(

src/sentry/codecov/endpoints/TestResultsAggregates/test_results_aggregates.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from sentry.api.api_publish_status import ApiPublishStatus
77
from sentry.api.base import region_silo_endpoint
88
from sentry.apidocs.constants import RESPONSE_BAD_REQUEST, RESPONSE_FORBIDDEN, RESPONSE_NOT_FOUND
9-
from sentry.apidocs.parameters import PreventParams
9+
from sentry.apidocs.parameters import GlobalParams, PreventParams
1010
from sentry.codecov.base import CodecovEndpoint
1111
from sentry.codecov.client import CodecovApiClient
1212
from sentry.codecov.endpoints.TestResultsAggregates.query import query
@@ -27,8 +27,9 @@ class TestResultsAggregatesEndpoint(CodecovEndpoint):
2727
}
2828

2929
@extend_schema(
30-
operation_id="Retrieve aggregated test result metrics for repository and owner",
30+
operation_id="Retrieve aggregated test result metrics for repository, owner, and organization",
3131
parameters=[
32+
GlobalParams.ORG_ID_OR_SLUG,
3233
PreventParams.OWNER,
3334
PreventParams.REPOSITORY,
3435
PreventParams.INTERVAL,
@@ -41,7 +42,9 @@ class TestResultsAggregatesEndpoint(CodecovEndpoint):
4142
404: RESPONSE_NOT_FOUND,
4243
},
4344
)
44-
def get(self, request: Request, owner: str, repository: str, **kwargs) -> Response:
45+
def get(
46+
self, request: Request, organization_id_or_slug: str, owner: str, repository: str, **kwargs
47+
) -> Response:
4548
"""
4649
Retrieves aggregated test result metrics for a given repository and owner.
4750
Also accepts a query parameter to specify the time period for the metrics.

src/sentry/data_secrecy/data_access_grant_service/__init__.py

Whitespace-only changes.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from django.db import models
2+
from django.utils import timezone
3+
4+
from sentry.data_secrecy.data_access_grant_service.model import RpcEffectiveGrantStatus
5+
from sentry.data_secrecy.data_access_grant_service.serial import serialize_effective_grant_status
6+
from sentry.data_secrecy.data_access_grant_service.service import DataAccessGrantService
7+
from sentry.data_secrecy.models.data_access_grant import DataAccessGrant
8+
9+
10+
class DatabaseBackedDataAccessGrantService(DataAccessGrantService):
11+
def get_effective_grant_status(self, *, organization_id: int) -> RpcEffectiveGrantStatus | None:
12+
"""
13+
Get the effective grant status for an organization.
14+
"""
15+
now = timezone.now()
16+
active_grants = DataAccessGrant.objects.filter(
17+
organization_id=organization_id,
18+
grant_start__lte=now,
19+
grant_end__gt=now,
20+
revocation_date__isnull=True, # Not revoked
21+
)
22+
23+
if not active_grants.exists():
24+
return None
25+
26+
# Calculate aggregate grant status - only need the time window for access control
27+
min_start = active_grants.aggregate(min_start=models.Min("grant_start"))["min_start"]
28+
max_end = active_grants.aggregate(max_end=models.Max("grant_end"))["max_end"]
29+
30+
grant_status = {
31+
"access_start": min_start.isoformat(),
32+
"access_end": max_end.isoformat(),
33+
}
34+
35+
return serialize_effective_grant_status(grant_status, organization_id)

0 commit comments

Comments
 (0)