From 0defaf05869dbede93b960becf5b3513dbd98ff7 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 20 Jul 2026 17:51:29 -0400 Subject: [PATCH 1/2] build(deps): bump kotlin to 2.4.10 and coil to 3.5.0 Combines Dependabot PRs #1087 (kotlin 2.3.21 -> 2.4.10) and #947 (compose-coil 3.4.0 -> 3.5.0), which were held back individually. Kotlin 2.4.0 promotes the Compose compiler plugin's singular `stabilityConfigurationFile` (RegularFileProperty) to an ERROR-level deprecation in favor of the plural `stabilityConfigurationFiles` (ListProperty). Migrate both usages accordingly. KSP is left at 2.3.10: it compiles cleanly under Kotlin 2.4.10 across all kspDebugKotlin tasks (Hilt, Room, FeatureFlagProcessor) with no compatibility warning. Coil 3.5.0 needs no source changes. Verified: :apps:flipcash:app:assembleDebug succeeds and the debug APK launches and renders on-device (Maestro launch + login navigation). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DgP1XtH7buYQ5bFPN9uU3v --- apps/flipcash/app/build.gradle.kts | 2 +- .../src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt | 2 +- gradle/libs.versions.toml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/flipcash/app/build.gradle.kts b/apps/flipcash/app/build.gradle.kts index 60f10da4d6..8123d0f514 100644 --- a/apps/flipcash/app/build.gradle.kts +++ b/apps/flipcash/app/build.gradle.kts @@ -136,7 +136,7 @@ bugsnag { composeCompiler { // Isolated Projects-safe root access (see AndroidLibraryComposeConventionPlugin). - stabilityConfigurationFile.set( + stabilityConfigurationFiles.add( isolated.rootProject.projectDirectory.file("compose_compiler_config.conf") ) } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt index d093322f91..d83836cd83 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt @@ -26,7 +26,7 @@ class AndroidLibraryComposeConventionPlugin : Plugin { // `rootProject.layout` reaches into another project's model, which // Isolated Projects forbids; `isolated.rootProject` is the blessed // read-only view that exposes the root project directory safely. - stabilityConfigurationFile.set( + stabilityConfigurationFiles.add( isolated.rootProject.projectDirectory.file("compose_compiler_config.conf") ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9215f9cf0b..df7253caaf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ android-minSdk = "29" android-targetSdk = "37" android-java = "21" -kotlin = "2.3.21" +kotlin = "2.4.10" ksp = "2.3.10" kotlinx-coroutines = "1.11.0" kotlinx-serialization = "1.11.0" @@ -41,7 +41,7 @@ compose-view-models = "2.11.0" compose-paging = "3.5.0" compose-webview = "2.0.3" compose-accompanist = "0.36.0" -compose-coil = "3.4.0" +compose-coil = "3.5.0" hilt = "2.59.2" hilt-jetpack = "1.4.0" From fd94e5426fbe9b9665dba45e387288c63d8e6def Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 20 Jul 2026 18:09:35 -0400 Subject: [PATCH 2/2] test: fix always-false `is` checks rejected by Kotlin 2.4 Kotlin 2.4's control-flow analysis promotes "Check for instance is always 'false'" from a warning to a compile error. Two tests assert that specific sealed-error leaf types are NOT NotifiableError, using an `is` check the compiler can now prove is statically false (the leaf types don't implement the interface). Widen the reference to the sealed parent (which does have a notifiable variant) so the check is legal while still verifying the runtime contract. No behavior change. - SwapErrorTest: Timeout / Terminal are not NotifiableError - CoinbaseOnRampEventHandlerTest: RegionMismatch / PaymentSheetTimeout are not NotifiableError Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DgP1XtH7buYQ5bFPN9uU3v --- .../app/onramp/internal/CoinbaseOnRampEventHandlerTest.kt | 4 ++-- .../com/getcode/opencode/model/core/errors/SwapErrorTest.kt | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/flipcash/shared/onramp/coinbase/src/test/kotlin/com/flipcash/app/onramp/internal/CoinbaseOnRampEventHandlerTest.kt b/apps/flipcash/shared/onramp/coinbase/src/test/kotlin/com/flipcash/app/onramp/internal/CoinbaseOnRampEventHandlerTest.kt index 2ed1bd32e4..96c7331c3c 100644 --- a/apps/flipcash/shared/onramp/coinbase/src/test/kotlin/com/flipcash/app/onramp/internal/CoinbaseOnRampEventHandlerTest.kt +++ b/apps/flipcash/shared/onramp/coinbase/src/test/kotlin/com/flipcash/app/onramp/internal/CoinbaseOnRampEventHandlerTest.kt @@ -295,13 +295,13 @@ class CoinbaseOnRampWebErrorTest { @Test fun guestRegionMismatchIsNotNotifiable() { - val error = CoinbaseOnRampWebError.RegionNotSupported.RegionMismatch() + val error: CoinbaseOnRampWebError = CoinbaseOnRampWebError.RegionNotSupported.RegionMismatch() assertFalse(error is NotifiableError) } @Test fun paymentSheetTimeoutIsNotNotifiable() { - val error = CoinbaseOnRampWebError.PaymentSheetTimeout() + val error: CoinbaseOnRampWebError = CoinbaseOnRampWebError.PaymentSheetTimeout() assertFalse(error is NotifiableError) } } diff --git a/services/opencode/src/test/kotlin/com/getcode/opencode/model/core/errors/SwapErrorTest.kt b/services/opencode/src/test/kotlin/com/getcode/opencode/model/core/errors/SwapErrorTest.kt index 76dcc5345c..b672936882 100644 --- a/services/opencode/src/test/kotlin/com/getcode/opencode/model/core/errors/SwapErrorTest.kt +++ b/services/opencode/src/test/kotlin/com/getcode/opencode/model/core/errors/SwapErrorTest.kt @@ -128,13 +128,14 @@ class SwapErrorTest { @Test fun timeoutIsNotNotifiable() { - assertFalse(SwapError.Timeout() is NotifiableError) + val error: SwapError = SwapError.Timeout() + assertFalse(error is NotifiableError) } @Test fun terminalIsNotNotifiableAndCarriesState() { val error = SwapError.Terminal(SwapState.CANCELLED) - assertFalse(error is NotifiableError) + assertFalse((error as SwapError) is NotifiableError) assertEquals(SwapState.CANCELLED, error.state) }