Skip to content

Commit

Permalink
Merge branch 'master' into abdk/explore-charts-syncing
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdkhan14 committed Sep 28, 2024
2 parents 548c2d4 + 6564a46 commit 0c92300
Show file tree
Hide file tree
Showing 20 changed files with 376 additions and 739 deletions.
4 changes: 3 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ yarn.lock @getsentry/owners-js-de

/tests/snuba/search/test_backend.py @getsentry/visibility

/src/sentry/search/events/ @getsentry/visibility @getsentry/issues
/src/sentry/search/events/ @getsentry/visibility

/src/sentry/utils/performance_issues/ @getsentry/performance

Expand Down Expand Up @@ -519,6 +519,8 @@ tests/sentry/api/endpoints/test_organization_dashboard_widget_details.py @ge
/src/sentry/grouping/ @getsentry/issues
/src/sentry/mediators/ @getsentry/issues
/src/sentry/ratelimits/ @getsentry/issues
/src/sentry/search/events/builder/issue_platform.py @getsentry/issues
/src/sentry/search/events/builder/errors.py @getsentry/issues
/src/sentry/search/snuba/ @getsentry/issues
/src/sentry/seer/similarity/ @getsentry/issues
/src/sentry/tasks/auto_ongoing_issues.py @getsentry/issues
Expand Down
2 changes: 1 addition & 1 deletion api-docs/paths/events/issue-details.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
"properties": {
"status": {
"type": "string",
"description": "The new status for the issues. Valid values are `\"resolved\"`, `\"reprocessing\"`, `\"unresolved\"`, and `\"ignored\"`."
"description": "The new status for the issues. Valid values are `\"resolved\"`, `\"resolvedInNextRelease\"`, `\"unresolved\"`, and `\"ignored\"`."
},
"statusDetails": {
"type": "object",
Expand Down
7 changes: 0 additions & 7 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,8 @@ const {
GITHUB_PR_REF,
GITHUB_RUN_ID,
GITHUB_RUN_ATTEMPT,
USING_YARN_TEST,
} = process.env;

if (USING_YARN_TEST === undefined) {
// eslint-disable-next-line no-console
console.error('Do not run `jest` directly, use `yarn test` instead!');
process.exit();
}

const IS_MASTER_BRANCH = GITHUB_PR_REF === 'refs/heads/master';

const BALANCE_RESULTS_PATH = path.resolve(
Expand Down
3 changes: 0 additions & 3 deletions scripts/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
process.env.TZ = 'America/New_York';

// Marker to indicate that we've correctly ran with `yarn test`.
process.env.USING_YARN_TEST = true;

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
Expand Down
40 changes: 23 additions & 17 deletions src/sentry/api/endpoints/debug_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from symbolic.debuginfo import normalize_debug_id
from symbolic.exceptions import SymbolicError

from sentry import ratelimits, roles
from sentry import ratelimits
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import region_silo_endpoint
Expand All @@ -39,6 +39,7 @@
from sentry.models.project import Project
from sentry.models.release import Release, get_artifact_counts
from sentry.models.releasefile import ReleaseFile
from sentry.roles import organization_roles
from sentry.tasks.assemble import (
AssembleTask,
ChunkFileState,
Expand All @@ -53,15 +54,15 @@
_release_suffix = re.compile(r"^(.*)\s+\(([^)]+)\)\s*$")


def upload_from_request(request, project):
def upload_from_request(request: Request, project: Project):
if "file" not in request.data:
return Response({"detail": "Missing uploaded file"}, status=400)
fileobj = request.data["file"]
files = create_files_from_dif_zip(fileobj, project=project)
return Response(serialize(files, request.user), status=201)


def has_download_permission(request, project):
def has_download_permission(request: Request, project: Project):
if is_system_auth(request.auth) or is_active_superuser(request):
return True

Expand All @@ -72,7 +73,7 @@ def has_download_permission(request, project):
required_role = organization.get_option("sentry:debug_files_role") or DEBUG_FILES_ROLE_DEFAULT

if request.user.is_sentry_app:
if roles.get(required_role).priority > roles.get("member").priority:
if organization_roles.can_manage("member", required_role):
return request.access.has_scope("project:write")
else:
return request.access.has_scope("project:read")
Expand All @@ -86,7 +87,12 @@ def has_download_permission(request, project):
except OrganizationMember.DoesNotExist:
return False

return roles.get(current_role).priority >= roles.get(required_role).priority
if organization_roles.can_manage(current_role, required_role):
return True

# There's an edge case where a team admin is an org member but the required
# role is org admin. In that case, the team admin should be able to download.
return required_role == "admin" and request.access.has_project_scope(project, "project:write")


def _has_delete_permission(access: Access, project: Project) -> bool:
Expand All @@ -104,7 +110,7 @@ class ProguardArtifactReleasesEndpoint(ProjectEndpoint):
}
permission_classes = (ProjectReleasePermission,)

def post(self, request: Request, project) -> Response:
def post(self, request: Request, project: Project) -> Response:
release_name = request.data.get("release_name")
proguard_uuid = request.data.get("proguard_uuid")

Expand Down Expand Up @@ -153,7 +159,7 @@ def post(self, request: Request, project) -> Response:
status=status.HTTP_409_CONFLICT,
)

def get(self, request: Request, project) -> Response:
def get(self, request: Request, project: Project) -> Response:
"""
List a Project's Proguard Associated Releases
````````````````````````````````````````
Expand Down Expand Up @@ -189,7 +195,7 @@ class DebugFilesEndpoint(ProjectEndpoint):
}
permission_classes = (ProjectReleasePermission,)

def download(self, debug_file_id, project):
def download(self, debug_file_id, project: Project):
rate_limited = ratelimits.backend.is_limited(
project=project,
key=f"rl:DSymFilesEndpoint:download:{debug_file_id}:{project.id}",
Expand Down Expand Up @@ -223,7 +229,7 @@ def download(self, debug_file_id, project):
except OSError:
raise Http404

def get(self, request: Request, project) -> Response:
def get(self, request: Request, project: Project) -> Response:
"""
List a Project's Debug Information Files
````````````````````````````````````````
Expand All @@ -240,7 +246,7 @@ def get(self, request: Request, project) -> Response:
:auth: required
"""
download_requested = request.GET.get("id") is not None
if download_requested and (has_download_permission(request, project)):
if download_requested and has_download_permission(request, project):
return self.download(request.GET.get("id"), project)
elif download_requested:
return Response(status=403)
Expand Down Expand Up @@ -335,7 +341,7 @@ def delete(self, request: Request, project: Project) -> Response:

return Response(status=404)

def post(self, request: Request, project) -> Response:
def post(self, request: Request, project: Project) -> Response:
"""
Upload a New File
`````````````````
Expand Down Expand Up @@ -367,7 +373,7 @@ class UnknownDebugFilesEndpoint(ProjectEndpoint):
}
permission_classes = (ProjectReleasePermission,)

def get(self, request: Request, project) -> Response:
def get(self, request: Request, project: Project) -> Response:
checksums = request.GET.getlist("checksums")
missing = ProjectDebugFile.objects.find_missing(checksums, project=project)
return Response({"missing": missing})
Expand All @@ -382,7 +388,7 @@ class AssociateDSymFilesEndpoint(ProjectEndpoint):
permission_classes = (ProjectReleasePermission,)

# Legacy endpoint, kept for backwards compatibility
def post(self, request: Request, project) -> Response:
def post(self, request: Request, project: Project) -> Response:
return Response({"associatedDsymFiles": []})


Expand All @@ -394,7 +400,7 @@ class DifAssembleEndpoint(ProjectEndpoint):
}
permission_classes = (ProjectReleasePermission,)

def post(self, request: Request, project) -> Response:
def post(self, request: Request, project: Project) -> Response:
"""
Assemble one or multiple chunks (FileBlob) into debug files
````````````````````````````````````````````````````````````
Expand Down Expand Up @@ -517,7 +523,7 @@ class SourceMapsEndpoint(ProjectEndpoint):
}
permission_classes = (ProjectReleasePermission,)

def get(self, request: Request, project) -> Response:
def get(self, request: Request, project: Project) -> Response:
"""
List a Project's Source Map Archives
````````````````````````````````````
Expand Down Expand Up @@ -549,7 +555,7 @@ def get(self, request: Request, project) -> Response:

queryset = queryset.filter(query_q)

def expose_release(release, count):
def expose_release(release, count: int):
return {
"type": "release",
"id": release["id"],
Expand Down Expand Up @@ -581,7 +587,7 @@ def serialize_results(results):
on_results=serialize_results,
)

def delete(self, request: Request, project) -> Response:
def delete(self, request: Request, project: Project) -> Response:
"""
Delete an Archive
```````````````````````````````````````````````````
Expand Down
27 changes: 6 additions & 21 deletions src/sentry/event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,7 @@
GroupingConfig,
get_grouping_config_dict_for_project,
)
from sentry.grouping.ingest.config import (
is_in_transition,
project_uses_optimized_grouping,
update_grouping_config_if_needed,
)
from sentry.grouping.ingest.config import is_in_transition, update_grouping_config_if_needed
from sentry.grouping.ingest.hashing import (
find_existing_grouphash,
get_hash_values,
Expand Down Expand Up @@ -517,12 +513,10 @@ def save(
return jobs[0]["event"]
else:
project = job["event"].project
job["optimized_grouping"] = project_uses_optimized_grouping(project)
job["in_grouping_transition"] = is_in_transition(project)
metric_tags = {
"platform": job["event"].platform or "unknown",
"sdk": normalized_sdk_tag_from_event(job["event"].data),
"using_transition_optimization": job["optimized_grouping"],
"in_transition": job["in_grouping_transition"],
}
# This metric allows differentiating from all calls to the `event_manager.save` metric
Expand Down Expand Up @@ -1323,20 +1317,11 @@ def get_culprit(data: Mapping[str, Any]) -> str:

@sentry_sdk.tracing.trace
def assign_event_to_group(event: Event, job: Job, metric_tags: MutableTags) -> GroupInfo | None:
if job["optimized_grouping"]:
group_info = _save_aggregate_new(
event=event,
job=job,
metric_tags=metric_tags,
)
else:
group_info = _save_aggregate(
event=event,
job=job,
release=job["release"],
received_timestamp=job["received_timestamp"],
metric_tags=metric_tags,
)
group_info = _save_aggregate_new(
event=event,
job=job,
metric_tags=metric_tags,
)

if group_info:
event.group = group_info.group
Expand Down
3 changes: 1 addition & 2 deletions src/sentry/grouping/ingest/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from sentry import options
from sentry.grouping.api import GroupingConfig
from sentry.grouping.ingest.config import is_in_transition, project_uses_optimized_grouping
from sentry.grouping.ingest.config import is_in_transition
from sentry.models.project import Project
from sentry.utils import metrics
from sentry.utils.tag_normalization import normalized_sdk_tag_from_event
Expand Down Expand Up @@ -65,7 +65,6 @@ def record_calculation_metric_with_result(
# count to get an average number of calculations per event
tags = {
"in_transition": str(is_in_transition(project)),
"using_transition_optimization": str(project_uses_optimized_grouping(project)),
"result": result,
}
metrics.incr(
Expand Down
2 changes: 1 addition & 1 deletion src/sentry/roles/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
get_choices = default_manager.get_choices
get_default = default_manager.get_default
get_top_dog = default_manager.get_top_dog
with_scope = default_manager.with_scope
with_any_scope = default_manager.with_any_scope
with_scope = default_manager.with_scope
2 changes: 1 addition & 1 deletion src/sentry/seer/anomaly_detection/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def fetch_historical_data(
dataset_label = "errors"
elif dataset_label in ["generic_metrics", "transactions"]:
# XXX: performance alerts dataset differs locally vs in prod
dataset_label = "discover"
dataset_label = "metricsEnhanced"
dataset = get_dataset(dataset_label)

if not project or not dataset or not alert_rule.organization:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function TagDetailsDrawerContent({
const {
data: tag,
isError: tagIsError,
isLoading: tagIsLoading,
isPending: tagIsLoading,
} = useFetchIssueTag({
orgSlug: organization.slug,
groupId,
Expand Down
31 changes: 1 addition & 30 deletions static/app/views/issueList/addViewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import InteractionStateLayer from 'sentry/components/interactionStateLayer';
import ExternalLink from 'sentry/components/links/externalLink';
import QuestionTooltip from 'sentry/components/questionTooltip';
import {FormattedQuery} from 'sentry/components/searchQueryBuilder/formattedQuery';
import {IconClose, IconMegaphone} from 'sentry/icons';
import {IconClose} from 'sentry/icons';
import {t, tn} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import type {SavedSearch} from 'sentry/types/group';
import {trackAnalytics} from 'sentry/utils/analytics';
import {useFeedbackForm} from 'sentry/utils/useFeedbackForm';
import useOrganization from 'sentry/utils/useOrganization';
import {OverflowEllipsisTextContainer} from 'sentry/views/insights/common/components/textAlign';
import {NewTabContext} from 'sentry/views/issueList/utils/newTabContext';
Expand Down Expand Up @@ -154,7 +153,6 @@ function AddViewBanner({hasSavedSearches}: {hasSavedSearches: boolean}) {
>
{t('Read Docs')}
</FittedLinkButton>
<FeedbackButton />
</Banner>
) : null;
}
Expand Down Expand Up @@ -274,33 +272,6 @@ function SearchSuggestionList({
);
}

function FeedbackButton() {
const openForm = useFeedbackForm();

if (!openForm) {
return null;
}

return (
<Button
size="xs"
icon={<IconMegaphone />}
onClick={() =>
openForm({
messagePlaceholder: t('How can we make custom views better for you?'),
tags: {
['feedback.source']: 'custom_views',
['feedback.owner']: 'issues',
},
})
}
style={{width: 'fit-content'}}
>
{t('Give Feedback')}
</Button>
);
}

export default AddViewPage;

const Suggestions = styled('section')`
Expand Down
Loading

0 comments on commit 0c92300

Please sign in to comment.