Skip to content

feat(preprod): Add snapshot image comparison task and endpoint logic#109151

Merged
NicoHinderling merged 3 commits intomasterfrom
nh/add-endpoint-logic-to-trigger-task
Feb 27, 2026
Merged

feat(preprod): Add snapshot image comparison task and endpoint logic#109151
NicoHinderling merged 3 commits intomasterfrom
nh/add-endpoint-logic-to-trigger-task

Conversation

@NicoHinderling
Copy link
Contributor

Adds the ability to automatically compare snapshot images between two preprod builds using pixel-level diffing.

When a snapshot is uploaded with VCS info (base_sha, base_repo_name, base_ref), the endpoint now looks for a matching base artifact and triggers a compare_snapshots Celery task. This task:

  • Fetches manifests for both head and base artifacts
  • Matches images by file name across the two builds
  • Runs pixel-level comparison using odiff (via a new image_diff module)
  • Stores diff masks and a comparison manifest in object storage
  • Records results in a PreprodSnapshotComparison model

The GET endpoint is updated to return categorized image lists (changed, added, removed, unchanged) along with diff metadata when comparison data is available.

New modules:

  • sentry.preprod.snapshots.image_diff — wraps the odiff binary in server mode for efficient batch image comparison
  • sentry.preprod.snapshots.tasks — Celery task for async snapshot comparison
  • snapshot-diff internal endpoint registered in URL patterns

Also adds odiff-bin as a dependency for the image diffing binary.

@github-actions github-actions bot added Scope: Frontend Automatically applied to PRs that change frontend components Scope: Backend Automatically applied to PRs that change backend components labels Feb 23, 2026
@github-actions
Copy link
Contributor

🚨 Warning: This pull request contains Frontend and Backend changes!

It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently.

Have questions? Please ask in the #discuss-dev-infra channel.

@NicoHinderling NicoHinderling changed the base branch from master to graphite-base/109151 February 24, 2026 00:55
@NicoHinderling NicoHinderling force-pushed the nh/add-endpoint-logic-to-trigger-task branch from f04c5f3 to 2b4c3f4 Compare February 24, 2026 00:56
@NicoHinderling NicoHinderling changed the base branch from graphite-base/109151 to create-compare-task-v1 February 24, 2026 00:56
Copy link
Contributor Author

NicoHinderling commented Feb 24, 2026

@NicoHinderling NicoHinderling force-pushed the nh/add-endpoint-logic-to-trigger-task branch from 2b4c3f4 to e1d9787 Compare February 24, 2026 20:41
@NicoHinderling NicoHinderling force-pushed the nh/add-endpoint-logic-to-trigger-task branch from e1d9787 to 317a73a Compare February 24, 2026 21:08
@NicoHinderling NicoHinderling force-pushed the nh/add-endpoint-logic-to-trigger-task branch 2 times, most recently from 43cc0fc to 03eceb6 Compare February 24, 2026 21:20
@NicoHinderling NicoHinderling marked this pull request as ready for review February 24, 2026 21:21
@NicoHinderling NicoHinderling requested a review from a team as a code owner February 24, 2026 21:21
@NicoHinderling NicoHinderling force-pushed the nh/add-endpoint-logic-to-trigger-task branch from 1793aa1 to 2ea9010 Compare February 24, 2026 21:41
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

)
diff_mask_bytes = base64.b64decode(diff_result.diff_mask_png)
logger.info(
"compare_snapshots: uploading mask for %s (%d bytes, diff=%.4f, changed_px=%d)",
Copy link
Contributor

Choose a reason for hiding this comment

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

Errored items missing available dimension data in manifest

Medium Severity

For exceeds_pixel_limit errored items, the task has head_meta and base_meta with width/height readily available (lines 241-242) but doesn't store them in image_results. The "removed" items were fixed to include before_width/before_height per PR discussion, but errored items were missed. In the categorizer fallback path (when head_img or base_img is None), img.before_width, img.after_width, etc. are all None, causing dimensions to silently fall back to 0. This produces incorrect dimension metadata for errored diff pairs in the API response.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we don't need the right dimensions for error cases since they couldn't be processed and therefore can't be displayed

@NicoHinderling NicoHinderling merged commit 4af11ae into master Feb 27, 2026
77 checks passed
@NicoHinderling NicoHinderling deleted the nh/add-endpoint-logic-to-trigger-task branch February 27, 2026 20:01
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 Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants