Build modernization: Gradle 9.5, AGP 9.2, Kotlin 2.3, and tooling updates#736
Build modernization: Gradle 9.5, AGP 9.2, Kotlin 2.3, and tooling updates#736solcott wants to merge 27 commits into
Conversation
|
Looks like the following github actions are not on your orgs allow list: softprops/action-gh-release@v2 — used in create_swift_package.yml. Used for KMMBridge publishing. It looks like the Create Swift Package action has never been run. If you don't think it will be run in the future I can remove the KMMBridge support as well as create_swift_package.yml where these actions are used. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #736 +/- ##
=======================================
Coverage 80.17% 80.17%
=======================================
Files 42 42
Lines 928 928
Branches 177 177
=======================================
Hits 744 744
Misses 110 110
Partials 74 74 🚀 New features to boost your workflow:
|
15ad958 to
3c8f67c
Compare
|
Hi @matt-ramotar, friendly nudge on this one. I know it landed out of the blue as one big PR, and a 30-file toolchain/CI/publishing change is a lot to take on in one review, so I'm happy to make it easier to digest. I rebased onto current main today. It's mergeable and CI is running clean, so there's nothing broken or behind to untangle here, it just needs a look. If the size is the sticking point, I can split it into small, independently-reviewable PRs, each green on its own, in a low-risk-first order:
Would that split be easier to review, or would you rather take it as one PR? Just tell me the format you prefer and I'll deliver it that way. (Also still flagging the two Actions not on the org allow-list — softprops/action-gh-release@v2 and touchlab/ga-update-release-tag@v1 — both only used by the KMMBridge workflow in #7, so they go away if you skip that piece.) |
There was a problem hiding this comment.
Can you re-run apiDump - I would have expected the Android dumps to regenerate too
There was a problem hiding this comment.
The jvm() and android targets use different compilation backends with different -jvm-default modes.
Kotlin 2.2 changed the default -jvm-default from disable to enable. Under enable, an interface method with a default body (getAllPresent()) is emitted as a real JVM default method — non-abstract in the dump, with DefaultImpls kept for compat. The jvm() target picked this up on the Kotlin bump; the android target (compiled by AGP) pins its own mode and stayed on the old abstract + DefaultImpls shape.
Three ways to reconcile, your call:
- disable on JVM → both revert to abstract + DefaultImpls.
- enable on Android → both match the new JVM shape (real default method + DefaultImpls).
- no-compatibility on both → both drop DefaultImpls, real default method only.
The last two emit real interface default methods, which Android supports at API 24+ — safe since minSdk = 24.
| permissions: | ||
| contents: read | ||
| checks: write | ||
| pull-requests: write |
There was a problem hiding this comment.
Let's revert this if it's not being used
There was a problem hiding this comment.
Looks like I removed the action that required these. I'll remove.
There was a problem hiding this comment.
Why is there not a KMMBridge-Debug.yml / KMMBridge-Release.yml?
There was a problem hiding this comment.
Good call on the naming — I've renamed KMMBridge-Publish.yml → KMMBridge-Release.yml to make the intent explicit. It's now based on KMMBridge's new recommended flow ([Base-Publish.yml](https://github.com/touchlab/KMMBridgeSPMQuickStart/blob/main/.github/workflows/Base-Publish.yml)), since a lot changed since the version we previously used.
There's no KMMBridge-Debug.yml because only release is something we distribute:
- The SPM
Package.swiftbinary target can point at one XCFramework URL per tag, so a separate debug variant isn't independently consumable — a second publish would just overwrite the manifest. - Debug XCFrameworks are a local dev concern. When you need to step through Kotlin from Xcode, KMMBridge builds one on demand via
./gradlew store:spmDevBuild, which rewritesPackage.swiftto a local path — no CI or Release upload. So a debug workflow would have nothing to publish.
I've also fixed the stale line-1 comment that claimed it published "both debug and release."
| sourceSets.getByName("nativeMain") { dependencies { api(atomicFuDep) } } | ||
| sourceSets.getByName("jsMain") { dependencies { api(atomicFuDep) } } | ||
| sourceSets.getByName("wasmJsMain") { dependencies { api(atomicFuDep) } } |
There was a problem hiding this comment.
Why is this needed? All consumers of core would gain a transitive dependency. If this is needed for klib linking in cache/multicast, let's scope it to those modules (or their own build files)
There was a problem hiding this comment.
Looks like this isn't needed anymore with newer versions of the atomicfu gradle plugin. I can see them being added as dependencies to jsApiElements-published and jsRuntimeElements-published in the published gradle .module file. I'll remove this.
|
Hey @solcott - thanks for doing this. Sorry to be slow. On board with general direction. Left a few questions/comments. 1 more - can you update the PR description? I see a few things are stale
|
|
Updated the version - #742 |
… to 1.0.0 * Upgrade Gradle from 8.6 to 8.14.4 * Upgrade `org.gradle.toolchains.foojay-resolver-convention` from 0.8.0 to 1.0.0 Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Upgrade `actions/checkout` to v6 * Upgrade `actions/setup-java` to v5 * Migrate `gradle/gradle-build-action@v3` to `gradle/actions/setup-gradle@v6` * Upgrade `codecov/codecov-action` to v6 Signed-off-by: Scott Olcott <scottolcott@gmail.com>
The dependency is already added by Kotlin Target Hierarchy template Signed-off-by: Scott Olcott <scottolcott@gmail.com>
Signed-off-by: Scott Olcott <scottolcott@gmail.com>
Defining disabled rules was deprecated in build.gradle.kts files Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Migrate deprecated `kotlinOptions` to `compilerOptions` using `JvmTarget.JVM_11` in `build.gradle.kts` * Add `browser()` target to the `wasmJs` configuration block * Defer Kotlin compiler options configuration by using `compileTaskProvider.configure` for multiplatform and native targets * Add explicit `kotlinx-atomic-fu` dependencies to `nativeMain`, `jsMain`, and `wasmJsMain` source sets via the version catalog * Fix minor spacing formatting in `configureCocoapods` Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Add `updateDaemonJvm` task configuration in `build.gradle.kts` to target Java 17 and the Azul vendor * Add `gradle/gradle-daemon-jvm.properties` with platform-specific toolchain URLs generated by the task Signed-off-by: Scott Olcott <scottolcott@gmail.com>
Replace hardcoded JVM, SDK, and dependency versions with version catalog
references throughout the build scripts and convention plugins.
Introduce jvmToolchain=17 and jvmCompat=11 version catalog entries to
clearly separate toolchain from target compatibility: the Gradle daemon
and Java/Kotlin compilers run on JDK 17, while compiled bytecode targets
JVM 11 for downstream consumer compatibility.
Version catalog (libs.versions.toml):
- Bump androidCompileSdk/targetSdk 33 -> 34
- Bump androidGradlePlugin 8.0.0 -> 8.2.2
- Bump atomicFu 0.24.0 -> 0.26.1
- Bump dokkaGradlePlugin 1.9.20 -> 2.2.0
- Bump ktlintGradle 12.1.0 -> 12.3.0
- Bump jacocoGradlePlugin 0.8.12 -> 0.8.14
- Bump mavenPublishPlugin 0.34.0 -> 0.35.0
- Bump spotlessPluginGradle 6.4.1 -> 8.5.1
- Bump testCore 1.6.1 -> 1.7.0
- Bump kover 0.9.0-RC -> 0.9.8
- Bump truth 1.1.3 -> 1.4.5
- Bump binary-compatibility-validator 0.15.0-Beta.2 -> 0.18.1
- Add jvmToolchain (17) and jvmCompat (11) version entries
- Add spotless plugin alias
- Remove unused molecule and paging dependencies
Convention plugins:
- Add VersionCatalogExt.kt with typed accessors for version catalog
entries (jvmToolchain, jvmCompat, store, SDK versions)
- Replace hardcoded Versions object and magic numbers with version
catalog lookups in AndroidConventionPlugin and
KotlinMultiplatformConventionPlugin
- Wire jvmToolchain for compiler toolchain resolution (JDK 17) and
jvmCompat for sourceCompatibility/targetCompatibility (JVM 11)
- Migrate to Dokka 2.x API (DokkaExtension replaces DokkaTask)
- Add ktlint plugin and configure rules to preserve single-line
expression-body style (= with(project) {)
Root build.gradle.kts:
- Use version catalog alias for spotless plugin
- Derive JVM target/compatibility from libs.versions.jvmCompat
tooling/plugins/build.gradle.kts:
- Add ktlint plugin with rule overrides for expression-body formatting
- Derive Java/Kotlin JVM settings from version catalog
Signed-off-by: Scott Olcott <scottolcott@gmail.com>
…endencies
* Upgrade Gradle to 9.5.1 and Kotlin to 2.3.21
* Migrate from `com.android.library` to `com.android.kotlin.multiplatform.library` in convention plugins
* Enable Gradle configuration cache and disable configure-on-demand in `gradle.properties`
* Update coroutines testing API from `TestCoroutineScope` to `TestScope` and `runTest`
* Remove redundant `AndroidManifest.xml` files and centralize Android namespace configuration in convention plugins
* Add `-Xcontext-parameters` Kotlin compiler argument in tooling:plugin module
* Upgrade various dependencies:
* Android Gradle Plugin to 9.2.1
* Coroutines and Serialization to 1.11.0
* AtomicFU to 0.32.1
* Ktlint to 1.8.0 (plugin to 14.2.0)
* Update `configureAndroid` to use context receivers and the new `KotlinMultiplatformAndroidLibraryTarget` configuration block
* Temporarily comment out `kmmBridge` plugin and related configurations
Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Add `KMMBridge-Debug.yml` and `KMMBridge-Release.yml` workflows to trigger manual SPM builds * Update `create_swift_package.yml` to a reusable `workflow_call` that handles JDK 17 setup, GitHub releases, and `kmmBridgePublish` execution * Upgrade KMMBridge to version 1.2.1 and migrate plugin coordinates from `co.touchlab.faktory` to `co.touchlab.kmmbridge.github` * Enable and configure the KMMBridge plugin with SPM support in `KotlinMultiplatformConventionPlugin.kt` * Update `VERSION_NAME` to `5.1.0-SNAPSHOT` in `gradle.properties` * Uncomment KMMBridge dependencies in `build.gradle.kts` and tooling plugin configurations Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Move repository definitions to `dependencyResolutionManagement` and `pluginManagement` in `settings.gradle` * Replace legacy `buildscript` classpath dependencies with Version Catalog plugin aliases in `build.gradle.kts` * Remove redundant `allprojects` repository block * Update `libs.versions.toml` to include comprehensive plugin definitions and remove unused library entries * Fix typo in `updateDaemonJvm` task comment Signed-off-by: Scott Olcott <scottolcott@gmail.com>
Signed-off-by: Scott Olcott <scottolcott@gmail.com>
…upload * Add `contents: read`, `checks: write`, and `pull-requests: write` permissions to the `build-and-test` job * Add `--continue` flag to the Gradle build command to ensure all tests are executed * Add `mikepenz/action-junit-report@v5` step to publish test results * Restrict Codecov upload step to the `MobileNativeFoundation/Store` repository via an `if` condition Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Configure the `browser` target to use Karma with Chrome Headless * Set a 5s timeout for Mocha in both `browser` and `nodejs` test tasks Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Add `contents: write` and `packages: write` permissions to the `call-publish` job in `KMMBridge-Debug.yml` and `KMMBridge-Release.yml` Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Add `ENABLE_PUBLISHING=true` project property to the `create_swift_package.yml` workflow * Call `gitHubReleaseArtifacts()` within the KmmBridge configuration in `KotlinMultiplatformConventionPlugin` Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Remove `mikepenz/action-junit-report` step from `.github/workflows/ci.yml` Signed-off-by: Scott Olcott <scottolcott@gmail.com>
Replace the separate debug/release dispatch workflows with a single KMMBridge-Publish workflow that publishes the release XCFramework. This removes the artifact-name collision that occurred when running both for the same version. For debugging Kotlin from Xcode, use KMMBridge local/dev publishing instead. Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Upgrade Gradle distribution to 9.6.1 in `gradle-wrapper.properties` * Add `distributionSha256Sum` to verify the Gradle distribution * Configure `retries` and `retryBackOffMs` properties for distribution downloads * Update `gradlew` and `gradlew.bat` scripts to the latest version, removing redundant `CLASSPATH` logic and improving shell environment handling Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Update `mavenPublishPlugin` to `0.37.0` * Update `spotlessPluginGradle` to `8.8.0` Signed-off-by: Scott Olcott <scottolcott@gmail.com>
…ionPlugin` * This is not needed for js, wasm and native sourceSets with newer versions of the atomicfu gradle plugin Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Update `androidGradlePlugin` to 9.3.0 in `libs.versions.toml` * Update `kover` to 0.9.9 in `libs.versions.toml` Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* No longer needed now that action-junit-report is not used Signed-off-by: Scott Olcott <scottolcott@gmail.com>
* Rename `.github/workflows/KMMBridge-Publish.yml` to `KMMBridge-Release.yml` * Update workflow descriptions to focus on publishing release XCFrameworks only * Update instructions to recommend `./gradlew <module>:spmDevBuild` for local Kotlin debugging in Xcode instead of CI-based publishing Signed-off-by: Scott Olcott <scottolcott@gmail.com>
|
I believe I have updated everything base on your comments. Should I update to the latest Kotlin: After updating Kotlin from |
Define the published version in a single place — gradle/libs.versions.toml (store) — instead of duplicating it in gradle.properties as VERSION_NAME. - Remove VERSION_NAME from gradle.properties; keep GROUP and POM_* metadata. - Apply the catalog version to project.version in KotlinMultiplatformConventionPlugin so the vanniktech maven-publish version (via its project.version fallback) and the CocoaPods podspec version share one source of truth. - Point the CI version lookups (ci.yml, create_swift_package.yml) at the catalog with a whitespace-tolerant grep instead of gradle.properties. - Bump store 5.1.0-alpha10 -> 5.1.0-SNAPSHOT. Verified project.version and the generated js/jvm/kotlinMultiplatform/android POMs all resolve to 5.1.0-SNAPSHOT. Signed-off-by: Scott Olcott <scottolcott@gmail.com>
|
|
||
| # POM file | ||
| GROUP=org.mobilenativefoundation.store | ||
| VERSION_NAME=5.1.0-SNAPSHOT |
There was a problem hiding this comment.
I consolidated the project version to libs.versions.toml in 6b18ec7. Let me know if this works for you.
|
@solcott Thanks again for this contribution, Scott. I did some digging and it looks like this is an issue with BCV. I reported it here and flagged to Kotlin team - Kotlin/binary-compatibility-validator#315. There's no clean fix on Kotlin 2.3.21, so let's delete api/android/*.api in store, cache, core, and multicast, and note the coverage change in the PR body. The jvm dumps are a faithful interim proxy since both targets compile the same source with the same compiler and mode. Really appreciate the modernization help |
Let's keep it at 2.3.21
We can do it in a separate PR |
After the AGP 9 KMP Android library migration, binary-compatibility-validator no longer registers API tasks for the Android target (upstream limitation, Kotlin/binary-compatibility-validator#315), so it neither generates nor checks api/android/*.api. Remove the now-orphaned dumps for store, cache, core, and multicast. The JVM and klib dumps are still validated; the JVM dump serves as a proxy for the Android ABI since both compile the same common source. Signed-off-by: Scott Olcott <scottolcott@gmail.com>
Applying plugins to other projects via the root `subprojects {}` block is
deprecated (cross-project configuration is incompatible with project
isolation and the configuration cache). Replace it with a dedicated
FormattingConventionPlugin (org.mobilenativefoundation.store.formatting)
that each project applies to itself.
Move the ktlint + spotless configuration out of the root build.gradle.kts
`subprojects {}` block into the new plugin, and apply it from both the
Kotlin Multiplatform and Android convention plugins so every module shares
one formatting definition.
- Add ktlint/spotless gradle-plugin catalog entries and compileOnly deps to
the build-logic project, and register the new plugin id.
- Remove the now-redundant subprojects formatting block from build.gradle.kts.
Signed-off-by: Scott Olcott <scottolcott@gmail.com>
|
I removed the android .api files in core, cache. multicast, and store modules and updated the PR body. I also made one last change in 9805deb to migrate away from applying plugins in |
Overview
This PR modernizes the build infrastructure across the board — toolchain upgrades,
configuration cache adoption, CI improvements, and migration to current plugin APIs.
Changes
Gradle & Toolchain
gradle/gradle-daemon-jvm.propertiespinning the daemon to Azul JDK 17org.gradle.configuration-cache=true)configureondemand(incompatible with configuration cache)updateDaemonJvmtask configured for JDK 17 / AzulDependency & Plugin Updates
com.android.kotlin.multiplatform.libraryplugin)DokkaExtensionAPI)co.touchlab.kmmbridge.githubplugin)Build Script Modernization
buildscript {}block — all plugins now declared viaalias(libs.plugins.*)in the rootbuild.gradle.ktslibs.versions.tomlVersionCatalogExt.ktwith typed accessors for version catalog values (JVM toolchain, compat version, SDK levels, store version), replacing the hardcodedVersionsobjectjvmToolchain = 17,jvmCompat = 11)configureAndroid()updated for the new multiplatform Android library plugin API (namespace,withHostTest/withDeviceTest, compiler options)android { namespace = ... }andAndroidManifest.xmlfromcache,core, andmulticast— namespace now set centrally in the convention pluginsourceSets { val x by getting { } }tosourceSets { x { } }idiom across submodulesFormattingConventionPlugin(org.mobilenativefoundation.store.formatting) applied per-module, replacing the deprecated cross-projectsubprojects {}plugin application in the rootbuild.gradle.ktsCI / GitHub Actions
actions/checkoutv4 → v6actions/setup-javav4 → v5gradle/gradle-build-action→gradle/actions/setup-gradle@v6codecov/codecov-actionv4 → v6permissionsblock to CI job (least-privilege:contents: read,checks: write,pull-requests: write)--continueflag to build step so all module failures are reported in one runcreate_swift_package.yml/ KMMBridge workflow based on current KMMBridgeSPMQuickStart template; addedKMMBridge-Release.ymldispatch workflowAPI Validation
After migrating to the AGP 9 KMP Android library plugin, binary-compatibility-validator no longer registers any API tasks for the Android target (upstream limitation — Kotlin/binary-compatibility-validator#315). BCV neither generates nor checks
api/android/*.api, so the previously committed dumps forstore,cache,core, andmulticastare stale, orphaned files. They have been removed.Coverage note: the Android target is not independently ABI-validated. The JVM and klib (ios/js/linux/wasm) dumps are still generated and checked, and the JVM dump is a faithful proxy for the Android ABI since both compile the same common source. Android validation can be restored once BCV supports the AGP 9 KMP Android target.
Lint / Style
.editorconfigdisablingktlint_standard_import-orderingfor Kotlin filesadditionalEditorconfigrules to suppress several noisy checks project-wideOther
rx2: migrated deprecatedTestCoroutineScope→TestScopecacheAPI:getAllPresent()now compiles to a default interface method on the JVM (Kotlin 2.2+jvm-defaultdefault change), reflected in the updated JVM.apidumpgradle.properties: removed deprecatedkotlin.js.compiler=irgradle/libs.versions.toml(store); removedVERSION_NAMEfromgradle.propertiesand pointed the CI version lookups at the catalog