build: drop the AGP 9 built-in Kotlin opt-out - #4120
Merged
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Public API changes in ui:debugview (2 removed)- public final class InternalDebugRevenueCatScreenViewModelFactory extends androidx.lifecycle.ViewModelProvider.NewInstanceFactory
- ctor public InternalDebugRevenueCatScreenViewModelFactory(kotlin.jvm.functions.Function1<? super com.revenuecat.purchases.models.StoreTransaction,kotlin.Unit> onPurchaseCompleted, kotlin.jvm.functi…Generated by 🚫 Danger |
AlvaroBrey
force-pushed
the
build/agp9-drop-compat-flags
branch
from
August 27, 2026 18:48
4f55318 to
9a6cad3
Compare
📸 Snapshot Test31 modified, 590 unchanged
🛸 Powered by Emerge Tools |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 11.0-dev #4120 +/- ##
=========================================
Coverage 83.25% 83.25%
=========================================
Files 448 448
Lines 18110 18110
Branches 2744 2744
=========================================
Hits 15077 15077
Misses 2140 2140
Partials 893 893 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
AlvaroBrey
force-pushed
the
build/agp9-drop-compat-flags
branch
from
August 28, 2026 10:12
9a6cad3 to
c97fc41
Compare
AlvaroBrey
marked this pull request as ready for review
August 28, 2026 11:10
AlvaroBrey
added a commit
that referenced
this pull request
Aug 28, 2026
…e to AGP 9 (#4115) - Moves the two standalone sample builds, `MagicWeatherCompose` and `CustomEntitlementComputationSample`, to AGP 9.2.1 and Gradle 9.4.1, catching them up with the root build. - Both take the `android.builtInKotlin=false` and `android.newDsl=false` opt-out. #4120 removes it, stacked on top of this. Targets integration branch (`11.0-dev`) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Build-only version and Gradle property changes in example projects; no runtime or library code changes. > > **Overview** > Aligns the **MagicWeatherCompose** and **CustomEntitlementComputationSample** example builds with the root toolchain by bumping **AGP** from `8.13.2` to **`9.2.1`** and the Gradle wrapper from **`8.14.5`** to **`9.4.1`**. > > Each sample’s `gradle.properties` adds **`android.builtInKotlin=false`** and **`android.newDsl=false`** so existing **`kotlin-android`** plugin usage keeps working until a follow-up removes those opt-outs for AGP 10. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 16f5db0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
ui/debugview/api.txt loses InternalDebugRevenueCatScreenViewModelFactory. The class lives in src/debug/kotlin, so it was never in the published defaultsRelease AAR and the signature was wrong; confirmed zero occurrences in debugview-defaults-release.aar.
AlvaroBrey
force-pushed
the
build/agp9-drop-compat-flags
branch
from
August 28, 2026 11:26
d579358 to
e45c589
Compare
AlvaroBrey
added a commit
that referenced
this pull request
Aug 31, 2026
…e to AGP 9 (#4115) - Moves the two standalone sample builds, `MagicWeatherCompose` and `CustomEntitlementComputationSample`, to AGP 9.2.1 and Gradle 9.4.1, catching them up with the root build. - Both take the `android.builtInKotlin=false` and `android.newDsl=false` opt-out. #4120 removes it, stacked on top of this. Targets integration branch (`11.0-dev`) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Build-only version and Gradle property changes in example projects; no runtime or library code changes. > > **Overview** > Aligns the **MagicWeatherCompose** and **CustomEntitlementComputationSample** example builds with the root toolchain by bumping **AGP** from `8.13.2` to **`9.2.1`** and the Gradle wrapper from **`8.14.5`** to **`9.4.1`**. > > Each sample’s `gradle.properties` adds **`android.builtInKotlin=false`** and **`android.newDsl=false`** so existing **`kotlin-android`** plugin usage keeps working until a follow-up removes those opt-outs for AGP 10. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 16f5db0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
AlvaroBrey
added a commit
that referenced
this pull request
Aug 31, 2026
- Removes the `android.builtInKotlin=false` and `android.newDsl=false` opt-out that #3964 added, from the root build and from both standalone sample builds, and takes `kotlin-android` out of 11 build scripts and the 3 convention plugins. - `ui/debugview/api.txt` loses `InternalDebugRevenueCatScreenViewModelFactory`. Metalava now analyses the release variant, and that class lives in `src/debug/kotlin`. The release AAR contains zero occurrences of it, so it never shipped and the entry was wrong - Fixes `:dokkaGenerate`, which is already broken on `11.0-dev`. Built-in Kotlin registers Dokka source sets per Android variant instead of per Kotlin source set, and registers them lazily, so both `:purchases` and `:ui:revenuecatui` now select the documented variant through `configureEach`. - Bumps `androidx.navigation` 2.5.3 to 2.9.8. safeargs 2.5.3 detects AGP through the old DSL and hard fails, so the navigation bump is a prerequisite for the new DSL rather than an independent upgrade. ### Checklist - [ ] If applicable, unit tests - [ ] If applicable, create follow-up issues for `purchases-ios` and hybrids <details><summary>Agent description</summary> ### Motivation AGP 9 enables built-in Kotlin and rejects the `org.jetbrains.kotlin.android` plugin outright: ``` The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0. ``` Opting out needs two flags together, `android.builtInKotlin=false` and `android.newDsl=false`, because the kotlin-android plugin casts the android extension to `BaseExtension`, which the new DSL drops. #3964 took that opt-out so the version bump stayed reviewable. AGP 10 removes the opt-out, so the migration has to happen regardless; doing it separately keeps the two diffs legible. ### Description Four things blocked the migration, each hidden behind the previous. **The old DSL extension types are gone.** `com.android.build.gradle.BaseExtension` and `com.android.build.gradle.LibraryExtension` do not exist once the new DSL is active. The convention plugins now configure `com.android.build.api.dsl.ApplicationExtension` and `com.android.build.api.dsl.LibraryExtension`, and set `compileSdk` directly rather than calling `compileSdkVersion()`. `KotlinAndroidProjectExtension` stays as is: AGP's built-in Kotlin still registers it. **safeargs 2.5.3 cannot see AGP 9.** It fails with `safeargs plugin must be used with android plugin`, because its detection goes through the old DSL. The 2.5.3 jar references `com/android/build/gradle/BaseExtension`, `AppExtension` and `gradle/api/BaseVariant`; the 2.9.8 jar references only `com.android.build.api.variant.*`. `examples/purchase-tester` is the only module applying the plugin, and it gets its own commit. **Dokka source sets changed shape.** With the kotlin-android plugin, Dokka saw the Kotlin source sets and the config addressed `main`, `defaults` and `customEntitlementComputation`. Built-in Kotlin instead registers one source set per Android variant, and registers them after the `dokka { }` block runs, so `named("defaultsRelease")` throws even though the name is valid later. Both modules now select through `matching { }.configureEach`. `:purchases` keeps `reportUndocumented`, `skipDeprecated`, the Android external documentation link, both source links and the `paywalls.components` suppression, all moved onto the selected variant. The explicit `customEntitlementComputation` suppression is load-bearing, not redundant: Dokka defaults `suppress` to `!isPublishable` and `customEntitlementComputationRelease` is published, so it would otherwise be documented. **`kotlin-test` stops carrying JUnit.** `:feature:galaxy` names `kotlin-test-junit` instead. Verified rather than inherited: with plain `kotlin-test`, `org.junit.Test` is unresolved across all 25 test methods. **Not visible in the diff:** `./gradlew :dokkaGenerate` fails on the base commit with `Dokka cannot generate documentation for Android projects with multiple enabled variants that have common source roots`. The `docs-deploy` job that runs it is gated on release tags, so #3964 never exercised it. This PR is what makes it pass again, which is a bigger deal than the diff makes it look. **Worth noting separately:** AGP 9.2.1 declares `kotlin-gradle-plugin:2.2.10`, so built-in Kotlin takes its compiler from buildscript classpath resolution rather than from our catalog. Confirmed the published contract from #3964 is intact rather than assumed: | check | result | | --- | --- | | resolved KGP | `2.2.21`, not AGP's bundled `2.2.10` | | `:purchases` POM | `kotlin-stdlib:2.2.21` at `compile` scope | | release AAR metadata | `mv=[1,8,0]`, so `languageVersion` 1.8 survives | ### Regression gates - `./gradlew :dokkaGenerate` for the Dokka rework. Generates 1367 pages with `com.revenuecat.purchases.paywalls.components` still suppressed. - `:feature:galaxy:testDefaultsDebugUnitTest` for the `kotlin-test-junit` swap. Needs `--rerun-tasks`: a cached run passes even with the dependency reverted, which is how this could slip through. - `:examples:purchase-tester:assembleDebug` for the navigation bump. **Rejected:** - Wiring the Dokka variant selector to `ANDROID_VARIANT_TO_PUBLISH` instead of hardcoding `"defaultsRelease"` twice. `fastlane/Fastfile:295` rewrites that property per publish, so a `customEntitlementComputation` publish would point Dokka at exactly the variant `:purchases` suppresses. - Hoisting the shared Dokka config into `ConfigureDokka.kt`. Dokka's types are not on build-logic's compile classpath, so it needs the reflection pattern from `ConfigureMetalava.kt`, and sharing `reportUndocumented.set(true)` would newly turn it on for the four public-library modules that have no `dokka { }` block. - Moving the five hand-rolled app modules onto `revenuecat-android-application`, which would collapse 5 of the 6 per-module edits. Each keeps 2 to 3 overrides, and both `testpurchases*` modules deliberately pin old `compileSdk`/`targetSdk` to test compatibility. Worth a separate PR, not this one. **Limitations:** - `examples/MagicWeather` and `test-apps/sdksizetesting` still apply `kotlin-android`. They are separate builds pinned to AGP 8.13.2, so they keep the plugin correctly and are untouched. - `purchases/build.gradle.kts:120` has a dead `androidComponents { onVariants }` block guarding a `"free"` product flavor that does not exist in the repo. Pre-existing and unrelated, left alone. </details> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Wide Gradle/AGP convention changes affect every Android module’s compile and doc generation; navigation and Dokka behavior are prerequisites for CI release docs, with limited runtime SDK impact. > > **Overview** > Completes the AGP 9 migration by removing the **`android.builtInKotlin=false`** / **`android.newDsl=false`** opt-outs and dropping **`org.jetbrains.kotlin.android`** across convention plugins, app modules, samples, and the version catalog. > > Build-logic now configures **`ApplicationExtension`** / **`LibraryExtension`** from the new DSL (e.g. **`compileSdk`** instead of **`BaseExtension`**). **`:purchases`** and **`:ui:revenuecatui`** Dokka blocks use **`matching { }.configureEach`** so documentation targets **`defaultsRelease`** and suppresses **`customEntitlementComputation`** variants after AGP registers per-variant source sets lazily. > > **`androidx.navigation`** is bumped **2.5.3 → 2.9.8** so Safe Args works with the new DSL. **`:feature:galaxy`** switches unit tests to **`kotlin-test-junit`**. **`ui/debugview/api.txt`** drops **`InternalDebugRevenueCatScreenViewModelFactory`** (debug-only; not in the release API Metalava analyzes). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e45c589. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
AlvaroBrey
added a commit
that referenced
this pull request
Sep 7, 2026
…e to AGP 9 (#4115) - Moves the two standalone sample builds, `MagicWeatherCompose` and `CustomEntitlementComputationSample`, to AGP 9.2.1 and Gradle 9.4.1, catching them up with the root build. - Both take the `android.builtInKotlin=false` and `android.newDsl=false` opt-out. #4120 removes it, stacked on top of this. Targets integration branch (`11.0-dev`) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Build-only version and Gradle property changes in example projects; no runtime or library code changes. > > **Overview** > Aligns the **MagicWeatherCompose** and **CustomEntitlementComputationSample** example builds with the root toolchain by bumping **AGP** from `8.13.2` to **`9.2.1`** and the Gradle wrapper from **`8.14.5`** to **`9.4.1`**. > > Each sample’s `gradle.properties` adds **`android.builtInKotlin=false`** and **`android.newDsl=false`** so existing **`kotlin-android`** plugin usage keeps working until a follow-up removes those opt-outs for AGP 10. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 16f5db0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
AlvaroBrey
added a commit
that referenced
this pull request
Sep 7, 2026
- Removes the `android.builtInKotlin=false` and `android.newDsl=false` opt-out that #3964 added, from the root build and from both standalone sample builds, and takes `kotlin-android` out of 11 build scripts and the 3 convention plugins. - `ui/debugview/api.txt` loses `InternalDebugRevenueCatScreenViewModelFactory`. Metalava now analyses the release variant, and that class lives in `src/debug/kotlin`. The release AAR contains zero occurrences of it, so it never shipped and the entry was wrong - Fixes `:dokkaGenerate`, which is already broken on `11.0-dev`. Built-in Kotlin registers Dokka source sets per Android variant instead of per Kotlin source set, and registers them lazily, so both `:purchases` and `:ui:revenuecatui` now select the documented variant through `configureEach`. - Bumps `androidx.navigation` 2.5.3 to 2.9.8. safeargs 2.5.3 detects AGP through the old DSL and hard fails, so the navigation bump is a prerequisite for the new DSL rather than an independent upgrade. ### Checklist - [ ] If applicable, unit tests - [ ] If applicable, create follow-up issues for `purchases-ios` and hybrids <details><summary>Agent description</summary> ### Motivation AGP 9 enables built-in Kotlin and rejects the `org.jetbrains.kotlin.android` plugin outright: ``` The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0. ``` Opting out needs two flags together, `android.builtInKotlin=false` and `android.newDsl=false`, because the kotlin-android plugin casts the android extension to `BaseExtension`, which the new DSL drops. #3964 took that opt-out so the version bump stayed reviewable. AGP 10 removes the opt-out, so the migration has to happen regardless; doing it separately keeps the two diffs legible. ### Description Four things blocked the migration, each hidden behind the previous. **The old DSL extension types are gone.** `com.android.build.gradle.BaseExtension` and `com.android.build.gradle.LibraryExtension` do not exist once the new DSL is active. The convention plugins now configure `com.android.build.api.dsl.ApplicationExtension` and `com.android.build.api.dsl.LibraryExtension`, and set `compileSdk` directly rather than calling `compileSdkVersion()`. `KotlinAndroidProjectExtension` stays as is: AGP's built-in Kotlin still registers it. **safeargs 2.5.3 cannot see AGP 9.** It fails with `safeargs plugin must be used with android plugin`, because its detection goes through the old DSL. The 2.5.3 jar references `com/android/build/gradle/BaseExtension`, `AppExtension` and `gradle/api/BaseVariant`; the 2.9.8 jar references only `com.android.build.api.variant.*`. `examples/purchase-tester` is the only module applying the plugin, and it gets its own commit. **Dokka source sets changed shape.** With the kotlin-android plugin, Dokka saw the Kotlin source sets and the config addressed `main`, `defaults` and `customEntitlementComputation`. Built-in Kotlin instead registers one source set per Android variant, and registers them after the `dokka { }` block runs, so `named("defaultsRelease")` throws even though the name is valid later. Both modules now select through `matching { }.configureEach`. `:purchases` keeps `reportUndocumented`, `skipDeprecated`, the Android external documentation link, both source links and the `paywalls.components` suppression, all moved onto the selected variant. The explicit `customEntitlementComputation` suppression is load-bearing, not redundant: Dokka defaults `suppress` to `!isPublishable` and `customEntitlementComputationRelease` is published, so it would otherwise be documented. **`kotlin-test` stops carrying JUnit.** `:feature:galaxy` names `kotlin-test-junit` instead. Verified rather than inherited: with plain `kotlin-test`, `org.junit.Test` is unresolved across all 25 test methods. **Not visible in the diff:** `./gradlew :dokkaGenerate` fails on the base commit with `Dokka cannot generate documentation for Android projects with multiple enabled variants that have common source roots`. The `docs-deploy` job that runs it is gated on release tags, so #3964 never exercised it. This PR is what makes it pass again, which is a bigger deal than the diff makes it look. **Worth noting separately:** AGP 9.2.1 declares `kotlin-gradle-plugin:2.2.10`, so built-in Kotlin takes its compiler from buildscript classpath resolution rather than from our catalog. Confirmed the published contract from #3964 is intact rather than assumed: | check | result | | --- | --- | | resolved KGP | `2.2.21`, not AGP's bundled `2.2.10` | | `:purchases` POM | `kotlin-stdlib:2.2.21` at `compile` scope | | release AAR metadata | `mv=[1,8,0]`, so `languageVersion` 1.8 survives | ### Regression gates - `./gradlew :dokkaGenerate` for the Dokka rework. Generates 1367 pages with `com.revenuecat.purchases.paywalls.components` still suppressed. - `:feature:galaxy:testDefaultsDebugUnitTest` for the `kotlin-test-junit` swap. Needs `--rerun-tasks`: a cached run passes even with the dependency reverted, which is how this could slip through. - `:examples:purchase-tester:assembleDebug` for the navigation bump. **Rejected:** - Wiring the Dokka variant selector to `ANDROID_VARIANT_TO_PUBLISH` instead of hardcoding `"defaultsRelease"` twice. `fastlane/Fastfile:295` rewrites that property per publish, so a `customEntitlementComputation` publish would point Dokka at exactly the variant `:purchases` suppresses. - Hoisting the shared Dokka config into `ConfigureDokka.kt`. Dokka's types are not on build-logic's compile classpath, so it needs the reflection pattern from `ConfigureMetalava.kt`, and sharing `reportUndocumented.set(true)` would newly turn it on for the four public-library modules that have no `dokka { }` block. - Moving the five hand-rolled app modules onto `revenuecat-android-application`, which would collapse 5 of the 6 per-module edits. Each keeps 2 to 3 overrides, and both `testpurchases*` modules deliberately pin old `compileSdk`/`targetSdk` to test compatibility. Worth a separate PR, not this one. **Limitations:** - `examples/MagicWeather` and `test-apps/sdksizetesting` still apply `kotlin-android`. They are separate builds pinned to AGP 8.13.2, so they keep the plugin correctly and are untouched. - `purchases/build.gradle.kts:120` has a dead `androidComponents { onVariants }` block guarding a `"free"` product flavor that does not exist in the repo. Pre-existing and unrelated, left alone. </details> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Wide Gradle/AGP convention changes affect every Android module’s compile and doc generation; navigation and Dokka behavior are prerequisites for CI release docs, with limited runtime SDK impact. > > **Overview** > Completes the AGP 9 migration by removing the **`android.builtInKotlin=false`** / **`android.newDsl=false`** opt-outs and dropping **`org.jetbrains.kotlin.android`** across convention plugins, app modules, samples, and the version catalog. > > Build-logic now configures **`ApplicationExtension`** / **`LibraryExtension`** from the new DSL (e.g. **`compileSdk`** instead of **`BaseExtension`**). **`:purchases`** and **`:ui:revenuecatui`** Dokka blocks use **`matching { }.configureEach`** so documentation targets **`defaultsRelease`** and suppresses **`customEntitlementComputation`** variants after AGP registers per-variant source sets lazily. > > **`androidx.navigation`** is bumped **2.5.3 → 2.9.8** so Safe Args works with the new DSL. **`:feature:galaxy`** switches unit tests to **`kotlin-test-junit`**. **`ui/debugview/api.txt`** drops **`InternalDebugRevenueCatScreenViewModelFactory`** (debug-only; not in the release API Metalava analyzes). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e45c589. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
AlvaroBrey
added a commit
that referenced
this pull request
Sep 7, 2026
…e to AGP 9 (#4115) - Moves the two standalone sample builds, `MagicWeatherCompose` and `CustomEntitlementComputationSample`, to AGP 9.2.1 and Gradle 9.4.1, catching them up with the root build. - Both take the `android.builtInKotlin=false` and `android.newDsl=false` opt-out. #4120 removes it, stacked on top of this. Targets integration branch (`11.0-dev`) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Build-only version and Gradle property changes in example projects; no runtime or library code changes. > > **Overview** > Aligns the **MagicWeatherCompose** and **CustomEntitlementComputationSample** example builds with the root toolchain by bumping **AGP** from `8.13.2` to **`9.2.1`** and the Gradle wrapper from **`8.14.5`** to **`9.4.1`**. > > Each sample’s `gradle.properties` adds **`android.builtInKotlin=false`** and **`android.newDsl=false`** so existing **`kotlin-android`** plugin usage keeps working until a follow-up removes those opt-outs for AGP 10. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 16f5db0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
AlvaroBrey
added a commit
that referenced
this pull request
Sep 7, 2026
- Removes the `android.builtInKotlin=false` and `android.newDsl=false` opt-out that #3964 added, from the root build and from both standalone sample builds, and takes `kotlin-android` out of 11 build scripts and the 3 convention plugins. - `ui/debugview/api.txt` loses `InternalDebugRevenueCatScreenViewModelFactory`. Metalava now analyses the release variant, and that class lives in `src/debug/kotlin`. The release AAR contains zero occurrences of it, so it never shipped and the entry was wrong - Fixes `:dokkaGenerate`, which is already broken on `11.0-dev`. Built-in Kotlin registers Dokka source sets per Android variant instead of per Kotlin source set, and registers them lazily, so both `:purchases` and `:ui:revenuecatui` now select the documented variant through `configureEach`. - Bumps `androidx.navigation` 2.5.3 to 2.9.8. safeargs 2.5.3 detects AGP through the old DSL and hard fails, so the navigation bump is a prerequisite for the new DSL rather than an independent upgrade. ### Checklist - [ ] If applicable, unit tests - [ ] If applicable, create follow-up issues for `purchases-ios` and hybrids <details><summary>Agent description</summary> ### Motivation AGP 9 enables built-in Kotlin and rejects the `org.jetbrains.kotlin.android` plugin outright: ``` The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0. ``` Opting out needs two flags together, `android.builtInKotlin=false` and `android.newDsl=false`, because the kotlin-android plugin casts the android extension to `BaseExtension`, which the new DSL drops. #3964 took that opt-out so the version bump stayed reviewable. AGP 10 removes the opt-out, so the migration has to happen regardless; doing it separately keeps the two diffs legible. ### Description Four things blocked the migration, each hidden behind the previous. **The old DSL extension types are gone.** `com.android.build.gradle.BaseExtension` and `com.android.build.gradle.LibraryExtension` do not exist once the new DSL is active. The convention plugins now configure `com.android.build.api.dsl.ApplicationExtension` and `com.android.build.api.dsl.LibraryExtension`, and set `compileSdk` directly rather than calling `compileSdkVersion()`. `KotlinAndroidProjectExtension` stays as is: AGP's built-in Kotlin still registers it. **safeargs 2.5.3 cannot see AGP 9.** It fails with `safeargs plugin must be used with android plugin`, because its detection goes through the old DSL. The 2.5.3 jar references `com/android/build/gradle/BaseExtension`, `AppExtension` and `gradle/api/BaseVariant`; the 2.9.8 jar references only `com.android.build.api.variant.*`. `examples/purchase-tester` is the only module applying the plugin, and it gets its own commit. **Dokka source sets changed shape.** With the kotlin-android plugin, Dokka saw the Kotlin source sets and the config addressed `main`, `defaults` and `customEntitlementComputation`. Built-in Kotlin instead registers one source set per Android variant, and registers them after the `dokka { }` block runs, so `named("defaultsRelease")` throws even though the name is valid later. Both modules now select through `matching { }.configureEach`. `:purchases` keeps `reportUndocumented`, `skipDeprecated`, the Android external documentation link, both source links and the `paywalls.components` suppression, all moved onto the selected variant. The explicit `customEntitlementComputation` suppression is load-bearing, not redundant: Dokka defaults `suppress` to `!isPublishable` and `customEntitlementComputationRelease` is published, so it would otherwise be documented. **`kotlin-test` stops carrying JUnit.** `:feature:galaxy` names `kotlin-test-junit` instead. Verified rather than inherited: with plain `kotlin-test`, `org.junit.Test` is unresolved across all 25 test methods. **Not visible in the diff:** `./gradlew :dokkaGenerate` fails on the base commit with `Dokka cannot generate documentation for Android projects with multiple enabled variants that have common source roots`. The `docs-deploy` job that runs it is gated on release tags, so #3964 never exercised it. This PR is what makes it pass again, which is a bigger deal than the diff makes it look. **Worth noting separately:** AGP 9.2.1 declares `kotlin-gradle-plugin:2.2.10`, so built-in Kotlin takes its compiler from buildscript classpath resolution rather than from our catalog. Confirmed the published contract from #3964 is intact rather than assumed: | check | result | | --- | --- | | resolved KGP | `2.2.21`, not AGP's bundled `2.2.10` | | `:purchases` POM | `kotlin-stdlib:2.2.21` at `compile` scope | | release AAR metadata | `mv=[1,8,0]`, so `languageVersion` 1.8 survives | ### Regression gates - `./gradlew :dokkaGenerate` for the Dokka rework. Generates 1367 pages with `com.revenuecat.purchases.paywalls.components` still suppressed. - `:feature:galaxy:testDefaultsDebugUnitTest` for the `kotlin-test-junit` swap. Needs `--rerun-tasks`: a cached run passes even with the dependency reverted, which is how this could slip through. - `:examples:purchase-tester:assembleDebug` for the navigation bump. **Rejected:** - Wiring the Dokka variant selector to `ANDROID_VARIANT_TO_PUBLISH` instead of hardcoding `"defaultsRelease"` twice. `fastlane/Fastfile:295` rewrites that property per publish, so a `customEntitlementComputation` publish would point Dokka at exactly the variant `:purchases` suppresses. - Hoisting the shared Dokka config into `ConfigureDokka.kt`. Dokka's types are not on build-logic's compile classpath, so it needs the reflection pattern from `ConfigureMetalava.kt`, and sharing `reportUndocumented.set(true)` would newly turn it on for the four public-library modules that have no `dokka { }` block. - Moving the five hand-rolled app modules onto `revenuecat-android-application`, which would collapse 5 of the 6 per-module edits. Each keeps 2 to 3 overrides, and both `testpurchases*` modules deliberately pin old `compileSdk`/`targetSdk` to test compatibility. Worth a separate PR, not this one. **Limitations:** - `examples/MagicWeather` and `test-apps/sdksizetesting` still apply `kotlin-android`. They are separate builds pinned to AGP 8.13.2, so they keep the plugin correctly and are untouched. - `purchases/build.gradle.kts:120` has a dead `androidComponents { onVariants }` block guarding a `"free"` product flavor that does not exist in the repo. Pre-existing and unrelated, left alone. </details> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Wide Gradle/AGP convention changes affect every Android module’s compile and doc generation; navigation and Dokka behavior are prerequisites for CI release docs, with limited runtime SDK impact. > > **Overview** > Completes the AGP 9 migration by removing the **`android.builtInKotlin=false`** / **`android.newDsl=false`** opt-outs and dropping **`org.jetbrains.kotlin.android`** across convention plugins, app modules, samples, and the version catalog. > > Build-logic now configures **`ApplicationExtension`** / **`LibraryExtension`** from the new DSL (e.g. **`compileSdk`** instead of **`BaseExtension`**). **`:purchases`** and **`:ui:revenuecatui`** Dokka blocks use **`matching { }.configureEach`** so documentation targets **`defaultsRelease`** and suppresses **`customEntitlementComputation`** variants after AGP registers per-variant source sets lazily. > > **`androidx.navigation`** is bumped **2.5.3 → 2.9.8** so Safe Args works with the new DSL. **`:feature:galaxy`** switches unit tests to **`kotlin-test-junit`**. **`ui/debugview/api.txt`** drops **`InternalDebugRevenueCatScreenViewModelFactory`** (debug-only; not in the release API Metalava analyzes). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e45c589. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
android.builtInKotlin=falseandandroid.newDsl=falseopt-out that build: update to AGP 9 (AGP 9.2.1, Gradle 9.4.1, Kotlin 2.2.21) #3964 added, from the root build and from both standalone sample builds, and takeskotlin-androidout of 11 build scripts and the 3 convention plugins.ui/debugview/api.txtlosesInternalDebugRevenueCatScreenViewModelFactory. Metalava now analyses the release variant, and that class lives insrc/debug/kotlin. The release AAR contains zero occurrences of it, so it never shipped and the entry was wrong:dokkaGenerate, which is already broken on11.0-dev. Built-in Kotlin registers Dokka source sets per Android variant instead of per Kotlin source set, and registers them lazily, so both:purchasesand:ui:revenuecatuinow select the documented variant throughconfigureEach.androidx.navigation2.5.3 to 2.9.8. safeargs 2.5.3 detects AGP through the old DSL and hard fails, so the navigation bump is a prerequisite for the new DSL rather than an independent upgrade.Checklist
purchases-iosand hybridsAgent description
Motivation
AGP 9 enables built-in Kotlin and rejects the
org.jetbrains.kotlin.androidplugin outright:Opting out needs two flags together,
android.builtInKotlin=falseandandroid.newDsl=false, because the kotlin-android plugin casts the android extension toBaseExtension, which the new DSL drops. #3964 took that opt-out so the version bump stayed reviewable. AGP 10 removes the opt-out, so the migration has to happen regardless; doing it separately keeps the two diffs legible.Description
Four things blocked the migration, each hidden behind the previous.
The old DSL extension types are gone.
com.android.build.gradle.BaseExtensionandcom.android.build.gradle.LibraryExtensiondo not exist once the new DSL is active. The convention plugins now configurecom.android.build.api.dsl.ApplicationExtensionandcom.android.build.api.dsl.LibraryExtension, and setcompileSdkdirectly rather than callingcompileSdkVersion().KotlinAndroidProjectExtensionstays as is: AGP's built-in Kotlin still registers it.safeargs 2.5.3 cannot see AGP 9. It fails with
safeargs plugin must be used with android plugin, because its detection goes through the old DSL. The 2.5.3 jar referencescom/android/build/gradle/BaseExtension,AppExtensionandgradle/api/BaseVariant; the 2.9.8 jar references onlycom.android.build.api.variant.*.examples/purchase-testeris the only module applying the plugin, and it gets its own commit.Dokka source sets changed shape. With the kotlin-android plugin, Dokka saw the Kotlin source sets and the config addressed
main,defaultsandcustomEntitlementComputation. Built-in Kotlin instead registers one source set per Android variant, and registers them after thedokka { }block runs, sonamed("defaultsRelease")throws even though the name is valid later. Both modules now select throughmatching { }.configureEach.:purchaseskeepsreportUndocumented,skipDeprecated, the Android external documentation link, both source links and thepaywalls.componentssuppression, all moved onto the selected variant. The explicitcustomEntitlementComputationsuppression is load-bearing, not redundant: Dokka defaultssuppressto!isPublishableandcustomEntitlementComputationReleaseis published, so it would otherwise be documented.kotlin-teststops carrying JUnit.:feature:galaxynameskotlin-test-junitinstead. Verified rather than inherited: with plainkotlin-test,org.junit.Testis unresolved across all 25 test methods.Not visible in the diff:
./gradlew :dokkaGeneratefails on the base commit withDokka cannot generate documentation for Android projects with multiple enabled variants that have common source roots. Thedocs-deployjob that runs it is gated on release tags, so #3964 never exercised it. This PR is what makes it pass again, which is a bigger deal than the diff makes it look.Worth noting separately: AGP 9.2.1 declares
kotlin-gradle-plugin:2.2.10, so built-in Kotlin takes its compiler from buildscript classpath resolution rather than from our catalog. Confirmed the published contract from #3964 is intact rather than assumed:2.2.21, not AGP's bundled2.2.10:purchasesPOMkotlin-stdlib:2.2.21atcompilescopemv=[1,8,0], solanguageVersion1.8 survivesRegression gates
./gradlew :dokkaGeneratefor the Dokka rework. Generates 1367 pages withcom.revenuecat.purchases.paywalls.componentsstill suppressed.:feature:galaxy:testDefaultsDebugUnitTestfor thekotlin-test-junitswap. Needs--rerun-tasks: a cached run passes even with the dependency reverted, which is how this could slip through.:examples:purchase-tester:assembleDebugfor the navigation bump.Rejected:
ANDROID_VARIANT_TO_PUBLISHinstead of hardcoding"defaultsRelease"twice.fastlane/Fastfile:295rewrites that property per publish, so acustomEntitlementComputationpublish would point Dokka at exactly the variant:purchasessuppresses.ConfigureDokka.kt. Dokka's types are not on build-logic's compile classpath, so it needs the reflection pattern fromConfigureMetalava.kt, and sharingreportUndocumented.set(true)would newly turn it on for the four public-library modules that have nodokka { }block.revenuecat-android-application, which would collapse 5 of the 6 per-module edits. Each keeps 2 to 3 overrides, and bothtestpurchases*modules deliberately pin oldcompileSdk/targetSdkto test compatibility. Worth a separate PR, not this one.Limitations:
examples/MagicWeatherandtest-apps/sdksizetestingstill applykotlin-android. They are separate builds pinned to AGP 8.13.2, so they keep the plugin correctly and are untouched.purchases/build.gradle.kts:120has a deadandroidComponents { onVariants }block guarding a"free"product flavor that does not exist in the repo. Pre-existing and unrelated, left alone.Note
Medium Risk
Wide Gradle/AGP convention changes affect every Android module’s compile and doc generation; navigation and Dokka behavior are prerequisites for CI release docs, with limited runtime SDK impact.
Overview
Completes the AGP 9 migration by removing the
android.builtInKotlin=false/android.newDsl=falseopt-outs and droppingorg.jetbrains.kotlin.androidacross convention plugins, app modules, samples, and the version catalog.Build-logic now configures
ApplicationExtension/LibraryExtensionfrom the new DSL (e.g.compileSdkinstead ofBaseExtension).:purchasesand:ui:revenuecatuiDokka blocks usematching { }.configureEachso documentation targetsdefaultsReleaseand suppressescustomEntitlementComputationvariants after AGP registers per-variant source sets lazily.androidx.navigationis bumped 2.5.3 → 2.9.8 so Safe Args works with the new DSL.:feature:galaxyswitches unit tests tokotlin-test-junit.ui/debugview/api.txtdropsInternalDebugRevenueCatScreenViewModelFactory(debug-only; not in the release API Metalava analyzes).Reviewed by Cursor Bugbot for commit e45c589. Bugbot is set up for automated code reviews on this repo. Configure here.