chore: coordinated Android toolchain upgrade (AGP 9.3.1, Gradle 9.7.1, Kotlin plugin 2.4.10) - #393
chore: coordinated Android toolchain upgrade (AGP 9.3.1, Gradle 9.7.1, Kotlin plugin 2.4.10)#393nickolas-dimitrakas wants to merge 4 commits into
Conversation
…, Kotlin plugin 2.4.10) Combines what were three separate, individually-unbuildable dependabot PRs (#365 AGP, #372/#390 Gradle wrapper, #364 Kotlin plugin) since none of them pass CI alone: AGP 9.3.1 needs the newer Gradle wrapper, and Kotlin Gradle Plugin 2.4.10 needs AGP >=8.5.2. Fixes needed beyond the version bumps themselves, found by actually running the build rather than guessing: - AGP 9 registers its own kotlin extension, so explicitly applying the kotlin-android plugin on top now fails configuration. Guard it (same fix already proposed standalone in #384 -- this supersedes that PR too, so it can close without ever needing its CI run approved). - Kotlin Gradle Plugin 2.x removed the android.kotlinOptions DSL; moved jvmTarget to the new top-level kotlin { compilerOptions { ... } } block. - AGP 9 removed adbOptions.installOptions (long-deprecated, only affects adb install flags for on-device installs, unused by CI). - AGP 9's android.sourceSets.main.java.srcDirs no longer pulls Kotlin files into compilation on its own -- needed the parallel kotlin.srcDirs addition, or the old/new-arch source set split (oldarch vs newarch) silently stopped compiling. - compileSdk/targetSdk 33 -> 36: newer transitive deps (e.g. androidx.annotation:annotation-experimental) now require compileSdk 34+; 36 matches what /sample already uses. minSdk left at 21 -- untouched, since that's a support-range product decision, not a build requirement. - Removed the byte-buddy 1.15.11 force-pin added in #317: that pin worked around Jetifier failing to parse byte-buddy's newer multi-release jar. AGP 9 deprecates enableJetifier (defaults to false, removed in AGP 10) -- every dependency here is already AndroidX-native, so Jetifier was doing nothing except failing on that jar. Disabling it outright fixes the root cause and, as a bonus, unblocks #387/#388 (byte-buddy 1.18.13 bump) too: verified locally that 1.18.13 builds clean once Jetifier is off. Verified locally end to end: - android/: ./gradlew test, ./gradlew lint, ./gradlew ktlintCheck (the exact commands the JS Tests/Android Unit Tests/Android Lint/Android kotlin lint CI jobs run) -- all pass. - sample/: full CI sequence (yarn install, yarn dev:pack, fresh sample yarn.lock + install including a real pod install, then ./gradlew assembleDebug) -- passes, matching the Android Sample App job. - Did not touch anything iOS, so the iOS Sample App job is unaffected.
PR SummaryMedium Risk Overview Gradle / AGP compatibility fixes include guarding Docs ( Reviewed by Cursor Bugbot for commit 0550676. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
🟡 Changes recommended
Resolve the Windows wrapper termination issue and reconcile compileSdk 36 with documented consumer requirements.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Coordinates the Android toolchain upgrade to AGP 9.3.1, Gradle 9.7.1, and Kotlin 2.4.10.
Changes:
- Migrates AGP and Kotlin configuration.
- Updates SDK, source sets, and Gradle wrapper versions.
- Disables Jetifier and removes obsolete configuration.
File summaries
| File | Summary |
|---|---|
android/gradlew.bat |
Regenerated Windows wrapper; error paths need to terminate cleanly. |
android/gradlew |
Regenerated POSIX wrapper script. |
android/gradle/wrapper/gradle-wrapper.properties |
Upgrades the Gradle distribution to 9.7.1. |
android/gradle.properties |
Disables deprecated Jetifier processing. |
android/build.gradle |
Updates Android/Kotlin tooling and SDK configuration; compile SDK documentation compatibility requires resolution. |
Review details
Suppressed comments (2)
android/build.gradle:70
- For an Android library, the configured compile SDK is recorded as the AAR metadata
minCompileSdk, so changing this from 33 to 36 makes consuming apps require compileSdk 36. That conflicts with the repository’s documented 35+ requirement (README.md:341 and MIGRATING.md:136), while the stated dependency requirement is only 34+/35+. Please either keep the library at the minimum required SDK or update the documented consumer support requirement and migration guidance.
compileSdkVersion 36
android/gradlew.bat:68
- The invalid-JAVA_HOME path has the same fall-through problem: after setting the child cmd's error level, execution reaches
:executeand invokes the invalidJAVA_EXE. Exit the batch file after reporting the error so callers receive the intended failure without attempting execution.
"%COMSPEC%" /c exit 1
- Files reviewed: 5/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
trunk-io/trunk-action's own setup script checks 'command -v jq' and
errors out if missing ("jq not installed on system!"), which has been
failing Trunk Check across many recent PRs in this repo even though
ubuntu-latest normally ships jq. Not a required check, but add a
fallback install so it stops being red noise on every PR.
These are regenerated verbatim by `gradle wrapper` (not hand-maintained), so trunk's shellcheck/shfmt findings on them are noise, not something to fix by hand — editing would just get overwritten on the next wrapper regen, or drift from the vendored original. The 9.7.1 wrapper regen in this PR surfaced 4 new findings on android/gradlew that would otherwise fail Trunk Check.
Copilot review caught this: bumping this library's own compileSdk to 36 raises its AAR metadata minCompileSdk, which is a hard floor for consuming apps regardless of whether android-rokt-kit (which only needs 35+) is included. Docs previously only mentioned the kit's 35+ floor.
Needed to actually get this PR's dependency bump working end to end: lifecycle-runtime-ktx 2.11.0 pulls in lifecycle-runtime-compose-android, which requires AGP >=9.1.0. The library module already has that (from #393), but the sample app has its own separate Gradle/AGP/Kotlin toolchain via React Native's own gradle-plugin, still pinned well below that on RN 0.84.0. - react-native 0.84.0 -> 0.87.1 (latest stable), with matching @react-native/* and @react-native-community/cli bumps. - RN 0.87.1's bundled react-native-gradle-plugin defaults to a newer AGP that requires Gradle >=9.4.1 — bumped the sample's wrapper to 9.4.1 (not 9.7.1 like the library: RN 0.87.1's gradle-plugin pins its own Kotlin to 2.2.0 internally, which can't read Gradle 9.7.1's bundled Kotlin 2.4.0 metadata; 9.4.1 is what RN 0.87.1 actually ships against). - Matched the sample's own kotlinVersion to 2.2.0 for the same reason. - Applied the same 'AGP9 registers its own kotlin extension' guard to the sample's app/build.gradle that #393 already applied to the library (same root cause, different module). - getDefaultProguardFile('proguard-android.txt') is no longer supported by this AGP (removes -dontoptimize implicitly) — switched to 'proguard-android-optimize.txt' per the build's own error message. - pod install pulled the newer prebuilt React Native Core/Dependencies setup into the Xcode project and privacy manifest automatically. Verified: sample/android ./gradlew assembleDebug passes clean (including checkDebugAarMetadata, the actual check this PR needed to satisfy). sample/ios pod install succeeds. Library module (android/) re-verified unaffected — test/lint/ktlintCheck still pass. Known follow-up, not introduced by this change and not CI-gated: sample's own 'yarn lint' hits a pre-existing @babel/eslint-parser 7.29.x bug (TypeError in convertTemplateType) unrelated to this upgrade — the required JS Tests check lints js/lib at the repo root, not sample/, so this doesn't block CI, but worth fixing separately.
|
Closing — bumping compileSdk to support AGP9 is a breaking change for consumers below the new floor, so this needs proper scoping/comms rather than shipping as a toolchain bump. |
Combines three dependabot PRs that were each individually unbuildable — AGP 9.3.1 (#365), Gradle wrapper (#372/#390), and Kotlin Gradle Plugin 2.4.10 (#364) — since AGP 9.3.1 needs the newer Gradle wrapper, and KGP 2.4.10 needs AGP >=8.5.2. None of them could pass CI alone.
What else broke (found by actually running the build, not guessing)
kotlinextension, so explicitly applyingkotlin-androidon top now fails configuration. Guarded it — this is the same fix already proposed standalone in fix(android): skip explicit Kotlin plugin when AGP registers the kotlin extension #384, so that PR can close without ever needing its CI run approved (it's a fork PR stuck on GitHub's first-time-contributor gate).android.kotlinOptionsDSL; movedjvmTargetto the new top-levelkotlin { compilerOptions { ... } }block.adbOptions.installOptions(long-deprecatedadb installflags, unused by CI anyway).android.sourceSets.main.java.srcDirsstopped pulling Kotlin files into compilation on its own — needed the parallelkotlin.srcDirsaddition, or the old/new-arch source set split silently broke (old-arch Kotlin files weren't compiled at all).compileSdk/targetSdk33 → 36: newer transitive deps (e.g.androidx.annotation:annotation-experimental) now require compileSdk 34+. 36 matches what/samplealready uses.minSdkleft untouched at 21 — that's a support-range product decision, not something this build upgrade should make.byte-buddy1.15.11 force-pin from chore: bump org.mockito:mockito-android from 5.8.0 to 5.23.0 in /android #317: that pin worked around Jetifier failing to parse byte-buddy's newer multi-release jar (Unsupported class file major version 68). AGP 9 deprecatesenableJetifier(defaults tofalse, removed entirely in AGP 10) — every dependency here is already AndroidX-native, so Jetifier was doing nothing except choking on that jar. Disabling it fixes the root cause, and as a bonus unblocks chore: bump net.bytebuddy:byte-buddy from 1.15.11 to 1.18.13 in /android #387/chore: bump net.bytebuddy:byte-buddy-agent from 1.15.11 to 1.18.13 in /android #388 (byte-buddy 1.18.13 bump) — verified locally that 1.18.13 builds clean with Jetifier off.Verification
Ran the exact commands CI runs, not just a generic build:
android/:./gradlew test,./gradlew lint,./gradlew ktlintCheck— matching the JS Tests/Android Unit Tests/Android Lint/Android kotlin lint jobs. All pass.sample/: full CI sequence —yarn install,yarn dev:pack, freshsample/yarn.lock+ install (including a realpod install), then./gradlew assembleDebug— matching the Android Sample App job. Passes.Recommend closing once this merges
#387/#388 (byte-buddy 1.18.13) should become mergeable once rebased onto this.