Minify the Wear app's release builds - #16443
Conversation
`minifyEnabled false` came from the Android Studio Wear OS module template
in the module's scaffolding commit and was never revisited,
so the Wear app has always shipped unshrunk.
Two weeks after the scaffold, `WooCommerce-Wear/proguard-rules.pro` was replaced
with a copy of the phone app's rules that R8 has never read.
Turning it on cuts the `vanillaRelease` APK from 18,996,193 to 6,839,159 bytes.
It also gives the Wear module a ProGuard mapping to upload,
which is what `includeProguardMapping` in the parent PR was already asking for.
The copied rules carry `-dontobfuscate` and `-keep class com.woocommerce.** { *; }`,
so this shrinks unused library code
without renaming anything or touching a single app class.
---
Generated with the help of Claude Code, https://code.claude.com
Co-Authored-By: Claude Code Opus 5 <noreply@anthropic.com>
Both apps had the same 40 lines of Sentry setup copy-pasted, and they had already drifted: until the parent PR, the Wear app was missing `includeProguardMapping` and had `includeSourceContext` hardcoded to `true`. Keeping one copy makes that class of drift impossible rather than something a reviewer has to catch twice. Each module now declares only what is genuinely its own: the Sentry project it reports to, and for the phone app the `cardreader` source directory that the Wear app does not depend on. The shared block lives in the root build file rather than under `config/gradle/` because a script applied with `apply from:` gets its own classloader scope and cannot resolve `InstrumentationFeature` or `SentryCliExecTask`. The root script can, via `alias(libs.plugins.sentry) apply false` — the same mechanism the neighbouring `AppPlugin` and `LibraryPlugin` blocks rely on. Verified by dumping every `sentry` extension property for both modules before and after: identical. The only difference is the Wear module gaining the `uploadSentryProguardMappings*` tasks, which the previous commit is what enables. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Code Opus 5 <noreply@anthropic.com>
Flagged `[*****]` because R8 building cleanly says nothing about tiles and complications surviving on a watch, and this is the first release where they run through it. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Code Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
AI Code Review - No issues found. The changes look good.
This is a clean build-configuration refactor. The shared Sentry block moves to the root build.gradle and is applied per-project via plugins.withId(libs.plugins.sentry.get().pluginId); each app keeps only its projectName (and WooCommerce keeps its extra source dirs). The merge order is correct: the root callback fires when each app applies the Sentry plugin and sets org/authToken/etc., then each app's own sentry { projectName = ... } runs later in its script body, so projectName is preserved. Enabling R8 for the Wear release is well supported by the existing proguard-rules.pro (-dontobfuscate, plus keep rules for com.woocommerce.**, FluxC, Gson, Retrofit, EventBus), which mitigates the usual shrinking risks to JSON deserialization and reflection. A nice side effect is that the Wear mapping upload (includeProguardMapping) now becomes meaningful for de-obfuscating Sentry stack traces.
PR housekeeping
- Build/tooling change: no formal app test plan required. Worth a quick smoke test of a release Wear build to confirm R8 shrinking doesn't break runtime behaviour, and a CI check that Sentry source-context/mapping uploads still succeed for both projects.
Automatic review · claude-opus-4-8 · Workflow run
How to reply to a finding
Reply on this review (or inline at the line the finding refers to) with one of:
@claude addressed- I made the change. Bot verifies against the next diff before marking resolved.@claude rejected: <reason>- Will not fix; reason gets quoted on the next review.@claude not-applicable- Finding does not apply (wrong file, already covered elsewhere, etc.).
The bot honours these on the next review pass.
There was a problem hiding this comment.
Pull request overview
Enables R8 shrinking for the Wear OS app’s release builds and centralizes shared Sentry Gradle configuration at the root project level, reducing duplicated/dated module-specific Sentry config and making mapping/source uploads consistent across modules.
Changes:
- Turn on
minifyEnabledforWooCommerce-Wearrelease builds to shrink the shipped artifact. - Move common
sentry {}configuration + Sentry auth-token guard from module build scripts into the rootbuild.gradlefor all subprojects that apply the Sentry plugin. - Add a release note calling out the Wear release shrink change and its higher smoke-test priority.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
WooCommerce/build.gradle |
Removes duplicated shared Sentry config; keeps only app-specific Sentry settings (project name + extra source dirs). |
WooCommerce-Wear/build.gradle |
Enables R8 shrinking for release builds and trims Sentry config to module-specific project naming. |
build.gradle |
Adds shared Sentry configuration under subprojects for any module applying the Sentry plugin. |
RELEASE-NOTES.txt |
Adds a Wear-focused release note entry (with [*****]) about enabling shrinking. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Build environment changeslist+ New Dependencies
io.sentry.android.gradle:io.sentry.android.gradle.gradle.plugin:6.15.0
io.sentry:sentry:8.49.0
io.sentry:sentry-android-gradle-plugin:6.15.0tree+\--- io.sentry.android.gradle:io.sentry.android.gradle.gradle.plugin:6.15.0
+ \--- io.sentry:sentry-android-gradle-plugin:6.15.0
+ +--- org.ow2.asm:asm-util:9.4 -> 9.9 (*)
+ +--- org.ow2.asm:asm-commons:9.4 -> 9.9 (*)
+ \--- io.sentry:sentry:8.49.0 |
|
|
| buildTypes { | ||
| release { | ||
| minifyEnabled false | ||
| minifyEnabled = true |

Stacked on #16427.
Description
While reviewing #16427, @AliSoftware asked whether
minifyEnabled falseon the Wear app was intentional. It isn't: it came verbatim from the Android Studio Wear OS module template in the module's scaffolding commit and was never revisited. Two weeks later the module'sproguard-rules.prowas replaced with a copy of the phone app's — 161 lines that R8 has never read, and that someone has since maintained.Nothing about Wear OS prevents shrinking. The Wear app is a real shipped artifact, built and uploaded by the release pipeline with its own AAB and GitHub release, so it has been going to watches unshrunk this whole time. On
vanillaReleasethat is 18,996,193 → 6,839,159 bytes, on the platform with the tightest storage budget of the two.It also makes #16427's
includeProguardMappingmeaningful for Wear: with minification off, nouploadSentryProguardMappings*task exists on that module at all.The second commit removes the copy-paste this whole thread came from. The two
sentry {}blocks were identical, and they had already drifted — before #16427 the Wear one was missingincludeProguardMappingand hardcodedincludeSourceContext = true. There is now one copy in the root build file, and each module declares only its own Sentry project (plus, for the phone app, thecardreadersource dir the Wear app has no dependency on).Intentional tradeoffs
The shared block sits in the root
build.gradlerather than aconfig/gradle/sentry.gradlescript. A script applied withapply from:gets its own classloader scope and cannot resolveInstrumentationFeatureorSentryCliExecTask; the root script can, which is the same mechanism theAppPlugin/LibraryPluginblocks beside it already use.proguard-rules.prois left alone. Most of it — Zendesk, Glide, Picasso, photoview — names dependencies the Wear module doesn't have, but trimming it belongs in its own PR now that the file is finally live.Gotchas
R8 building cleanly is not the same as the watch app working. The copied rules carry
-dontobfuscateand-keep class com.woocommerce.** { *; }, so no app class is renamed or removed and this is shrinking over library code only — but tiles, complications and other manifest-only entry points are the classic Wear R8 casualties and only a device can prove them. Hence the[*****]release note.Test Steps
Nothing in the PR pipeline exercises a Wear release build — prototype builds are
JalapenoDebug, and only the API-triggered release pipeline assembles Release. So a green CI run here proves nothing about either change. #16444 is a throwaway stacked PR that runs the real upload tasks; read it for the CI-side evidence.Locally, against this branch:
./gradlew :WooCommerce-Wear:assembleVanillaRelease— R8 runs,lintVitalpasses, APK is 6,839,159 bytes against 18,996,193 ontrunk.CI=true ./gradlew :WooCommerce-Wear:tasks --all | grep uploadSentryProguardMappings— present here, absent on Configure Sentry from public values and an env-injected token #16427's head.CI=true ./gradlew :WooCommerce-Wear:assembleVanillaRelease --dry-runlists the upload tasks; withoutCIit lists none.SENTRY_AUTH_TOKEN= CI=true ./gradlew :WooCommerce-Wear:uploadSentryProguardMappingsVanillaReleasefails through the guard withSENTRY_AUTH_TOKEN is not set, proving the sharedtasks.withType(SentryCliExecTask)block still wires up per module.sentryextension property was dumped for both modules before and after via an init script: identical, the only difference being the Wear tasks from (2).Images/gif
N/A.
RELEASE-NOTES.txtif necessary. Use the "[Internal]" label for non-user-facing changes.