Skip to content

fix: normalize build numbers - #8568

Open
chenj-hub wants to merge 1 commit into
getsentry:mainfrom
chenj-hub:jackies/2026-07-24-fix-sentry-distribution-updater-normalize-build-number
Open

fix: normalize build numbers#8568
chenj-hub wants to merge 1 commit into
getsentry:mainfrom
chenj-hub:jackies/2026-07-24-fix-sentry-distribution-updater-normalize-build-number

Conversation

@chenj-hub

Copy link
Copy Markdown

📜 Description

Added a normalizeBuildNumber() method that converts dotted version strings into Sentry's base-1,000,000 format:

  • Each component occupies a 6-digit slot (values 0-999,999)
  • Supports 2-3 component versions (e.g., "1.2" or "1.2.3")
  • Pads to 3 components with zeros if needed
  • Falls back to the original string for invalid formats (non-numeric, out of range, wrong component count)

Examples:

  • "1.2" → "1002000000000"
  • "1.2.3" → "1002003000000"
  • "999999.999999.999999" → "999999999999999999"
  • "1.2.beta" → "1.2.beta" (unchanged, invalid format)

💡 Motivation and Context

The SentryDistribution.Updater was sending raw build numbers (e.g., "1.2.3") to Sentry's distribution API, but Sentry stores build numbers in a normalized base-1,000,000 format. This mismatch caused update checks to fail or return incorrect results

when comparing build numbers.

For example:

  • Client sends: "1.2.3"
  • Sentry expects: "1002003000000"

Without normalization, the server can't properly compare versions to determine if an update is available.

💚 How did you test it?

  • Manual verification: build numbers are correctly normalized before being sent in API requests

Comment on lines +120 to +124
guard (2...3).contains(components.count),
components.allSatisfy({ component in
!component.isEmpty && component.allSatisfy(\.isNumber)
}) else {
return buildNumber

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The normalizeBuildNumber function fails to normalize single-component build numbers (e.g., "42"), returning the raw string instead of the expected format required by the API.
Severity: HIGH

Suggested Fix

Modify the guard condition in normalizeBuildNumber to accept single-component version strings by changing the check to (1...3).contains(components.count). Then, adjust the logic to correctly pad and convert single-component numbers into the required base-1,000,000 format, ensuring they are handled consistently with multi-component versions.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: Sources/SentryDistribution/Updater.swift#L120-L124

Potential issue: The function `normalizeBuildNumber` is designed to convert version
strings into a normalized base-1,000,000 format for the Sentry API. However, a guard
condition `(2...3).contains(components.count)` causes it to reject and bypass
normalization for single-component build numbers, such as "42". This is a valid and
common format for `CFBundleVersion` in iOS apps. As a result, these build numbers are
sent to the API unnormalized, which prevents the server from correctly comparing
versions and defeats the purpose of the change for apps using simple integer build
numbers.

Did we get this right? 👍 / 👎 to inform future reviews.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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.

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 29cfb3d. Configure here.

}

return String(normalizedBuildNumber)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing tests for build normalization

Medium Severity

normalizeBuildNumber adds non-trivial packing and fallback logic, but no unit or request-level tests cover it. That violates the REVIEWS.md rule that new or changed code must have corresponding tests, and leaves the dotted-version conversion unverified in CI.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 29cfb3d. Configure here.

@NinjaLikesCheez

Copy link
Copy Markdown
Member

Thank you for your contribution! I'll approve the CI to run, but please do take a look at the bot's comments as well :)

@NinjaLikesCheez NinjaLikesCheez added the run-full-ci Allows gated GitHub Action workflows to run for a labelled pull request label Jul 27, 2026
@trevor-e

Copy link
Copy Markdown
Member

Hi @chenj-hub, thanks for the contribution. Could you share a failing request and response, and describe what you mean by “incorrect results”?

The API accepts raw build numbers such as 1.2.3 and normalizes them server-side before looking up the current artifact. SDKs should send the original CFBundleVersion, not the packed sortable value, so clients should not be normalizing this themselves. This support was added in getsentry/sentry@cbefac8.

If you’re seeing a problem with the current API, these details will help us diagnose it. Thanks!

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

Labels

run-full-ci Allows gated GitHub Action workflows to run for a labelled pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants