Skip to content
Merged
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
10 changes: 8 additions & 2 deletions src/sentry/seer/autofix/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from sentry.models.repository import Repository
from sentry.net.http import connection_from_url
from sentry.seer.autofix.constants import AutofixAutomationTuningSettings, AutofixStatus
from sentry.seer.constants import SEER_SUPPORTED_SCM_PROVIDERS
from sentry.seer.models import (
BranchOverride,
SeerApiError,
Expand Down Expand Up @@ -777,8 +778,13 @@ def get_autofix_repos_from_project_code_mappings(
repo: Repository = code_mapping.repository
repo_name_sections = repo.name.split("/")

# We expect a repository name to be in the format of "owner/name" for now.
if len(repo_name_sections) > 1 and repo.provider:
if (
# We expect a repository name to be in the format of "owner/name" for now.
len(repo_name_sections) > 1
# Filter out code mappings with unsupported providers.
and repo.provider
and repo.provider in SEER_SUPPORTED_SCM_PROVIDERS
):
repo_dict = {
"repository_id": repo.id,
"organization_id": repo.organization_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
default_seer_project_preference,
resolve_repository_ids,
)
from sentry.seer.constants import SEER_SUPPORTED_SCM_PROVIDERS
from sentry.seer.models import SeerProjectPreference, SeerRepoDefinition
from sentry.seer.utils import filter_repo_by_provider

Expand Down Expand Up @@ -67,6 +68,14 @@ class RepositorySerializer(CamelSnakeSerializer):
base_commit_sha = serializers.CharField(required=False, allow_null=True)
provider_raw = serializers.CharField(required=False, allow_null=True)

def validate_provider(self, value):
if value not in SEER_SUPPORTED_SCM_PROVIDERS:
supported = ", ".join(sorted(SEER_SUPPORTED_SCM_PROVIDERS))
raise serializers.ValidationError(
f'"{value}" is not a supported Seer provider. Supported providers: {supported}'
)
return value

def validate_branch_overrides(self, value):
if not value:
return value
Expand Down
24 changes: 24 additions & 0 deletions tests/sentry/autofix/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,30 @@ def test_get_repos_from_project_code_mappings_with_data(self) -> None:
]
assert repos == expected_repos

def test_filters_out_unsupported_providers(self) -> None:
project = self.create_project()
github_repo = self.create_repo(
name="getsentry/sentry",
provider="integrations:github",
external_id="123",
integration_id=234,
)
self.create_code_mapping(project=project, repo=github_repo)

gitlab_repo = self.create_repo(
name="getsentry/sentry-gitlab",
provider="integrations:gitlab",
external_id="456",
integration_id=345,
)
self.create_code_mapping(
project=project, repo=gitlab_repo, stack_root="gitlab/", source_root="src/gitlab/"
)

repos = get_autofix_repos_from_project_code_mappings(project)
assert len(repos) == 1
assert repos[0]["provider"] == "integrations:github"


class TestGetAutofixStateFromPrId(TestCase):
@patch("sentry.seer.autofix.utils.make_signed_seer_api_request")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1052,3 +1052,28 @@ def test_post_append_resolves_repo_id_for_existing_repos(
assert len(seer_repos) == 2
assert seer_repos[0].repository_id == existing_repo.id
assert seer_repos[1].repository_id == new_repo.id

@patch(
"sentry.seer.endpoints.organization_autofix_automation_settings.bulk_set_project_preferences"
)
def test_post_rejects_unsupported_repo_provider(self, mock_bulk_set_preferences):
project = self.create_project(organization=self.organization)

repo_data = {
"provider": "gitlab",
"owner": "test-org",
"name": "test-repo",
"externalId": "12345",
}

response = self.client.post(
self.url,
{
"projectIds": [project.id],
"projectRepoMappings": {
str(project.id): [repo_data],
},
},
)
assert response.status_code == 400
mock_bulk_set_preferences.assert_not_called()
20 changes: 20 additions & 0 deletions tests/sentry/seer/endpoints/test_project_seer_preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,26 @@ def test_post_rejects_mismatched_repo_name_or_owner(self, mock_request: MagicMoc
assert response.data["detail"] == "Invalid repository"
mock_request.assert_not_called()

@patch("sentry.seer.endpoints.project_seer_preferences.make_set_project_preference_request")
def test_post_rejects_unsupported_repo_provider(self, mock_request: MagicMock) -> None:
request_data = {
"repositories": [
{
"organization_id": self.org.id,
"integration_id": "111",
"provider": "gitlab",
"owner": "getsentry",
"name": "sentry",
"external_id": "123456",
}
],
}

response = self.client.post(self.url, data=request_data)

assert response.status_code == 400
mock_request.assert_not_called()

@patch("sentry.seer.endpoints.project_seer_preferences.make_set_project_preference_request")
def test_post_creates_seer_project_repository(self, mock_request: MagicMock) -> None:
"""Test that POST writes to SeerProjectRepository when feature flag is enabled."""
Expand Down
Loading