Skip to content

feat(seer): Add project flag to auto run issue summaries #90719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions src/sentry/api/endpoints/project_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ class ProjectAdminSerializer(ProjectMemberSerializer):
performanceIssueSendToPlatform = serializers.BooleanField(required=False)
tempestFetchScreenshots = serializers.BooleanField(required=False)
tempestFetchDumps = serializers.BooleanField(required=False)
autoRunIssueSummaries = serializers.BooleanField(required=False)

# DO NOT ADD MORE TO OPTIONS
# Each param should be a field in the serializer like above.
Expand Down Expand Up @@ -455,6 +456,15 @@ def validate_tempestFetchDumps(self, value):
)
return value

def validate_autoRunIssueSummaries(self, value):
organization = self.context["project"]
actor = self.context["request"]
if not features.has("projects:trigger-issue-summary-on-alerts", organization, actor=actor):
raise serializers.ValidationError(
"Your organization does not have access to enable automatic issue summaries."
)
return value


class RelaxedProjectPermission(ProjectPermission):
scope_map = {
Expand Down Expand Up @@ -762,6 +772,14 @@ def put(self, request: Request, project) -> Response:
"dynamicSamplingBiases"
]

if result.get("autoRunIssueSummaries") is not None:
if project.update_option(
"sentry:auto_run_issue_summaries", result["autoRunIssueSummaries"]
):
changed_proj_settings["sentry:auto_run_issue_summaries"] = result[
"autoRunIssueSummaries"
]

if has_elevated_scopes:
options = result.get("options", {})
if "sentry:origins" in options:
Expand Down
6 changes: 6 additions & 0 deletions src/sentry/api/serializers/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,9 @@ def serialize(
},
"symbolSources": serialized_sources,
"isDynamicallySampled": sample_rate is not None and sample_rate < 1.0,
"autoRunIssueSummaries": bool(
self.get_value_with_default(attrs, "sentry:auto_run_issue_summaries")
),
}

if has_tempest_access(obj.organization, user):
Expand Down Expand Up @@ -1149,6 +1152,9 @@ def format_options(self, attrs: Mapping[str, Any]) -> dict[str, Any]:
self.get_value_with_default(attrs, "sentry:toolbar_allowed_origins") or []
),
"quotas:spike-protection-disabled": options.get("quotas:spike-protection-disabled"),
"sentry:auto_run_issue_summaries": bool(
self.get_value_with_default(attrs, "sentry:auto_run_issue_summaries")
),
}

def get_value_with_default(self, attrs, key):
Expand Down
1 change: 1 addition & 0 deletions src/sentry/models/options/project_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"filters:react-hydration-errors",
"filters:chunk-load-error",
"relay.cardinality-limiter.limits",
"sentry:auto_run_issue_summaries",
]
)

Expand Down
3 changes: 3 additions & 0 deletions src/sentry/projectoptions/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,6 @@

# Should tempest fetch dumps for this project
register(key="sentry:tempest_fetch_dumps", default=False)

# Auto-enable issue summaries for projects
register(key="sentry:auto_run_issue_summaries", default=True)
29 changes: 29 additions & 0 deletions tests/sentry/api/endpoints/test_project_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,35 @@ def test_target_sample_rate(self):
self.get_success_response(self.org_slug, self.proj_slug, targetSampleRate=0.1)
assert self.project.get_option("sentry:target_sample_rate") == 0.1

def test_auto_run_issue_summaries(self):
# Check default is True
response = self.get_success_response(self.organization.slug, self.project.slug)
assert response.data["options"]["sentry:auto_run_issue_summaries"] is True
assert self.project.get_option("sentry:auto_run_issue_summaries") is True

# Try to set to True without flag
self.get_error_response(
self.organization.slug,
self.project.slug,
autoRunIssueSummaries=True,
status_code=400,
)

# Enable flag and set to True
with self.feature("projects:trigger-issue-summary-on-alerts"):
response = self.get_success_response(
self.organization.slug, self.project.slug, autoRunIssueSummaries=True
)
assert response.data["options"]["sentry:auto_run_issue_summaries"] is True
assert self.project.get_option("sentry:auto_run_issue_summaries") is True

# Set to False
response = self.get_success_response(
self.organization.slug, self.project.slug, autoRunIssueSummaries=False
)
assert response.data["options"]["sentry:auto_run_issue_summaries"] is False
assert self.project.get_option("sentry:auto_run_issue_summaries") is False


class CopyProjectSettingsTest(APITestCase):
endpoint = "sentry-api-0-project-details"
Expand Down
11 changes: 11 additions & 0 deletions tests/sentry/api/serializers/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,17 @@ def test_replay_hydration_error_flag(self):
result = serialize(self.project, self.user, DetailedProjectSerializer())
assert result["options"]["sentry:replay_hydration_error_issues"] is False

def test_auto_run_issue_summaries_flag(self):
result = serialize(self.project, self.user, DetailedProjectSerializer())
# default should be true
assert result["options"]["sentry:auto_run_issue_summaries"] is True
assert result["autoRunIssueSummaries"] is True

self.project.update_option("sentry:auto_run_issue_summaries", False)
result = serialize(self.project, self.user, DetailedProjectSerializer())
assert result["options"]["sentry:auto_run_issue_summaries"] is False
assert result["autoRunIssueSummaries"] is False

def test_toolbar_allowed_origins(self):
# Does not allow trailing newline or extra whitespace.
# Default is empty:
Expand Down
Loading