Skip to content

chore: coordinated Android toolchain upgrade (AGP 9.3.1, Gradle 9.7.1, Kotlin plugin 2.4.10) - #393

Closed
nickolas-dimitrakas wants to merge 4 commits into
mainfrom
chore/android-toolchain-upgrade
Closed

chore: coordinated Android toolchain upgrade (AGP 9.3.1, Gradle 9.7.1, Kotlin plugin 2.4.10)#393
nickolas-dimitrakas wants to merge 4 commits into
mainfrom
chore/android-toolchain-upgrade

Conversation

@nickolas-dimitrakas

Copy link
Copy Markdown
Contributor

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)

  • AGP 9 registers its own kotlin extension, so explicitly applying kotlin-android on 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).
  • 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 adb install flags, unused by CI anyway).
  • AGP 9's android.sourceSets.main.java.srcDirs stopped pulling Kotlin files into compilation on its own — needed the parallel kotlin.srcDirs addition, or the old/new-arch source set split silently broke (old-arch Kotlin files weren't compiled at all).
  • 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 untouched at 21 — that's a support-range product decision, not something this build upgrade should make.
  • Removed the byte-buddy 1.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 deprecates enableJetifier (defaults to false, 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, fresh sample/yarn.lock + install (including a real pod install), then ./gradlew assembleDebug — matching the Android Sample App job. Passes.
  • No iOS files touched, so the iOS Sample App job is unaffected by this PR.

Recommend closing once this merges

#387/#388 (byte-buddy 1.18.13) should become mergeable once rebased onto this.

…, 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.
Copilot AI lite review requested due to automatic review settings September 10, 2026 16:33
@nickolas-dimitrakas
nickolas-dimitrakas requested a review from a team as a code owner September 10, 2026 16:33
@cursor

cursor Bot commented Sep 10, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Major Android build-tool bumps and a higher compileSdk floor affect every Android integrator; runtime JS behavior is unchanged and minSdk is unchanged.

Overview
This PR coordinates the Android native build toolchain so CI and local builds stay in sync: Gradle wrapper 9.7.1, Android Gradle Plugin 9.3.1, and Kotlin Gradle Plugin 2.4.10, with compileSdk / targetSdk raised to 36 (minSdk still 21).

Gradle / AGP compatibility fixes include guarding kotlin-android when AGP 9 already registers the kotlin extension, moving JVM target to the KGP 2.x kotlin { compilerOptions { ... } } block, mirroring old/new-arch sources in kotlin.srcDirs (so Kotlin still compiles), dropping deprecated adbOptions.installOptions, turning android.enableJetifier off (and removing the byte-buddy force-pin that existed only to work around Jetifier), and regenerating gradlew / gradlew.bat. Trunk now ignores shellcheck/shfmt on vendored gradlew scripts; CI adds a step to ensure jq is installed.

Docs (README.md, MIGRATING.md) now state that because the library compiles against compileSdk 36, consuming apps need compileSdk 36+, not only when they add android-rokt-kit.

Reviewed by Cursor Bugbot for commit 0550676. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 :execute and invokes the invalid JAVA_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.

Comment thread android/gradlew.bat
@nickolas-dimitrakas nickolas-dimitrakas self-assigned this Sep 10, 2026
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.
nickolas-dimitrakas added a commit that referenced this pull request Sep 10, 2026
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.
@nickolas-dimitrakas

Copy link
Copy Markdown
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants