Skip to content

Conversation

NicoHinderling
Copy link
Contributor

@NicoHinderling NicoHinderling commented May 29, 2025

Upload endpoint described in the emerge size integration proposal

Most of the logic is pretty similar to the debug file and sourcemap upload endpoints

in addition to the unit tests, I've manually tested uploading works via my test sentry-cli branch

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label May 29, 2025
Copy link

codecov bot commented May 29, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #92528      +/-   ##
==========================================
+ Coverage   87.90%   87.91%   +0.01%     
==========================================
  Files       10251    10255       +4     
  Lines      587928   588565     +637     
  Branches    22830    22830              
==========================================
+ Hits       516792   517422     +630     
- Misses      70690    70697       +7     
  Partials      446      446              

"type": "array",
"items": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
},
# Optional metadata
Copy link
Member

Choose a reason for hiding this comment

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

Is this where we might need Git sha or other git info?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, after writing this doc, I think it's most likely that we'd just include the git info in the request body

@NicoHinderling NicoHinderling changed the title [wip] new preprod artifact upload endpoint feat(preprod): Add preprod artifact upload endpoint May 30, 2025
@NicoHinderling NicoHinderling marked this pull request as ready for review May 30, 2025 20:02
@NicoHinderling NicoHinderling requested review from a team as code owners May 30, 2025 20:02
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.

did we end up creating a 'prepod' app folder? is there any reason why the endpoint and task can't live there instead of the catchall folders?

@NicoHinderling
Copy link
Contributor Author

did we end up creating a 'prepod' app folder? is there any reason why the endpoint and task can't live there instead of the catchall folders?

good catch, I can move the endpoint into it. The task file already existed though (just adding a method into it), so I'll plan to leave it as is assuming that's kosher 🙏

@JoshFerge
Copy link
Member

did we end up creating a 'prepod' app folder? is there any reason why the endpoint and task can't live there instead of the catchall folders?

good catch, I can move the endpoint into it. The task file already existed though (just adding a method into it), so I'll plan to leave it as is assuming that's kosher 🙏

ah yup that makes sense. thanks! also feel free to define your own urls file and import them into the main one like here:

from django.urls import re_path


@region_silo_endpoint
class ProjectPreprodArtifactAssembleEndpoint(ProjectEndpoint):
owner = ApiOwner.OWNERS_INGEST
Copy link
Member

Choose a reason for hiding this comment

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

This should probably be for our team.

"file_name": data.get("file_name"),
"sha": data.get("sha"),
"build_configuration": data.get("build_configuration"),
"extras": data.get("extras"),
Copy link
Member

Choose a reason for hiding this comment

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

extras shouldn't be part of the external API, these are more for our own internal use. We had a few use-cases in Emerge that were locked down to org42, but let's try to avoid that here if possible for as long as we can.

# 4. Update state to PROCESSED when done (also update the date_built value to reflect when the artifact was built, among other fields)

except Exception as e:
logger.exception("Failed to assemble preprod artifact")
Copy link
Member

Choose a reason for hiding this comment

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

Can you record the project/org?

"project_id": project.id,
"checksum": checksum,
"chunks": chunks,
"file_name": data.get("file_name"),
Copy link
Member

Choose a reason for hiding this comment

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

I think we removed filename in our API a while back, do you think the UUID is fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hah, it's still in our docs. yea I talked w hector about this and neither of us felt strongly. We can just auto-gen a file name and remove this param 👍

"checksum": checksum,
"chunks": chunks,
"file_name": data.get("file_name"),
"sha": data.get("sha"),
Copy link
Member

Choose a reason for hiding this comment

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

nit: since this assemble api is doing some checksum stuff, maybe this should be git_sha?

Comment on lines 86 to 100
if state == ChunkFileState.OK:
return Response({"state": state, "detail": detail, "missingChunks": []})
elif state is not None:
return Response({"state": state, "detail": detail, "missingChunks": []})
Copy link
Contributor

Choose a reason for hiding this comment

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

The if and elif branches are the same, so this should be equivalent to

Suggested change
if state == ChunkFileState.OK:
return Response({"state": state, "detail": detail, "missingChunks": []})
elif state is not None:
return Response({"state": state, "detail": detail, "missingChunks": []})
if state is not None:
return Response({"state": state, "detail": detail, "missingChunks": []})

Copy link
Member

@cmanallen cmanallen left a comment

Choose a reason for hiding this comment

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

Not commenting on the Emerge specific code. I'll let your team decide what Emerge-specific code should do and if its properly covered. Unfortunately I'm not on any of the teams which are required reviewers. @wedamija was interested in reviewing some of the Emerge code and probably will get you past the review block.

