Skip to content
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

ref(auto_source_config): Move logic around #88251

Merged
merged 5 commits into from
Mar 31, 2025

Conversation

armenzg
Copy link
Member

@armenzg armenzg commented Mar 28, 2025

Changes included:

  • Move some of the endpoint logic to the centralized location
  • Create repository and platform modules

Changes included:

* Move derived code mappings endpoint logic to centralized place
* Create repository and platform modules
@armenzg armenzg self-assigned this Mar 28, 2025
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Mar 28, 2025
pyproject.toml Outdated
@@ -458,7 +458,6 @@ module = [
"sentry_plugins.base",
"social_auth.migrations.*",
"sudo.*",
"tests.sentry.api.endpoints.issues.test_organization_derive_code_mappings",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm moving the test under tests.sentry.issues.auto_source_config, where all other related tests are located.

@@ -425,32 +425,29 @@ def convert_stacktrace_frame_path_to_source_path(

def create_code_mapping(
organization: Organization,
code_mapping: CodeMapping,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CodeMapping type contains all four variables I'm replacing it with.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger = logging.getLogger(__name__)


def process_get_request(request: Request, organization: Organization) -> Response:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roughly equivalent to the original method:

try:
possible_code_mappings = []
resp_status: Literal[200, 204, 400] = status.HTTP_400_BAD_REQUEST
if stacktrace_filename:
possible_code_mappings = derive_code_mappings(
organization, {"filename": stacktrace_filename}, platform
)
if possible_code_mappings:
resp_status = status.HTTP_200_OK
else:
resp_status = status.HTTP_204_NO_CONTENT
return Response(serialize(possible_code_mappings), status=resp_status)
except InstallationCannotGetTreesError:
return self.respond(
{"text": "The integration does not support getting trees"},
status=status.HTTP_404_NOT_FOUND,
)
except InstallationNotFoundError:
return self.respond(
{"text": "Could not find this integration installed on your organization"},
status=status.HTTP_404_NOT_FOUND,
)

frame = {
"absPath": request.GET.get("absPath"),
# Currently, the only required parameter
"filename": request.GET.get("stacktraceFilename"),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frontend currently only sends filename, however, we're going to need the other two values as well.

)
except NeedsExtension:
return Response({"text": "Needs extension"}, status=status.HTTP_400_BAD_REQUEST)
except KeyError:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is new. It can be raised when get_frame_info_from_request gets called.

return FrameInfo(frame, request.GET.get("platform"))


def process_post_request(request: Request, organization: Organization) -> Response:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roughly equivalent to the original method:

try:
project = Project.objects.get(id=request.data.get("projectId"))
except Project.DoesNotExist:
return self.respond(
{"text": "Could not find project"}, status=status.HTTP_404_NOT_FOUND
)
if not request.access.has_project_access(project):
return self.respond(status=status.HTTP_403_FORBIDDEN)
repo_name = request.data.get("repoName")
stack_root = request.data.get("stackRoot")
source_root = request.data.get("sourceRoot")
branch = request.data.get("defaultBranch")
if not repo_name or not stack_root or not source_root or not branch:
return self.respond(
{"text": "Missing required parameters"}, status=status.HTTP_400_BAD_REQUEST
)
try:
new_code_mapping = create_code_mapping(
organization, project, stack_root, source_root, repo_name, branch
)
except InstallationNotFoundError:
return self.respond(
{"text": "Could not find this integration installed on your organization"},
status=status.HTTP_404_NOT_FOUND,
)
except InstallationCannotGetTreesError:
return self.respond(
{"text": "The integration does not support getting trees"},
status=status.HTTP_404_NOT_FOUND,
)
return self.respond(
serialize(new_code_mapping, request.user), status=status.HTTP_201_CREATED
)

raise InstallationNotFoundError

code_mapping = get_code_mapping_from_request(request)
new_code_mapping = create_code_mapping(organization, code_mapping, project)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing now code_mapping instead of the four parameters.
image

``````````````````

:param organization:
:param string absPath:
:param string module:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need these values for Java calls.

@armenzg armenzg marked this pull request as ready for review March 28, 2025 19:38
@armenzg armenzg requested review from a team as code owners March 28, 2025 19:38
Copy link
Member

@JoshFerge JoshFerge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keeping all of the logic outside of the actual endpoint file is a pattern that i'd prefer not to do -- it's not something that we really do elsewhere in the codebase.

it makes sense to have:

  • serialization
  • pagination
  • authorization
  • query building, etc.

inside the endpoint. domain specific business logic can live in a helper folder, but passing the entire request to a helper function is unnecessary indirection and can introduce confusion

@armenzg armenzg marked this pull request as draft March 28, 2025 19:50
Copy link

codecov bot commented Mar 28, 2025

Codecov Report

Attention: Patch coverage is 89.04110% with 8 lines in your changes missing coverage. Please review.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ues/endpoints/organization_derive_code_mappings.py 71.42% 6 Missing ⚠️
...try/issues/auto_source_code_config/code_mapping.py 66.66% 1 Missing ⚠️
...urce_code_config/derived_code_mappings_endpoint.py 95.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #88251       +/-   ##
===========================================
+ Coverage   46.48%   87.71%   +41.22%     
===========================================
  Files        9973     9992       +19     
  Lines      564383   565254      +871     
  Branches    22289    22289               
===========================================
+ Hits       262349   495806   +233457     
+ Misses     301599    69013   -232586     
  Partials      435      435               

@armenzg armenzg requested review from JoshFerge and removed request for a team March 28, 2025 20:13
@armenzg
Copy link
Member Author

armenzg commented Mar 28, 2025

keeping all of the logic outside of the actual endpoint file is a pattern that i'd prefer not to do -- it's not something that we really do elsewhere in the codebase.

it makes sense to have:

  • serialization
  • pagination
  • authorization
  • query building, etc.

inside the endpoint. domain specific business logic can live in a helper folder, but passing the entire request to a helper function is unnecessary indirection and can introduce confusion

I have partially gone back. Let me know if you want more changes than that.

"source_root": code_mapping.source_path,
"default_branch": code_mapping.repo.branch,
# This function is called from the UI, thus, we know that the code mapping is user generated
"automatically_generated": False,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change rather than just a refactor because we have a bunch of user generated code mappings marked as automatically generated (which is not true).

@@ -156,7 +156,7 @@ def test_post_simple(self) -> None:
repo = Repository.objects.get(name="getsentry/codemap")
assert response.status_code == 201, response.content
assert response.data == {
"automaticallyGenerated": True,
"automaticallyGenerated": False,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the behaviour change I mentioned earlier.

repo_name = request.data.get("repoName")
stack_root = request.data.get("stackRoot")
source_root = request.data.get("sourceRoot")
branch = request.data.get("defaultBranch")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All four values are now returned as an object in the call below: code_mapping = get_code_mapping_from_request(request)

@armenzg armenzg marked this pull request as ready for review March 31, 2025 12:38
@armenzg armenzg merged commit 5a6ef35 into master Mar 31, 2025
49 checks passed
@armenzg armenzg deleted the ref/endpoint/auto_source/armenzg branch March 31, 2025 15:27
Copy link

sentry-io bot commented Mar 31, 2025

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ UnsupportedFrameInfo: This path is not supported. /api/0/organizations/{organization_id_or_slug}/... View Issue
  • ‼️ MissingModuleOrAbsPath: Investigate why the data is missing. /api/0/organizations/{organization_id_or_slug}/... View Issue

Did you find this useful? React with a 👍 or 👎

andrewshie-sentry pushed a commit that referenced this pull request Mar 31, 2025
Changes included:

* Move some of the endpoint logic to the centralized location
* Create repository and platform modules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scope: Backend Automatically applied to PRs that change backend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants