fix(preprod): Parse dotted Apple build numbers instead of dropping them#645
Merged
Merged
Conversation
app_info.build (CFBundleVersion) is only guaranteed to be a plain integer for Android's versionCode. Apple allows up to three dot-separated non-negative integers (e.g. "1.2.3"), which the previous isdigit() check silently turned into None. That broke Sentry's build_number tiebreaker for sorting/finding the latest build within a version, and also made those artifacts non-installable on the Sentry side. Pack multi-component builds into a single sortable int by zero-padding each component to a fixed width, while leaving the existing plain-integer path unchanged. Also send the raw, unparsed build string alongside it as build_number_raw so Sentry can store/display the exact value later without another launchpad deploy; Sentry currently ignores unrecognized fields, so this is safe to ship ahead of that work. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
📲 Install BuildsiOS
Android
|
Covers _parse_build_number directly (plain ints unchanged, dotted Apple CFBundleVersion values packed and correctly ordered, malformed input still falls back to None) and _prepare_update_data's wiring of build_number/build_number_raw into the update payload. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
trevor-e
commented
Jul 8, 2026
| unchanged. Apple's CFBundleVersion also allows up to three dot-separated | ||
| non-negative integers (e.g. "1.2.3"); those are packed into a single int by | ||
| zero-padding each component to `component_width` digits, which preserves | ||
| correct ordering as long as no component reaches 10**component_width. |
Member
Author
There was a problem hiding this comment.
This field is stored as a BoundedBigInt in Sentry so it should be safe to pad like this.
component_width was a function parameter but nothing ever called _parse_build_number with a non-default value — it's an implementation detail of the packing scheme, not something callers should tune. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
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.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a08c7e0. Configure here.
A reviewer correctly flagged that plain-integer build numbers stay small while packed dotted values are much larger, so mixing both conventions within the same app_id/build_version isn't reliably ordered by this int alone. This can't be fixed here: a single artifact update has no visibility into sibling artifacts' formats, and unifying the magnitude would break backward compatibility with every already-stored plain-integer build_number. The authoritative fix belongs in Sentry's tiebreak query, comparing the raw build string once build_number_raw is available there, with this int remaining a fast common-case sort key. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2 tasks
mtopo27
approved these changes
Jul 8, 2026
trevor-e
added a commit
to getsentry/sentry
that referenced
this pull request
Jul 8, 2026
## Summary - Launchpad will start packing multi-component Apple `CFBundleVersion` values (e.g. `1.2.3`) into a large synthesized int for `build_number` (getsentry/launchpad#645), which would otherwise show up as an odd, unreadable number anywhere a build number is displayed. - Adds `build_number_raw` — the original unparsed build string — so those surfaces can show the real value instead. Stored in `PreprodArtifactMobileAppInfo.extras` (no migration needed) and exposed via `BuildDetailsAppInfo`. - Safe to deploy ahead of the launchpad change: it's a no-op until launchpad starts sending the field. - Frontend changes to consume this are a separate follow-up PR. ## Test plan - [x] New unit tests covering storage, the API response, and display formatting - [x] `prek` passing --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
app_info.build(CFBundleVersion) is only guaranteed to be a plain integer for Android'sversionCode. Apple allows up to three dot-separated non-negative integers (e.g."1.2.3"), which the previousisdigit()check silently turned intoNone.build_numbertiebreaker used to sort/find the latest build within a version, and also made those artifacts non-installable on the Sentry side (worked around there separately).build_number_rawso Sentry can store/display the exact value later without another launchpad deploy. Sentry currently ignores unrecognized fields, so this is safe to ship ahead of that follow-up work._parse_build_number(plain ints unchanged, dotted values packed and correctly ordered, malformed input falls back toNone) and for_prepare_update_data's wiring ofbuild_number/build_number_raw.Known limitation (flagged in review): plain-integer build numbers stay small while packed dotted values are much larger, so if the same
app_id/build_versionever has builds in both conventions,build_numberalone doesn't reliably order them. This can't be resolved in launchpad — a single artifact update has no visibility into sibling artifacts' formats, and unifying the magnitude would break backward compatibility with every already-stored plain-integerbuild_number. The authoritative fix belongs in Sentry's tiebreak query oncebuild_number_rawis available there (comparing the raw string directly for mixed-format cases), which is being scoped as a follow-up. Documented inline on_parse_build_number.Test plan
make test-unit(3 pre-existing, unrelated failures in Android APK signing/Swift symbol tests — confirmed present without this change)make check