General comments. You don't have to change anything. There are choices you can make. I know the endpoint file is taking inspiration from related files so the tests we have here reflect the choices made by others. But consider the lack of unit test coverage for this pull request. We require a database and Django to test your schema definition, for example. It might simplify your test setup to pull that out into a function. You can test it 100 different ways in a millisecond. I would say as much as possible make this endpoint unit testable. This is a core part of your workflows so having absolute certainty on how things behave would be important for me. Though you're welcome to make a choice that suits your needs.

Comment on lines 748 to 754
# where next set of changes will happen
# TODO: Trigger artifact processing (size analysis, etc.)
# This is where you'd add logic to:
# 1. create_or_update a new row in the Commit table as well (once base_sha is added as a column to it)
# 2. Detect artifact type (iOS/Android/etc.)
# 3. Queue processing tasks
# 4. Update state to PROCESSED when done (also update the date_built value to reflect when the artifact was built, among other fields)
Copy link
Member

Choose a reason for hiding this comment

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

This should probably be filled in before merging. Is this task useful on its own without the TODOs?

# 3. Queue processing tasks
# 4. Update state to PROCESSED when done (also update the date_built value to reflect when the artifact was built, among other fields)

except Exception as e:
Copy link
Member

Choose a reason for hiding this comment

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

If possible this should be more specific. But logging out to Sentry (as you did below) makes this less of a concern than the previous comment on this.

# Handle build configuration
build_config = None
if build_configuration:
build_config, _ = PreprodBuildConfiguration.objects.get_or_create(
Copy link
Member

Choose a reason for hiding this comment

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

One other thing, this and PreprodArtifact should likely be created together as part of a transaction.

Comment on lines +24 to +33
class ValidatePreprodArtifactSchemaTest(TestCase):
"""Unit tests for schema validation function - no database required."""

def test_valid_minimal_schema(self):
"""Test valid minimal schema passes validation."""
data = {"checksum": "a" * 40, "chunks": []}
body = orjson.dumps(data)
result, error = validate_preprod_artifact_schema(body)
assert error is None
assert result == data
Copy link
Member

Choose a reason for hiding this comment

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

For unit tests like these you don't need the class structure. You can just define a test:

def test_something():
    ...

The test_ prefix (in the tests directory) is a signal to pytest that it should execute that function. There's all sorts of other neat things you can do like bring in fixtures or parameterize your tests. For an example take a look at this test by Tony: https://github.com/getsentry/sentry/pull/92599/files#diff-76fbf98d7d80cafdea351cdb466743d2fa5b20afdb3951d4154406e111dc0805R1088-R1107

@cmanallen
Copy link
Member

@getsentry/issue-workflow Ping.

@NicoHinderling
Copy link
Contributor Author

@getsentry/issue-workflow Ping.

synced w malachi offline 👍

@NicoHinderling NicoHinderling merged commit 055b33d into master Jun 4, 2025
61 checks passed
@NicoHinderling NicoHinderling deleted the new-preprod-artifact-endpoint branch June 4, 2025 00:10
Copy link

sentry-io bot commented Jun 4, 2025

Suspect Issues

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

  • ‼️ Exception: Simulated failure unittest.mock in _execute_mock_call View Issue

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

andrewshie-sentry pushed a commit that referenced this pull request Jun 4, 2025
Upload endpoint described in the [emerge size integration
proposal](https://www.notion.so/sentry/Emerge-Size-Integration-Technical-Proposal-1ec8b10e4b5d801d9bc4cf8c7cc5ad1b?d=1fa8b10e4b5d80df9ed5001c55e19b89#1fa8b10e4b5d80dba610cb7273434b0d)

Most of the logic is pretty similar to the debug file and sourcemap
upload endpoints

in addition to the unit tests, I've manually tested uploading works via
my [test sentry-cli
branch](getsentry/sentry-cli#2533)
rbro112 added a commit to getsentry/sentry-cli that referenced this pull request Jun 10, 2025
Adds the upload functionality to the new `mobile-app upload` command. 

Tested E2E with new API preprod/assemble endpoint added in
getsentry/sentry#92528. Also added some basic
tests to ensure a minimal APK is successfully uploaded and that it skips
uploading if the server already has the chunks.
NicoHinderling added a commit that referenced this pull request Jun 18, 2025
…eprod endpoints (#93825)

#92528 (comment)

as suggested by @JoshFerge a few weeks back. We're going to add a few
more endpoints so it makes sense to have them all in the same self
contained file
andrewshie-sentry pushed a commit that referenced this pull request Jun 19, 2025
…eprod endpoints (#93825)

#92528 (comment)

as suggested by @JoshFerge a few weeks back. We're going to add a few
more endpoints so it makes sense to have them all in the same self
contained file
@github-actions github-actions bot locked and limited conversation to collaborators Jun 20, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Backend Automatically applied to PRs that change backend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants