getsentry / sentry-android-gradle-plugin

Gradle plugin for Sentry Android. Upload proguard, debug files, and more.
https://docs.sentry.io/platforms/android/gradle/
MIT License
143 stars 33 forks source link

Lazy variant details aren't supported for ProGuard mappings upload #776

Open bddckr opened 1 month ago

bddckr commented 1 month ago

Gradle Version

8.10.2

AGP Version

8.7.0

Code Minifier/Optimizer

R8

Version

4.11.0

Sentry SDK Version

7.15.0

Steps to Reproduce

  1. Configure your app's version code and name via the property-based APIs AGP offers for that these days.
    1. A recipe doing so in one way (manifest transformation) can be seen here.
    2. Setting the variant outputs' properties can also be used. See a usage example from Slack here.
  2. Use this plugin to upload ProGuard mapping files for your release build.
  3. Check out the uploaded mappings at https://example.sentry.io/settings/projects/myproject/proguard/.
  4. Notice that all of them are linked to the non-existing release com.example.myproject@undefined.
    1. This means it's quite difficult to find the mappings used in a release.
      1. Why do I care? Because I log (to Sentry) a bunch of things that aren't exceptions, Sentry's automatic deobfuscation doesn't apply. To deobfuscate logged details manually, I need the correct mappings file of the release that raised an issue. While it's rare for me to apply this manual process, it's still crucial to allow understanding all Sentry errors. Downloading the mappings file from Sentry allows there to be a single source of truth when it comes to all things related to a release.
    2. Note: This is not breaking Sentry's automatic deobfuscation of stack traces. That still works fine thanks to the UUID-based lookup.
    3. As seen here, that seems to be expected at this time since the plugin doesn't support all the various ways the version details can be set in newer AGP versions.### Expected Result

The lazily configured version details should be used when uploading ProGuard mappings.

Actual Result

The statically set version values are used when uploading ProGuard mappings.

bddckr commented 1 month ago

This might be a problem for more areas than the ProGuard mappings handling. I haven't checked whether variant information is utilized elsewhere in this plugin.

bddckr commented 1 month ago

Here's a workaround to this issue that I'm successfully applying in a convention plugin. It supports the Gradle configuration cache. Note that it relies on a bunch of assumptions that work for me, but not for everyone. It's probably not easy to decide which of the potentially many outputs from a variant to pick for this. Using the first output works for my case, but it might not work for everyone else.

extensions.configure<ApplicationAndroidComponentsExtension> {
    onVariants(selector().withName("release")) { variant ->
        val variantNameTitleCased =
            variant.name.replaceFirstChar(Char::titlecaseChar)
        val applicationId = variant.applicationId
        val versionName = variant.outputs[0].versionName

        tasks.named<SentryUploadProguardMappingsTask>(
            "uploadSentryProguardMappings$variantNameTitleCased"
        ) {
            releaseInfo.set(
                rootProject.tasks
                    .named("taskThatGeneratesTheVersionProperties")
                    .flatMap { task -> task.outputs.files.elements }
                    .map {
                        ReleaseInfo(
                            applicationId = applicationId.get(),
                            versionName = versionName.get(),
                            // I bake the version code into the name instead.
                            versionCode = null,
                        )
                    }
            )
        }
    }
}

I worry that the task lookup might break in the future. Additionally, the task is probably not considered public API, is it? Perhaps this plugin could offer its own properties to set the various details it relies on? 🤔

Also, if someone could tell me whether I need to apply similar workarounds to other tasks, that would be much appreciated. As I said above, I'm not sure if there are other areas with similar issues.

markushi commented 1 month ago

@bddckr thanks for reporting, this actually looks like a bug on our end. In general our Gradle plugin is variant-aware, looks like we missed that part.