--- a/buildSrc/src/main/kotlin/AndroidPlayStorePublisher.kt Mon Mar 09 14:41:46 2026 -0400
+++ b/buildSrc/src/main/kotlin/AndroidPlayStorePublisher.kt Mon Mar 09 16:20:21 2026 -0400
@@ -21,7 +21,7 @@
*/
package com.geekorum.build
-import com.android.build.gradle.AppExtension
+import com.android.build.api.dsl.ApplicationExtension
import com.github.triplet.gradle.play.PlayPublisherExtension
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
@@ -47,7 +47,7 @@
serviceAccountCredentials.set(file(properties["PLAY_STORE_JSON_KEY_FILE"]!!))
}
- val android = the<AppExtension>() as ExtensionAware
+ val android = the<ApplicationExtension>() as ExtensionAware
tasks.apply {
register("publishToGooglePlayStore") {
--- a/buildSrc/src/main/kotlin/AndroidSigning.kt Mon Mar 09 14:41:46 2026 -0400
+++ b/buildSrc/src/main/kotlin/AndroidSigning.kt Mon Mar 09 16:20:21 2026 -0400
@@ -21,22 +21,17 @@
*/
package com.geekorum.build
-import com.android.build.api.dsl.*
+import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.Project
-private typealias AppExtensionWithSigning = CommonExtension<*, ApplicationBuildType, *, *, *, *>
-private typealias LibExtensionWithSigning = CommonExtension<*, LibraryBuildType, *, *, *, *>
-private typealias TestExtensionWithSigning = CommonExtension<*, TestBuildType, *, *, *, *>
-// TODO This implicitly supports only the AppPlugin
-// should we support other android plugins: LibraryPlugin TestPlugin ?
internal fun Project.configureReleaseSigningConfig() {
val releaseStoreFile = findProperty("RELEASE_STORE_FILE") as? String ?: ""
val releaseStorePassword = findProperty("RELEASE_STORE_PASSWORD") as? String ?: ""
val releaseKeyAlias= findProperty("RELEASE_KEY_ALIAS") as? String ?: ""
val releaseKeyPassword= findProperty("RELEASE_KEY_PASSWORD") as? String ?: ""
- extensions.configure<AppExtensionWithSigning>("android") {
+ extensions.configure<ApplicationExtension>("android") {
signingConfigs {
register("release") {
storeFile = file(releaseStoreFile)
--- a/buildSrc/src/main/kotlin/AndroidTests.kt Mon Mar 09 14:41:46 2026 -0400
+++ b/buildSrc/src/main/kotlin/AndroidTests.kt Mon Mar 09 16:20:21 2026 -0400
@@ -21,10 +21,9 @@
*/
package com.geekorum.build
+import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
-import com.android.build.api.dsl.DefaultConfig
-import com.android.build.gradle.BaseExtension
-import com.android.build.gradle.internal.dsl.TestOptions
+import com.android.build.api.dsl.LibraryExtension
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.DependencyConstraint
@@ -33,28 +32,37 @@
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.kotlin.dsl.*
-const val espressoVersion = "3.5.1"
-const val androidxTestRunnerVersion = "1.5.2"
-const val androidxTestCoreVersion = "1.5.0"
-const val robolectricVersion = "4.10.2"
+const val espressoVersion = "3.6.1"
+const val androidxTestRunnerVersion = "1.6.2"
+const val androidxTestCoreVersion = "1.6.1"
+const val robolectricVersion = "4.14.1"
-private typealias BaseExtension = CommonExtension<*, *, DefaultConfig, *, *, *>
/*
* Configuration for espresso and robolectric usage in an Android project
*/
-@Suppress("UnstableApiUsage")
internal fun Project.configureTests() {
- extensions.configure<BaseExtension>("android") {
- defaultConfig {
+ extensions.configure<CommonExtension>("android") {
+ if (this is ApplicationExtension) {
+ defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- testInstrumentationRunnerArguments += mapOf(
- "clearPackageData" to "true",
- "disableAnalytics" to "true"
- )
+ testInstrumentationRunnerArguments += mapOf(
+ "clearPackageData" to "true",
+ "disableAnalytics" to "true"
+ )
+ }
+ }
+ if (this is LibraryExtension) {
+ defaultConfig {
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunnerArguments += mapOf(
+ "clearPackageData" to "true",
+ "disableAnalytics" to "true"
+ )
+ }
}
- testOptions {
+ testOptions.apply {
execution = "ANDROIDX_TEST_ORCHESTRATOR"
animationsDisabled = true
@@ -64,20 +72,20 @@
}
}
-
dependencies {
dualTestImplementation(kotlin("test-junit"))
- androidTestUtil("androidx.test:orchestrator:1.4.2")
+ androidTestUtil("androidx.test:orchestrator:1.5.1")
androidTestImplementation("androidx.test:runner:$androidxTestRunnerVersion")
- dualTestImplementation("androidx.test.ext:junit-ktx:1.1.1")
+ dualTestImplementation("androidx.test.ext:junit-ktx:1.2.1")
dualTestImplementation("androidx.test:core-ktx:$androidxTestCoreVersion")
- dualTestImplementation("androidx.test:rules:1.5.0")
+ dualTestImplementation("androidx.test:rules:1.6.1")
+
// fragment testing is usually declared on debugImplementation configuration and need these dependencies
constraints {
debugImplementation("androidx.test:core:$androidxTestCoreVersion")
- debugImplementation("androidx.test:monitor:$androidxTestRunnerVersion")
+ debugImplementation("androidx.test:monitor:1.7.2")
}
dualTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
@@ -87,12 +95,12 @@
dualTestImplementation("androidx.test.espresso:espresso-intents:$espressoVersion")
// assertions
- dualTestImplementation("com.google.truth:truth:1.0")
- dualTestImplementation("androidx.test.ext:truth:1.3.0-alpha01")
+ dualTestImplementation("com.google.truth:truth:1.4.4")
+ dualTestImplementation("androidx.test.ext:truth:1.6.0")
// mock
- testImplementation("io.mockk:mockk:1.13.5")
- androidTestImplementation("io.mockk:mockk-android:1.13.5")
+ testImplementation("io.mockk:mockk:1.13.8")
+ androidTestImplementation("io.mockk:mockk-android:1.13.8")
testImplementation("org.robolectric:robolectric:$robolectricVersion")
constraints {
--- a/buildSrc/src/main/kotlin/RepositoryChangeset.kt Mon Mar 09 14:41:46 2026 -0400
+++ b/buildSrc/src/main/kotlin/RepositoryChangeset.kt Mon Mar 09 16:20:21 2026 -0400
@@ -42,7 +42,12 @@
internal fun ExecOperations.getHgSha1(projectDir: File): String? = runCommand("hg id --debug -i -r .", workingDir = projectDir)?.trim()
-internal fun ExecOperations.getHgLocalRevisionNumber(projectDir: File): String? = runCommand("hg id -n -r .", workingDir = projectDir)?.trim()
+internal fun ExecOperations.getHgLocalRevisionNumber(projectDir: File): String? {
+ val hg = File(projectDir, ".hg")
+ return if (hg.exists()) {
+ runCommand("hg id -n -r .", workingDir = projectDir)?.trim()
+ } else null
+}
private fun ExecOperations.getChangeSet(projectDir: File): String {
val git = File(projectDir, ".git")
@@ -132,7 +137,7 @@
val mainOutput = it.outputs.single { it.outputType == OutputType.SINGLE }
// create version Code generating task
- val versionCodeTask = project.tasks.register<VersionCodeTask>("computeVersionCodeFor${it.name.replaceFirstChar { it.titlecase() }}") {
+ val versionCodeTask = project.tasks.register<VersionCodeTask>("computeVersionCodeFor${it.name.capitalized()}") {
this.major.set(major)
this.minor.set(minor)
this.patch.set(patch)
@@ -154,3 +159,5 @@
})
}
}
+
+private fun String.capitalized() = replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
--- a/geekdroid-firebase/build.gradle.kts Mon Mar 09 14:41:46 2026 -0400
+++ b/geekdroid-firebase/build.gradle.kts Mon Mar 09 16:20:21 2026 -0400
@@ -1,6 +1,5 @@
plugins {
id("com.android.library")
- kotlin("android")
id("com.geekorum.build.android-tests")
id("com.geekorum.build.android-avdl")
`maven-publish`
@@ -18,7 +17,7 @@
buildTypes {
getByName("release") {
isMinifyEnabled = false
- proguardFiles(getDefaultProguardFile("proguard-android.txt"),
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")
}
}
--- a/geekdroid/build.gradle.kts Mon Mar 09 14:41:46 2026 -0400
+++ b/geekdroid/build.gradle.kts Mon Mar 09 16:20:21 2026 -0400
@@ -21,12 +21,11 @@
*/
plugins {
id("com.android.library")
- kotlin("android")
- kotlin("kapt")
id("com.geekorum.build.android-tests")
id("com.geekorum.build.android-avdl")
`maven-publish`
alias(libs.plugins.compose.compiler)
+ alias(libs.plugins.kotlin.ksp)
}
@@ -42,7 +41,7 @@
buildTypes {
getByName("release") {
isMinifyEnabled = false
- proguardFiles(getDefaultProguardFile("proguard-android.txt"),
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")
}
}
@@ -88,7 +87,7 @@
api(libs.okhttp)
implementation(libs.dagger.compiler)
- kapt(libs.dagger.compiler)
+ ksp(libs.dagger.compiler)
implementation(platform(libs.kotlinx.coroutines.bom))
implementation(libs.kotlinx.coroutines.core)
--- a/gradle/libs.versions.toml Mon Mar 09 14:41:46 2026 -0400
+++ b/gradle/libs.versions.toml Mon Mar 09 16:20:21 2026 -0400
@@ -1,5 +1,5 @@
[versions]
-android-gradle-plugin = "8.13.0"
+android-gradle-plugin = "9.1.0"
annotation = "1.9.1"
androidx-activity = "1.12.4"
androidx-compose-bom = "2026.02.01"
@@ -12,6 +12,7 @@
firebase-bom = "34.10.0"
fragment = "1.8.9"
kotlin = "2.2.20"
+kotlin-ksp = "2.3.5"
kotlinx-coroutines-bom = "1.10.2"
lifecycle = "2.10.0"
material = "1.13.0"
@@ -29,6 +30,7 @@
android-application = { id = "com.android.application", version.ref = "android-gradle-plugin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+kotlin-ksp = { id = "com.google.devtools.ksp", version.ref = "kotlin-ksp" }
[libraries]
--- a/gradle/wrapper/gradle-wrapper.properties Mon Mar 09 14:41:46 2026 -0400
+++ b/gradle/wrapper/gradle-wrapper.properties Mon Mar 09 16:20:21 2026 -0400
@@ -1,6 +1,6 @@
#Sat May 06 19:25:31 AST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists