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
24 changes: 11 additions & 13 deletions src/sentry/seer/endpoints/seer_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
from sentry.hybridcloud.rpc.service import RpcAuthenticationSetupException, RpcResolutionException
from sentry.hybridcloud.rpc.sig import SerializableFunctionValueException
from sentry.integrations.github_enterprise.integration import GitHubEnterpriseIntegration
from sentry.integrations.models.repository_project_path_config import RepositoryProjectPathConfig
from sentry.integrations.services.integration import integration_service
from sentry.integrations.types import IntegrationProviderSlug
from sentry.models.organization import Organization, OrganizationStatus
Expand Down Expand Up @@ -115,6 +114,7 @@
rpc_get_trace_waterfall,
)
from sentry.seer.fetch_issues import by_error_type, by_function_name, by_text_query, utils
from sentry.seer.fetch_issues.utils import NoProjectsForRepoError, get_repo_and_projects
from sentry.seer.issue_detection import create_issue_occurrence
from sentry.seer.models.seer_api_models import SeerProjectPreference
from sentry.seer.utils import filter_repo_by_provider
Expand Down Expand Up @@ -655,7 +655,7 @@ def trigger_coding_agent_launch(

def has_repo_code_mappings(
*, organization_id: int, provider: SeerSCMProvider, external_id: str, owner: str, name: str
) -> dict[str, bool]:
) -> dict[str, bool | dict[str, int]]:
"""
Validate that a repository exists and belongs to the given organization.

Expand All @@ -667,19 +667,17 @@ def has_repo_code_mappings(
name: The repository name (e.g., "sentry")

Returns:
dict: {"has_code_mappings": bool}
dict: {"has_code_mappings": bool, "project_slug_to_id": dict[str, int]}
"""
repo = filter_repo_by_provider(organization_id, provider, external_id, owner, name).first()

if not repo:
return {"has_code_mappings": False}

has_mappings = RepositoryProjectPathConfig.objects.filter(
organization_id=organization_id,
repository_id=repo.id,
).exists()
try:
repo_projects = get_repo_and_projects(organization_id, provider, external_id, owner, name)
except (Repository.DoesNotExist, NoProjectsForRepoError):
return {"has_code_mappings": False, "project_slug_to_id": {}}
Comment thread
kddubey marked this conversation as resolved.

return {"has_code_mappings": has_mappings}
project_slug_to_id = dict(
sorted((project.slug, project.id) for project in repo_projects.projects)
)
return {"has_code_mappings": True, "project_slug_to_id": project_slug_to_id}


def validate_repo(
Expand Down
22 changes: 19 additions & 3 deletions src/sentry/seer/fetch_issues/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
MAX_NUM_DAYS_AGO_DEFAULT = 90


class NoProjectsForRepoError(Exception):
"""Raised when a repo exists but has no Sentry projects via code mappings."""


class SeerResponseError(TypedDict):
error: str

Expand Down Expand Up @@ -91,15 +95,27 @@ def get_repo_and_projects(
repository_id=repo.id,
)
)
projects = [config.project for config in repo_configs]

projects = []
valid_configs = []
for config in repo_configs:
try:
project = config.project
except Project.DoesNotExist:
continue
else:
valid_configs.append(config)
projects.append(project)

if not projects:
raise ValueError("No Sentry projects found for repo")
raise NoProjectsForRepoError("No Sentry projects found for repo")
Comment thread
cursor[bot] marked this conversation as resolved.

return RepoProjects(
organization_id=organization_id,
provider=provider,
external_id=external_id,
repo=repo,
repo_configs=repo_configs,
repo_configs=valid_configs,
projects=projects,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,4 @@ def test_has_repo_code_mappings(self) -> None:
)

assert response.status_code == 200
assert response.data == {"has_code_mappings": False}
assert response.data == {"has_code_mappings": False, "project_slug_to_id": {}}
9 changes: 6 additions & 3 deletions tests/sentry/seer/endpoints/test_seer_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ def test_has_repo_code_mappings_repo_not_found(self) -> None:
owner="nonexistent",
name="nonexistent",
)
assert result == {"has_code_mappings": False}
assert result == {"has_code_mappings": False, "project_slug_to_id": {}}

def test_has_repo_code_mappings_no_mappings(self) -> None:
"""Test when repository exists but has no code mappings"""
Expand All @@ -1023,7 +1023,7 @@ def test_has_repo_code_mappings_no_mappings(self) -> None:
owner="test",
name="repo",
)
assert result == {"has_code_mappings": False}
assert result == {"has_code_mappings": False, "project_slug_to_id": {}}

def test_has_repo_code_mappings_with_mappings(self) -> None:
"""Test when repository exists and has code mappings"""
Expand Down Expand Up @@ -1059,7 +1059,10 @@ def test_has_repo_code_mappings_with_mappings(self) -> None:
owner="test",
name="repo",
)
assert result == {"has_code_mappings": True}
assert result == {
"has_code_mappings": True,
"project_slug_to_id": {project.slug: project.id},
}

def test_validate_repo_valid(self) -> None:
"""Test when repository exists and matches all fields"""
Expand Down
3 changes: 2 additions & 1 deletion tests/sentry/seer/fetch_issues/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pytest

from sentry.seer.fetch_issues.utils import (
NoProjectsForRepoError,
RepoProjects,
as_issue_details,
bulk_serialize_for_seer,
Expand Down Expand Up @@ -75,7 +76,7 @@ def test_get_repo_and_projects_no_configs(self) -> None:
external_id="123",
)

with pytest.raises(ValueError, match="No Sentry projects found for repo"):
with pytest.raises(NoProjectsForRepoError, match="No Sentry projects found for repo"):
get_repo_and_projects(
organization_id=self.organization.id,
provider="integrations:github",
Expand Down
Loading