diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df7219c..3c67134 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,27 @@ jobs: with: gradle_command: test allTests + check-api: + name: Check public api + runs-on: ubuntu-24.04 + timeout-minutes: 15 + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Setup java + uses: ./.github/actions/setup_java + + - name: Gradle cache + uses: ./.github/actions/gradle_cache + with: + key: "check-api" + + - name: Run gradle + uses: ./.github/actions/run_gradle + with: + gradle_command: apiCheck + assemble: name: Assemble runs-on: ubuntu-24.04 diff --git a/build-scripts/build.gradle.kts b/build-scripts/build.gradle.kts index 39c00b7..435d26c 100644 --- a/build-scripts/build.gradle.kts +++ b/build-scripts/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { implementation(files(vsCoreLibs.javaClass.superclass.protectionDomain.codeSource.location)) implementation(vsCoreLibs.gradlePlugins.kotlin.core) + implementation(vsCoreLibs.gradlePlugins.kotlin.binaryValidator) implementation(vsCoreLibs.gradlePlugins.android) implementation(vsCoreLibs.gradlePlugins.detekt) implementation(vsCoreLibs.gradlePlugins.checkUpdates) diff --git a/build-scripts/src/main/kotlin/ru/vladislavsumin/convention/analyze/binary-validator.gradle.kts b/build-scripts/src/main/kotlin/ru/vladislavsumin/convention/analyze/binary-validator.gradle.kts new file mode 100644 index 0000000..19958e7 --- /dev/null +++ b/build-scripts/src/main/kotlin/ru/vladislavsumin/convention/analyze/binary-validator.gradle.kts @@ -0,0 +1,9 @@ +package ru.vladislavsumin.convention.analyze + +/** + * Стандартные настройки проверки бинарной совместимости публичного апи. + */ + +plugins { + id("org.jetbrains.kotlinx.binary-compatibility-validator") +} diff --git a/core/decompose/components/api/android/components.api b/core/decompose/components/api/android/components.api new file mode 100644 index 0000000..e57b0b6 --- /dev/null +++ b/core/decompose/components/api/android/components.api @@ -0,0 +1,31 @@ +public abstract class ru/vladislavsumin/core/decompose/components/Component : com/arkivanov/decompose/ComponentContext { + public fun (Lcom/arkivanov/decompose/ComponentContext;)V + protected final fun asValue (Lkotlinx/coroutines/flow/StateFlow;)Lcom/arkivanov/decompose/value/Value; + public fun getBackHandler ()Lcom/arkivanov/essenty/backhandler/BackHandler; + public fun getComponentContextFactory ()Lcom/arkivanov/decompose/ComponentContextFactory; + public fun getInstanceKeeper ()Lcom/arkivanov/essenty/instancekeeper/InstanceKeeper; + public fun getLifecycle ()Lcom/arkivanov/essenty/lifecycle/Lifecycle; + public fun getStateKeeper ()Lcom/arkivanov/essenty/statekeeper/StateKeeper; + protected final fun launch (Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun launch$default (Lru/vladislavsumin/core/decompose/components/Component;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + protected fun viewModel (Lkotlin/jvm/functions/Function0;)Lru/vladislavsumin/core/decompose/components/ViewModel; +} + +public abstract class ru/vladislavsumin/core/decompose/components/ViewModel { + public fun ()V + public final fun getStateKeeper ()Lcom/arkivanov/essenty/statekeeper/StateKeeper; + protected final fun launch (Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun launch$default (Lru/vladislavsumin/core/decompose/components/ViewModel;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + protected final fun stateIn (Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlinx/coroutines/flow/SharingStarted;)Lkotlinx/coroutines/flow/StateFlow; + public static synthetic fun stateIn$default (Lru/vladislavsumin/core/decompose/components/ViewModel;Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlinx/coroutines/flow/SharingStarted;ILjava/lang/Object;)Lkotlinx/coroutines/flow/StateFlow; +} + +public final class ru/vladislavsumin/core/decompose/components/utils/FlowUtilsKt { + public static final fun asValue (Lkotlinx/coroutines/flow/StateFlow;Lkotlinx/coroutines/CoroutineScope;)Lcom/arkivanov/decompose/value/Value; +} + +public final class ru/vladislavsumin/core/decompose/components/utils/LifecycleCoroutineScopeKt { + public static final fun createCoroutineScope (Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/CoroutineScope; + public static synthetic fun createCoroutineScope$default (Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lkotlinx/coroutines/CoroutineScope; +} + diff --git a/core/decompose/components/api/jvm/components.api b/core/decompose/components/api/jvm/components.api new file mode 100644 index 0000000..e57b0b6 --- /dev/null +++ b/core/decompose/components/api/jvm/components.api @@ -0,0 +1,31 @@ +public abstract class ru/vladislavsumin/core/decompose/components/Component : com/arkivanov/decompose/ComponentContext { + public fun (Lcom/arkivanov/decompose/ComponentContext;)V + protected final fun asValue (Lkotlinx/coroutines/flow/StateFlow;)Lcom/arkivanov/decompose/value/Value; + public fun getBackHandler ()Lcom/arkivanov/essenty/backhandler/BackHandler; + public fun getComponentContextFactory ()Lcom/arkivanov/decompose/ComponentContextFactory; + public fun getInstanceKeeper ()Lcom/arkivanov/essenty/instancekeeper/InstanceKeeper; + public fun getLifecycle ()Lcom/arkivanov/essenty/lifecycle/Lifecycle; + public fun getStateKeeper ()Lcom/arkivanov/essenty/statekeeper/StateKeeper; + protected final fun launch (Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun launch$default (Lru/vladislavsumin/core/decompose/components/Component;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + protected fun viewModel (Lkotlin/jvm/functions/Function0;)Lru/vladislavsumin/core/decompose/components/ViewModel; +} + +public abstract class ru/vladislavsumin/core/decompose/components/ViewModel { + public fun ()V + public final fun getStateKeeper ()Lcom/arkivanov/essenty/statekeeper/StateKeeper; + protected final fun launch (Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun launch$default (Lru/vladislavsumin/core/decompose/components/ViewModel;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + protected final fun stateIn (Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlinx/coroutines/flow/SharingStarted;)Lkotlinx/coroutines/flow/StateFlow; + public static synthetic fun stateIn$default (Lru/vladislavsumin/core/decompose/components/ViewModel;Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlinx/coroutines/flow/SharingStarted;ILjava/lang/Object;)Lkotlinx/coroutines/flow/StateFlow; +} + +public final class ru/vladislavsumin/core/decompose/components/utils/FlowUtilsKt { + public static final fun asValue (Lkotlinx/coroutines/flow/StateFlow;Lkotlinx/coroutines/CoroutineScope;)Lcom/arkivanov/decompose/value/Value; +} + +public final class ru/vladislavsumin/core/decompose/components/utils/LifecycleCoroutineScopeKt { + public static final fun createCoroutineScope (Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/CoroutineScope; + public static synthetic fun createCoroutineScope$default (Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lkotlinx/coroutines/CoroutineScope; +} + diff --git a/core/decompose/components/build.gradle.kts b/core/decompose/components/build.gradle.kts index 49ae48d..ff9646d 100644 --- a/core/decompose/components/build.gradle.kts +++ b/core/decompose/components/build.gradle.kts @@ -3,6 +3,7 @@ plugins { id("ru.vladislavsumin.convention.kmp.js") id("ru.vladislavsumin.convention.kmp.jvm") id("ru.vladislavsumin.convention.publication.sonatype") + id("ru.vladislavsumin.convention.analyze.binary-validator") `maven-publish` } diff --git a/libs.versions.toml b/libs.versions.toml index 10acd99..3be39ae 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -4,6 +4,7 @@ kotlin-core = "2.1.0" kotlin-coroutines = "1.10.1" kotlin-serialization = "1.7.3" +kotlin-binaryValidator = "0.17.0" gradlePlugins-android = "8.7.3" gradlePlugins-detekt = "1.23.7" @@ -14,6 +15,7 @@ decompose = "3.2.2" # Gradle Plugins gradlePlugins-kotlin-core = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-core" } +gradlePlugins-kotlin-binaryValidator = { module = "org.jetbrains.kotlinx:binary-compatibility-validator", version.ref = "kotlin-binaryValidator" } gradlePlugins-android = { module = "com.android.tools.build:gradle", version.ref = "gradlePlugins-android" } gradlePlugins-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "gradlePlugins-detekt" } gradlePlugins-checkUpdates = { module = "com.github.ben-manes:gradle-versions-plugin", version.ref = "gradlePlugins-checkUpdates" }