diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..662fc2b1 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,80 @@ +version: 2.1 + +orbs: + android: circleci/android@2.5.0 + +commands: + install-android-sdk-on-macos: + description: Install the Android SDK on macOS + steps: + - run: + name: Install Android SDK commandline tools + command: brew install --cask android-commandlinetools + - run: + name: Set Android SDK environment variables + command: | + echo 'export ANDROID_HOME="$HOMEBREW_PREFIX/share/android-commandlinetools"' >> "$BASH_ENV" + echo 'export PATH="$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH"' >> "$BASH_ENV" + - android/accept-licenses + - run: + name: Install Android SDK platform tools + command: sdkmanager "platform-tools" + require-snapshot-version: + description: Check that the current version is a SNAPSHOT version + steps: + - run: + name: Check that the current version is a SNAPSHOT version + command: | + set -euo pipefail + file_path="gradle/libs.versions.toml" + version=$(grep 'revenuecat-kmp = ' "$file_path" | awk -F ' = ' '{print $2}' | tr -d '"') + if [[ ! "$version" =~ -SNAPSHOT$ ]]; then + echo "$version is not a SNAPSHOT version. Exiting..." + exit 1 + else + echo "$version is a SNAPSHOT version. Proceeding..." + fi + +executors: + xcode15: + macos: + xcode: 15.4.0 + resource_class: macos.m1.medium.gen1 + environment: + # Avoid waiting for Homebrew to auto update existing packages, as everything we care about is + # freshly installed. + HOMEBREW_NO_AUTO_UPDATE: 1 + +jobs: + deploy-snapshot: + executor: xcode15 + steps: + - checkout + - require-snapshot-version + - install-android-sdk-on-macos + - android/restore-gradle-cache + - android/restore-build-cache + - run: + name: Set environment variables for publishing + command: | + echo 'export ORG_GRADLE_PROJECT_mavenCentralUsername="$SONATYPE_NEXUS_TOKEN_USERNAME"' >> "$BASH_ENV" + echo 'export ORG_GRADLE_PROJECT_mavenCentralPassword="$SONATYPE_NEXUS_TOKEN_PASSWORD"' >> "$BASH_ENV" + echo 'export ORG_GRADLE_PROJECT_signingInMemoryKey="$SIGNING_GPG_IN_MEMORY"' >> "$BASH_ENV" + echo 'export ORG_GRADLE_PROJECT_signingInMemoryKeyPassword="$GPG_SIGNING_KEY_PW_NEW"' >> "$BASH_ENV" + - run: + name: Publish snapshot to Maven Central + command: ./gradlew publishAllPublicationsToMavenCentralRepository + - android/save-gradle-cache + - android/save-build-cache + +workflows: + on-main: + # On all pushes to main, except when it's a scheduled pipeline. + when: + and: + - equal: [ main, << pipeline.git.branch >> ] + - not: + equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + jobs: + - deploy-snapshot: + context: maven-central-publishing diff --git a/build-logic/convention/src/main/kotlin/com/revenuecat/purchases/kmp/buildlogic/plugin/LibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/revenuecat/purchases/kmp/buildlogic/plugin/LibraryConventionPlugin.kt index 1146b9cd..4506f594 100644 --- a/build-logic/convention/src/main/kotlin/com/revenuecat/purchases/kmp/buildlogic/plugin/LibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/com/revenuecat/purchases/kmp/buildlogic/plugin/LibraryConventionPlugin.kt @@ -25,7 +25,6 @@ class LibraryConventionPlugin : Plugin { apply("dev.adamko.dokkatoo-html") apply("io.gitlab.arturbosch.detekt") apply("com.vanniktech.maven.publish") - apply("com.gradleup.nmcp") } extensions.configure { diff --git a/build.gradle.kts b/build.gradle.kts index 1823c29c..6f005fca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,9 +2,8 @@ import com.vanniktech.maven.publish.MavenPublishBaseExtension import com.vanniktech.maven.publish.MavenPublishPlugin +import com.vanniktech.maven.publish.SonatypeHost import io.gitlab.arturbosch.detekt.Detekt -import nmcp.NmcpExtension -import nmcp.NmcpPlugin import org.gradle.configurationcache.extensions.capitalized plugins { @@ -19,45 +18,27 @@ plugins { alias(libs.plugins.adamko.dokkatoo.html) alias(libs.plugins.arturbosch.detekt).apply(false) alias(libs.plugins.vanniktech.mavenPublish).apply(false) - alias(libs.plugins.gradleup.nmcp).apply(false) } allprojects { - group = "" // FIXME Check publishing + group = "com.revenuecat.purchases" version = rootProject.libs.versions.revenuecat.kmp.get() - // NmcpPlugin publishes to a local repo when running assemble, meaning we need signing - // credentials for every assemble. This avoids that. - if (gradle.startParameter.taskNames.contains("publishAllPublicationsToCentralPortal")) { - // Remove when https://github.com/vanniktech/gradle-maven-publish-plugin/issues/722 is fixed. - plugins.withType { - configure() { - publishAllPublications { - username = System.getenv("ORG_GRADLE_PROJECT_mavenCentralUsername") - password = System.getenv("ORG_GRADLE_PROJECT_mavenCentralPassword") - publicationType = "AUTOMATIC" - } - } - } - } - plugins.withType { configure { - // Re-enable when https://github.com/vanniktech/gradle-maven-publish-plugin/issues/722 - // is fixed. - // publishToMavenCentral(SonatypeHost.DEFAULT, automaticRelease = true) + publishToMavenCentral(SonatypeHost.DEFAULT, automaticRelease = true) signAllPublications() coordinates( groupId = group.toString(), - artifactId = "kobankat-${project.name}", + artifactId = "purchases-kmp-${project.name}", version = version.toString() ) pom { - name.set("KobanKat (${project.name})") - description.set("RevenueCat SDK for Kotlin Multiplatform") + name.set("purchases-kmp-(${project.name})") + description.set("Mobile subscriptions in hours, not months.") inceptionYear.set("2024") - url.set("https://github.com/JayShortway/kobankat") + url.set("https://github.com/RevenueCat/purchases-kmp") licenses { license { name.set("The MIT License (MIT)") @@ -67,15 +48,15 @@ allprojects { } developers { developer { - id.set("JayShortway") - name.set("Jay Shortway") - url.set("https://github.com/JayShortway") + id.set("revenuecat") + name.set("RevenueCat, Inc.") + url.set("https://www.revenuecat.com/") } } scm { - url.set("https://github.com/JayShortway/kobankat") - connection.set("scm:git:https://github.com/JayShortway/kobankat.git") - developerConnection.set("scm:git:ssh://git@github.com/JayShortway/kobankat.git") + url.set("https://github.com/RevenueCat/purchases-kmp") + connection.set("scm:git:git://github.com/RevenueCat/purchases-kmp.git") + developerConnection.set("scm:git:ssh://git@github.com/RevenueCat/purchases-kmp.git") } } } diff --git a/core/api/core.klib.api b/core/api/core.klib.api index 8958c8fa..196b73e3 100644 --- a/core/api/core.klib.api +++ b/core/api/core.klib.api @@ -5,7 +5,7 @@ // - Show manifest properties: true // - Show declarations: true -// Library unique name: +// Library unique name: abstract interface com.revenuecat.purchases.kmp.models/PurchasingData { // com.revenuecat.purchases.kmp.models/PurchasingData|null[0] abstract val productId // com.revenuecat.purchases.kmp.models/PurchasingData.productId|{}productId[0] abstract fun (): kotlin/String // com.revenuecat.purchases.kmp.models/PurchasingData.productId.|(){}[0] diff --git a/datetime/api/datetime.klib.api b/datetime/api/datetime.klib.api index 87c5da4e..f615df2e 100644 --- a/datetime/api/datetime.klib.api +++ b/datetime/api/datetime.klib.api @@ -5,7 +5,7 @@ // - Show manifest properties: true // - Show declarations: true -// Library unique name: +// Library unique name: final val com.revenuecat.purchases.kmp.datetime/allExpirationInstants // com.revenuecat.purchases.kmp.datetime/allExpirationInstants|@cocoapods.PurchasesHybridCommon.RCCustomerInfo{}allExpirationInstants[0] final fun (cocoapods.PurchasesHybridCommon/RCCustomerInfo).(): kotlin.collections/Map // com.revenuecat.purchases.kmp.datetime/allExpirationInstants.|@cocoapods.PurchasesHybridCommon.RCCustomerInfo(){}[0] final val com.revenuecat.purchases.kmp.datetime/allPurchaseInstants // com.revenuecat.purchases.kmp.datetime/allPurchaseInstants|@cocoapods.PurchasesHybridCommon.RCCustomerInfo{}allPurchaseInstants[0] diff --git a/either/api/either.klib.api b/either/api/either.klib.api index ab321c20..a13bfd34 100644 --- a/either/api/either.klib.api +++ b/either/api/either.klib.api @@ -5,7 +5,7 @@ // - Show manifest properties: true // - Show declarations: true -// Library unique name: +// Library unique name: final class com.revenuecat.purchases.kmp.either/FailedPurchase { // com.revenuecat.purchases.kmp.either/FailedPurchase|null[0] constructor (com.revenuecat.purchases.kmp/PurchasesError, kotlin/Boolean) // com.revenuecat.purchases.kmp.either/FailedPurchase.|(com.revenuecat.purchases.kmp.PurchasesError;kotlin.Boolean){}[0] final fun component1(): com.revenuecat.purchases.kmp/PurchasesError // com.revenuecat.purchases.kmp.either/FailedPurchase.component1|component1(){}[0] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 17d05b0c..02128458 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,9 +29,8 @@ android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } codingfeline-buildkonfig = { id = "com.codingfeline.buildkonfig", version = "0.15.1" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -gradleup-nmcp = { id = "com.gradleup.nmcp", version = "0.0.4" } jetbrains-compose = { id = "org.jetbrains.compose", version = "1.6.10" } kotlin-cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlinx-binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.15.0-Beta.2" } -vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.27.0" } +vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.28.0" } diff --git a/paywalls/api/paywalls.klib.api b/paywalls/api/paywalls.klib.api index 39ac6e82..5cd7142b 100644 --- a/paywalls/api/paywalls.klib.api +++ b/paywalls/api/paywalls.klib.api @@ -5,7 +5,7 @@ // - Show manifest properties: true // - Show declarations: true -// Library unique name: +// Library unique name: abstract interface com.revenuecat.purchases.kmp.ui.revenuecatui/PaywallListener { // com.revenuecat.purchases.kmp.ui.revenuecatui/PaywallListener|null[0] open fun onPurchaseCancelled() // com.revenuecat.purchases.kmp.ui.revenuecatui/PaywallListener.onPurchaseCancelled|onPurchaseCancelled(){}[0] open fun onPurchaseCompleted(cocoapods.PurchasesHybridCommon/RCCustomerInfo, cocoapods.PurchasesHybridCommon/RCStoreTransaction) // com.revenuecat.purchases.kmp.ui.revenuecatui/PaywallListener.onPurchaseCompleted|onPurchaseCompleted(cocoapods.PurchasesHybridCommon.RCCustomerInfo;cocoapods.PurchasesHybridCommon.RCStoreTransaction){}[0] diff --git a/result/api/result.klib.api b/result/api/result.klib.api index 401472b5..74f412b9 100644 --- a/result/api/result.klib.api +++ b/result/api/result.klib.api @@ -5,7 +5,7 @@ // - Show manifest properties: true // - Show declarations: true -// Library unique name: +// Library unique name: final suspend fun (cocoapods.PurchasesHybridCommon/RCPurchases).com.revenuecat.purchases.kmp.result/awaitCustomerInfoResult(com.revenuecat.purchases.kmp/CacheFetchPolicy = ...): kotlin/Result // com.revenuecat.purchases.kmp.result/awaitCustomerInfoResult|awaitCustomerInfoResult@cocoapods.PurchasesHybridCommon.RCPurchases(com.revenuecat.purchases.kmp.CacheFetchPolicy){}[0] final suspend fun (cocoapods.PurchasesHybridCommon/RCPurchases).com.revenuecat.purchases.kmp.result/awaitGetProductsResult(kotlin.collections/List): kotlin/Result> // com.revenuecat.purchases.kmp.result/awaitGetProductsResult|awaitGetProductsResult@cocoapods.PurchasesHybridCommon.RCPurchases(kotlin.collections.List){}[0] final suspend fun (cocoapods.PurchasesHybridCommon/RCPurchases).com.revenuecat.purchases.kmp.result/awaitLogInResult(kotlin/String): kotlin/Result // com.revenuecat.purchases.kmp.result/awaitLogInResult|awaitLogInResult@cocoapods.PurchasesHybridCommon.RCPurchases(kotlin.String){}[0]