Open romtsn opened 1 year ago
Thanks for opening this issue @romtsn
For future reference, you can specify where you want the mapping file to be stored by passing a custom proguard configuration like this:
// desktop/build.gradle.kts
compose.desktop {
// your app's configuration
buildTypes.release.proguard {
obfuscate.set(true)
configurationFiles.from(project.file("compose-desktop.pro"))
}
}
}
and in your compose-desktop.pro
file. use the -printmapping
option (see the doc):
-printmapping mapping.txt
# your other proguard configurations & rules
(Moved from #429)
Currently, sentry only has a Gradle plugin for Android builds that integrates tightly into AGP.
We are developing Java applications, and want to use the release announcement, the proguard mapping file upload, and source map upload functionality in a regular java
Gradle build.
Extract common functionality from the sentry-android-gradle-plugin
into a shared component and create a sentry-gradle-plugin
that offers tasks to announce a release as well as upload proguard mapping files. These tasks should be able to accept all the required and optional parameters of the CLI commands. It should also register an extension to configure common parameters across the default tasks, such as the auth token.
@leonard84 thanks for moving it here. Could you please give more details about how you use proguard/r8? Is it through a custom task or through a gradle plugin (if so, which one)? Just wanna know better which tasks do we have to hook with. Thanks
It is a custom subclass of the official proguard.gradle.ProGuardTask
to fix some issues with build caching that the original has.
While I appreciate that having this upload functionality in a Gradle plugin could be useful for someone, why can't we just upload the mapping files on the web interface?
My expectation was that when I open a Sentry issue with an obfuscated stracktrace, Sentry would show a prompt like "we don't have a mapping file for version 1.2.3, click to upload", and let me upload my mapping-1.2.3.txt
right then.
I don't even use the Gradle plugin in my project and don't see a need to complicate my build.
@Nohus thanks for the feedback.
You could try to manually upload your mapping files to Sentry using CI. We have sentry-cli
which allows you to upload. Here's how we use it to upload mapping files from the Gradle plugin. There's some docs available as well.
You'd also have to specify io.sentry.ProguardUuids
or use setProguardUuid
so events sent to Sentry know which mapping file should be used. Both the upload and running applications need to know the UUID of the mapping file.
As for doing this after the fact. That's currenlty not possible as events are processed as they come in so adding the mapping file after events arrived won't change the events as it is implemented now. There were discussions around doing source lookup when looking at events in the Sentry UI instead of doing it during processing but as far as I know nothing has been implemented yet and there's no ETA for this change. Applying mapping files could work the same way but since you'd have to keep versioned mapping files around then manually upload them and add the UUID to the running application anyways, I'd suggest setting up CI to do the upload for you using sentry-cli
as suggested above.
Thank you for the information and links, I have used sentry-cli
to upload the mapping file from my CI and it is working correctly now.
@Nohus Can you share how you did this? I'm working on the same thing currently.
@sproctor This is the gist of it:
# Create release on Sentry
sentry-cli releases new \
--project "app" \
--finalize "app@$version"
# Upload ProGuard mapping
sentry-cli upload-proguard \
--uuid "$buildUuid" \
"build/mapping-$version.txt" \
--require-one \
--project "app" \
--app-id "app" \
--platform "kotlin" \
--version "$version" \
This was about half of it. I'll add my solution here for anyone else interested. I had a terrible time getting a properties file generated. It worked fine locally but not on CI.
Gradle task:
abstract class SentryGenerateProguardUuidTask : DefaultTask() {
init {
outputs.upToDateWhen { false }
}
@get:Input
abstract val output: Property<File>
@TaskAction
fun createUuidFile() {
val outputFile = output.get()
val uuid = UUID.randomUUID()
val props = Properties().also {
it.setProperty("io.sentry.ProguardUuids", uuid.toString())
}
outputFile.writer().use { writer ->
props.store(writer, "")
}
logger.info("SentryGenerateProguardUuidTask - outputFile: ${outputFile.absolutePath}, uuid: $uuid")
}
}
tasks {
val sentryUuid = register<SentryGenerateProguardUuidTask>("sentryUuid") {
dependsOn("processResources")
output.set(layout.buildDirectory.file("resources/main/sentry_proguard_uuid.properties").get().asFile)
}
compileKotlin {
dependsOn(sentryUuid)
}
}
Github action:
...
- name: Setup Sentry CLI
run: npm install @sentry/cli
- name: Upload mapping
shell: bash
run: |
SENTRY=node_modules/.bin/sentry-cli
VERSION=${GITHUB_REF_NAME:1}
while IFS='=' read -r key value
do
key=$(echo $key | tr '.' '_')
value=$(echo $value | tr -d '\n\r')
eval ${key}=\${value}
done < app/build/resources/main/sentry_proguard_uuid.properties
$SENTRY releases new --project "app" --org "org" --finalize "desktop@$VERSION" --auth-token "${{ secrets.SENTRY_AUTH_TOKEN }}"
$SENTRY upload-proguard --uuid "$io_sentry_ProguardUuids" "app/build/mapping.txt" --require-one --project "app" --org "org" --app-id "desktop" --platform "kotlin" --version "$VERSION" --auth-token "${{ secrets.SENTRY_AUTH_TOKEN }}"
Thanks for sharing
Description
Since compose-desktop receives more and more traction, and people usually like to minify their apps (to reduce the final
.jar
size, and also to optimize their bytecode), we should look into how to provide automatic support for uploading proguard/R8 mapping files.Since there's no standardized way of using proguard/r8 with pure JVM apps, I guess we'll need to provide some configuration option, which task to depend on or where is the location of the mapping file.
This is also valid for any JVM desktop app (JavaFX, Swing, etc.) that uses a minification tool.