Skip to content

fix(bugsnag): give the app and the uploaded mapping the same build UUID - #1374

Merged
bmc08gt merged 1 commit into
code/cashfrom
fix/bugsnag-build-uuid
Aug 30, 2026
Merged

fix(bugsnag): give the app and the uploaded mapping the same build UUID#1374
bmc08gt merged 1 commit into
code/cashfrom
fix/bugsnag-build-uuid

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Release crashes come through obfuscated. Bugsnag joins an uploaded ProGuard mapping to an incoming event on build UUID, falling back to applicationId + versionName + versionCode — and neither side of this build was supplying a build UUID, so matching rested entirely on the version numbers.

The app never reported one

com.bugsnag.gradle 1.2.0 emits the UUID as a string resource (GenerateResourcesTask), but bugsnag-android 6.27 reads com.bugsnag.android.BUILD_UUID only as manifest meta-data — ManifestConfigLoader lists it among the meta-data keys, and no class in the AAR looks up a string resource by that name (its R.txt has no bugsnag entry). The merged release manifest carried exactly one bugsnag meta-data entry, API_KEY.

Nothing references the resource, so it does not reach the APK either. From mapping/release/resources.txt:

string:com_bugsnag_android_BUILD_UUID:2131820793 is not reachable.

aapt2 dump resources on the release APK finds no bugsnag entry.

The upload omitted it too

registerProguardMappingTask sets the field conditionally:

buildUuidResolver.value?.let { task.buildUuid.set(it) }

BuildUuidResolver.value resolves to buildUuidGenerator or buildUuid from the bugsnag DSL, per variant then global. This project set none of them, so UploadMappingTask sent no build-uuid.

Change

Use the commit SHA on both sides:

  • buildUuid on the release variant in the bugsnag block, so the mapping upload is tagged;
  • a com.bugsnag.android.BUILD_UUID manifest meta-data entry backed by a manifestPlaceholders value, so the app reports the same string. Manifest meta-data is also out of the resource shrinker's reach, which the generated resource was not.

The release workflow builds the bundle and runs bugsnagUploadReleaseProguardMapping in one job on one checkout, so both Gradle invocations resolve the same HEAD.

Why it matters now

versionCode was the sole remaining join key, and the AGP 9 migration (c9edfc7) changed how it is produced: de.nanogiants.android-versioning was Gradle 9 incompatible, so versioning.getVersionCode() became git rev-list --count HEAD. Within a single CI job the two invocations agree, but a value derived from commit count is easy to desynchronise and fails silently when it does. An explicit build UUID removes the dependency.

Worth reporting the resource-versus-meta-data mismatch upstream as well: com.bugsnag.gradle 1.2.0 generates a resource that its own runtime never reads.

Bugsnag joins an uploaded ProGuard mapping to an incoming event on build UUID,
falling back to applicationId + versionName + versionCode. Neither side was
supplying one, so matching rested entirely on the version numbers.

The app never reported a build UUID. com.bugsnag.gradle 1.2.0 emits it as a
string resource, but bugsnag-android 6.27 reads com.bugsnag.android.BUILD_UUID
only as manifest meta-data (ManifestConfigLoader) — nothing in the AAR looks the
resource up. Being unreferenced, the resource is then dropped by resource
shrinking, per mapping/release/resources.txt:

    string:com_bugsnag_android_BUILD_UUID:2131820793 is not reachable.

The upload omitted it as well: registerProguardMappingTask sets build-uuid only
when the bugsnag DSL supplies buildUuid or buildUuidGenerator, and this project
supplied neither.

Use the commit SHA for both. The release workflow builds the bundle and runs
bugsnagUploadReleaseProguardMapping in the same job on the same checkout, so the
two Gradle invocations resolve the same HEAD. Carrying the app's copy as manifest
meta-data rather than a resource also keeps it out of the shrinker's reach.
@bmc08gt bmc08gt self-assigned this Aug 30, 2026
@github-actions github-actions Bot added the type: fix Bug fix label Aug 30, 2026
@bmc08gt
bmc08gt merged commit 78f911b into code/cash Aug 30, 2026
3 checks passed
bmc08gt added a commit that referenced this pull request Aug 31, 2026
…obuf-keep-rules

* origin/code/cash:
  perf(r8): keep exception names without keeping every exception (#1373)
  fix(bugsnag): give the app and the uploaded mapping the same build UUID (#1374)
  chore(r8): drop R8 options that no longer do anything (#1371)
@bmc08gt
bmc08gt deleted the fix/bugsnag-build-uuid branch August 31, 2026 13:59
bmc08gt added a commit that referenced this pull request Aug 31, 2026
The release deploy has failed since #1374 with `unknown flag --build-uuid`
from `bugsnagCreateReleaseBuild`. bugsnag-gradle-plugin 1.2.0 hands the
variant's `buildUuid` to two CLI calls: `upload android-proguard`, which
accepts `--build-uuid`, and `create-build`, which does not — the flag is
absent from the 3.10.2 the plugin embeds and from 3.10.5, the current
release. PR CI never caught it because only the deploy workflow runs the
Bugsnag tasks.

Set the UUID on the mapping upload task instead of through the `bugsnag`
block, so create-build goes back to its working default. The plugin only
writes that property when the DSL supplies a value, so it cannot overwrite
this one regardless of which configuration action runs first.

Verified against a stand-in CLI that records its arguments: create-build
now passes no `--build-uuid` and keeps the rest of its flags, the mapping
upload passes `--build-uuid=<HEAD>`, and the merged release manifest
carries the same SHA in `com.bugsnag.android.BUILD_UUID`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant