Skip to content

feat(snapshots): Restructure sidecar JSON to match ingestion schema#1162

Open
runningcode wants to merge 2 commits intomainfrom
no/snapshot-sidecar-schema
Open

feat(snapshots): Restructure sidecar JSON to match ingestion schema#1162
runningcode wants to merge 2 commits intomainfrom
no/snapshot-sidecar-schema

Conversation

@runningcode
Copy link
Copy Markdown
Contributor

@runningcode runningcode commented Apr 23, 2026

Summary

Aligns the per-snapshot sidecar JSON with the ingestion JSON Schema by organizing fields into the defined buckets:

  • Top level: display_name, group, diff_threshold, color_mode
  • tags (appearance / render inputs): preview_name, locale, device, font_scale, api_level, width_dp, height_dp, show_system_ui, show_background
  • context (preview identity / location): image_file_name, class_name, method_name

Notable behavior changes:

  • The old night_mode boolean is replaced by a color_mode enum. It is emitted only when the @Preview(uiMode = …) bits explicitly set UI_MODE_NIGHT_YES"dark" or UI_MODE_NIGHT_NO"light". The common UI_MODE_NIGHT_UNDEFINED case (which is the default for unannotated previews) now yields no color_mode key.
  • preview_name (the @Preview(name = …) label) moves from top level into tags.
  • tags is omitted when empty; context is always present.

Implementation notes:

  • The sidecar writer is emitted as a string literal inside the generated Paparazzi test (GenerateSnapshotTestsTask.kt), so the change lives in that template.
  • The hand-rolled JSON writer is replaced with a tiny recursive renderJson(value, indentLevel) that handles String, Number, Boolean, and Map<*,*> — no new dependencies.

Example output:

{
  "display_name": "FooPreview",
  "group": "main",
  "color_mode": "dark",
  "tags": { "preview_name": "Dark", "locale": "en", "font_scale": 1.5 },
  "context": {
    "image_file_name": "com.example.FooPreview",
    "class_name": "com.example.Foo",
    "method_name": "FooPreview"
  }
}

#skip-changelog

Bucket appearance inputs (locale, device, font_scale, api_level,
width_dp, height_dp, show_system_ui, show_background, preview_name)
under `tags`; move preview identity (class_name, method_name,
image_file_name) under `context`; replace the `night_mode` boolean
with a `color_mode` enum that is emitted only when `uiMode` explicitly
sets `UI_MODE_NIGHT_YES` or `UI_MODE_NIGHT_NO`.

The serializer is extended with a small recursive `renderJson`
helper so the template can emit nested objects without pulling in a
JSON library.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Fails
🚫 Please consider adding a changelog entry for the next release.
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

### Features

- Restructure sidecar JSON to match ingestion schema ([#1162](https://github.com/getsentry/sentry-android-gradle-plugin/pull/1162))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description or adding a skip-changelog label.

Generated by 🚫 dangerJS against e81b819

if (info.showBackground) metadata["show_background"] = true

when (info.uiMode and UI_MODE_NIGHT_MASK) {
UI_MODE_NIGHT_YES -> metadata["color_mode"] = "dark"
Copy link
Copy Markdown
Member

@rbro112 rbro112 Apr 23, 2026

Choose a reason for hiding this comment

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

Make sure to pass this through as uiMode in context

Relocate the uiMode → light/dark mapping from the top-level
metadata field `color_mode` into the `tags` map, keyed as
`ui_mode`. This aligns the field with the other appearance
inputs (locale, device, font_scale, etc.) and matches the
ingestion schema's expectation that preview configuration
travels as tags rather than first-class metadata.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@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.

Fix All in Cursor

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

Reviewed by Cursor Bugbot for commit 6acdeab. Configure here.

when (info.uiMode and UI_MODE_NIGHT_MASK) {
UI_MODE_NIGHT_YES -> tags["ui_mode"] = "dark"
UI_MODE_NIGHT_NO -> tags["ui_mode"] = "light"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Night mode field has wrong name and wrong placement

High Severity

The dark/light value is placed in tags under the key ui_mode, but the PR description and example JSON clearly define it as color_mode at the top level of the metadata (alongside display_name, group, diff_threshold). Additionally, the reviewer asks for the raw uiMode to be passed through in the context block, which is also not done. Both the field name and its location contradict the ingestion schema this PR is designed to match.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6acdeab. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants