diff --git a/.github/workflows/publish_android_camera.yml b/.github/workflows/publish_android_camera.yml index 5b22d2a..964e3fe 100644 --- a/.github/workflows/publish_android_camera.yml +++ b/.github/workflows/publish_android_camera.yml @@ -25,5 +25,12 @@ jobs: distribution: 'adopt' java-version: 11 + - name: Restore maven key + run: | + echo -e "${{ secrets.SIGNING_PROPERTIES }}" > signing.properties.asc + gpg -d --passphrase ${{ secrets.GPG_KEY }} --batch signing.properties.asc > configs/signing/signing.properties + echo -e "${{ secrets.MAVEN_KEY }}" > release-maven.asc + gpg -d --passphrase ${{ secrets.GPG_KEY }} --batch release-maven.asc > configs/signing/release-maven.txt + - name: Publish to github packages - run: ./gradlew publishCameraModulesToGithub --no-configuration-cache \ No newline at end of file + run: ./gradlew publishCameraModulesToGithub publishCameraModulesToSonaType --no-configuration-cache \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 596b532..7d06509 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("io.nyris.gradle.configuration") id("io.nyris.gradle.detekt") + id("io.nyris.gradle.sonatype-publisher") alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false @@ -15,6 +16,7 @@ plugins { alias(libs.plugins.firebase.appdist) apply false alias(libs.plugins.firebase.crashlytics) apply false alias(libs.plugins.google.services) apply false + alias(libs.plugins.nexus.publish) apply false } buildscript { diff --git a/buildLogic/convention/build.gradle.kts b/buildLogic/convention/build.gradle.kts index fac3a06..fc0ecf5 100644 --- a/buildLogic/convention/build.gradle.kts +++ b/buildLogic/convention/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { compileOnly(libs.testlogger.plugin) compileOnly(libs.firebase.appdist.plugin) compileOnly(libs.firebase.crashlytics.plugin) + compileOnly(libs.nexus.publish.plugin) } gradlePlugin { @@ -69,5 +70,10 @@ gradlePlugin { id = "io.nyris.gradle.crash-reporter" implementationClass = "io.nyris.gradle.ApplicationCrashReporterConventionPlugin" } + + register("gradle-nexus-publisher") { + id = "io.nyris.gradle.sonatype-publisher" + implementationClass = "io.nyris.gradle.SonatypePublisherPlugin" + } } } \ No newline at end of file diff --git a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/AndroidApplicationPlugin.kt b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/AndroidApplicationPlugin.kt index 82affa3..edc07ac 100644 --- a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/AndroidApplicationPlugin.kt +++ b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/AndroidApplicationPlugin.kt @@ -18,6 +18,7 @@ package io.nyris.gradle import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension import io.nyris.gradle.utils.Configuration +import io.nyris.gradle.utils.Vars import io.nyris.gradle.utils.applyKotlinJvmToolChain import io.nyris.gradle.utils.configureDefaultApplicationPlugins import io.nyris.gradle.utils.configureDefaultDependencies @@ -131,7 +132,7 @@ private fun BaseAppModuleExtension.defaultBuildTypes(project: Project) { // Since we don't have firebase configuration for .debug app, we want to add the suffix // only when the environment is not CI, which will allow the app to compile on // debug build type. - if (!System.getenv().containsKey("CI")) { + if (!Vars.IS_CI) { applicationIdSuffix = ".debug" } @@ -142,7 +143,7 @@ private fun BaseAppModuleExtension.defaultBuildTypes(project: Project) { enableUnitTestCoverage = false - if (System.getenv().containsKey("CI")) { + if (Vars.IS_CI) { extra.set("enableCrashlytics", false) configure { mappingFileUploadEnabled = false } } @@ -158,7 +159,7 @@ private fun BaseAppModuleExtension.defaultBuildTypes(project: Project) { signingConfig = signingConfigs.getByName("release") - if (System.getenv().containsKey("CI")) { + if (Vars.IS_CI) { extra.set("enableCrashlytics", false) configure { mappingFileUploadEnabled = false } } diff --git a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/RootBuildGradleConfigPlugin.kt b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/RootBuildGradleConfigPlugin.kt index 98b94f6..905d48e 100644 --- a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/RootBuildGradleConfigPlugin.kt +++ b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/RootBuildGradleConfigPlugin.kt @@ -15,6 +15,7 @@ */ package io.nyris.gradle +import io.nyris.gradle.utils.Vars import java.io.ByteArrayOutputStream import org.gradle.api.Plugin import org.gradle.api.Project @@ -46,7 +47,7 @@ private fun ExtraPropertiesExtension.loadExtras(target: Project) { loadDemoVersionCode(target) loadLibVersionName(target) loadGithubProperties(target) - loadReleaseSigningProperties(target) + loadSigningProperties(target) } private fun ExtraPropertiesExtension.loadDemoVersionCode(target: Project) { @@ -66,12 +67,12 @@ private fun ExtraPropertiesExtension.loadGithubProperties(target: Project) { set("NYRIS_BOT_USER", properties["NYRIS_BOT_USER"]) set("NYRIS_BOT_TAP", properties["NYRIS_BOT_TAP"]) } else { - set("NYRIS_BOT_USER", System.getenv("NYRIS_BOT_USER") ?: "") - set("NYRIS_BOT_TAP", System.getenv("NYRIS_BOT_TAP") ?: "") + set("NYRIS_BOT_USER", Vars.NYRIS_BOT_USER ?: "") + set("NYRIS_BOT_TAP", Vars.NYRIS_BOT_TAP ?: "") } } -private fun ExtraPropertiesExtension.loadReleaseSigningProperties(target: Project) { +private fun ExtraPropertiesExtension.loadSigningProperties(target: Project) { val propertiesFile = target.rootDir.resolve("configs/signing/signing.properties") if (propertiesFile.exists()) { val properties = java.util.Properties() @@ -80,10 +81,26 @@ private fun ExtraPropertiesExtension.loadReleaseSigningProperties(target: Projec set("RELEASE_KEYSTORE_PASSWORD", properties["RELEASE_KEYSTORE_PASSWORD"]) set("RELEASE_KEY_ALIAS", properties["RELEASE_KEY_ALIAS"]) set("RELEASE_KEY_PASSWORD", properties["RELEASE_KEY_PASSWORD"]) + + set("MAVEN_GPG_KEY_ID", properties["MAVEN_GPG_KEY_ID"]) + set("MAVEN_GPG_PASSWORD", properties["MAVEN_GPG_PASSWORD"]) + set("MAVEN_GPG_KEY", properties["MAVEN_GPG_KEY"]) + + set("SONATYPE_OSSRH_USERNAME", properties["SONATYPE_OSSRH_USERNAME"]) + set("SONATYPE_OSSRH_PASSWORD", properties["SONATYPE_OSSRH_PASSWORD"]) + set("SONATYPE_STAGING_PROFILE_ID", properties["SONATYPE_STAGING_PROFILE_ID"]) } else { set("RELEASE_KEYSTORE_PASSWORD", "") set("RELEASE_KEY_ALIAS", "") set("RELEASE_KEY_PASSWORD", "") + + set("MAVEN_GPG_KEY_ID", "") + set("MAVEN_GPG_PASSWORD", "") + set("MAVEN_GPG_KEY", "") + + set("SONATYPE_OSSRH_USERNAME", "") + set("SONATYPE_OSSRH_PASSWORD", "") + set("SONATYPE_STAGING_PROFILE_ID", "") } } @@ -92,10 +109,9 @@ private fun generateVersionCode(project: Project): Int { } private fun generateVersionName(project: Project): String { - val versionName = System.getenv("LIB_VERSION_NAME") - val isRelease = System.getenv().containsKey("CI") + val versionName = Vars.LIB_VERSION_NAME - return if (isRelease && versionName != null) { + return if (Vars.IS_CI && versionName != null) { versionName } else { val hash = "git rev-parse --short HEAD".execute(project) diff --git a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SdkMavenPublisherPlugin.kt b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SdkMavenPublisherPlugin.kt index d068c4e..ae285f3 100644 --- a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SdkMavenPublisherPlugin.kt +++ b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SdkMavenPublisherPlugin.kt @@ -16,6 +16,8 @@ package io.nyris.gradle import io.nyris.gradle.utils.Configuration +import io.nyris.gradle.utils.Vars +import java.time.LocalDate import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.publish.PublishingExtension @@ -25,46 +27,56 @@ import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.withType +import org.gradle.plugins.signing.SigningExtension +import org.gradle.plugins.signing.SigningPlugin class SdkMavenPublisherPlugin : Plugin { override fun apply(target: Project) { with(target) { pluginManager.apply(MavenPublishPlugin::class.java) + pluginManager.apply(SigningPlugin::class.java) group = "io.nyris.sdk" version = rootProject.extra["LIB_VERSION_NAME"] .toString() .cleanVersionName() afterEvaluate { - configure { - repositories { - maven { - name = "Github" - url = uri("https://maven.pkg.github.com/nyris/sdk-kmp") - credentials { - username = rootProject.extra["NYRIS_BOT_USER"].toString() - password = rootProject.extra["NYRIS_BOT_TAP"].toString() - } - } - maven { - name = "LocalMaven" - url = uri("file://$rootDir/build/maven") - } + configurePublishing() + } + } + } + + private fun Project.configurePublishing() { + configure { + repositories { + maven { + name = "Github" + url = uri("https://maven.pkg.github.com/nyris/sdk-kmp") + credentials { + username = rootProject.extra["NYRIS_BOT_USER"].toString() + password = rootProject.extra["NYRIS_BOT_TAP"].toString() } + } + maven { + name = "LocalMaven" + url = uri("file://$rootDir/build/maven") + } + } - publications { - // KMM project has already a defined project Published, in this - // case we need to make sure to use the publication and attach to - // it the pom configuration - if (pluginManager.hasPlugin(Configuration.kotlinMultiplatform)) { - withType { - configurePom(target) - } - } else { - create("release") { - from(components.findByName("release")) - configurePom(target) - } + publications { + // KMM project has already a defined project Published, in this case we need to make sure to + // use the publication and attach to it the pom configuration + if (pluginManager.hasPlugin(Configuration.kotlinMultiplatform)) { + withType { + configurePom(this@configurePublishing) + configureSigning(this) + } + } else { + create("release") { + from(components.findByName("release")) + configurePom(this@configurePublishing) + if (Vars.IS_CI) { + configureSigning(this) } } } @@ -72,10 +84,23 @@ class SdkMavenPublisherPlugin : Plugin { } } + private fun Project.configureSigning(mavenPublication: MavenPublication) { + configure { + useInMemoryPgpKeys( + rootProject.extra["MAVEN_GPG_KEY_ID"].toString(), + file("$rootDir/configs/signing/release-maven.txt").readText(), + rootProject.extra["MAVEN_GPG_PASSWORD"].toString() + ) + sign(mavenPublication) + } + } + private fun MavenPublication.configurePom(target: Project) { pom { name.set("Nyris SDK - ${target.name}") - inceptionYear.set("2023") + description.set("Nyris SDK - ${target.name}") + inceptionYear.set(LocalDate.now().year.toString()) + url.set("https://github.com/nyris/sdk-kmp") organization { name.set("nyris GmbH") @@ -89,6 +114,15 @@ class SdkMavenPublisherPlugin : Plugin { } } + developers { + developer { + id.set("github/nyris") + name.set("nyris GmbH") + email.set("hi@nyris.io") + } + // Add all other devs here... + } + issueManagement { system.set("Github") url.set("https://github.com/nyris/sdk-kmp/issues") diff --git a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SonatypePublisherPlugin.kt b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SonatypePublisherPlugin.kt new file mode 100644 index 0000000..560bdae --- /dev/null +++ b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/SonatypePublisherPlugin.kt @@ -0,0 +1,28 @@ +package io.nyris.gradle + +import io.github.gradlenexus.publishplugin.NexusPublishExtension +import io.github.gradlenexus.publishplugin.NexusPublishPlugin +import java.net.URI +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.extra + +class SonatypePublisherPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply(NexusPublishPlugin::class.java) + + configure { + repositories { + sonatype { + nexusUrl.set(URI.create("https://s01.oss.sonatype.org/service/local/")) + username.set(rootProject.extra["SONATYPE_OSSRH_USERNAME"].toString()) + password.set(rootProject.extra["SONATYPE_OSSRH_PASSWORD"].toString()) + stagingProfileId.set(rootProject.extra["SONATYPE_STAGING_PROFILE_ID"].toString()) + } + } + } + } + } +} diff --git a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/ProjectExt.kt b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/ProjectExt.kt index b09cb2e..bf4c80e 100644 --- a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/ProjectExt.kt +++ b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/ProjectExt.kt @@ -31,7 +31,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension internal fun Project.configureDefaultApplicationPlugins() { with(pluginManager) { apply(Configuration.androidApplicationPlugin) - if (System.getenv().containsKey("CI")) { + if (Vars.IS_CI) { apply(Configuration.appDist) apply(Configuration.crashReporter) apply(Configuration.googleServices) diff --git a/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/Vars.kt b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/Vars.kt new file mode 100644 index 0000000..98c5fb1 --- /dev/null +++ b/buildLogic/convention/src/main/kotlin/io/nyris/gradle/utils/Vars.kt @@ -0,0 +1,9 @@ +package io.nyris.gradle.utils + +object Vars { + val IS_CI = System.getenv().containsKey("CI") + val PUBLIC_API_KEY: String? = System.getenv("PUBLIC_API_KEY") + val NYRIS_BOT_USER: String? = System.getenv("NYRIS_BOT_USER") + val NYRIS_BOT_TAP: String? = System.getenv("NYRIS_BOT_TAP") + val LIB_VERSION_NAME: String? = System.getenv("LIB_VERSION_NAME") +} diff --git a/configs/signing/.gitignore b/configs/signing/.gitignore index 3648b50..799b4e9 100644 --- a/configs/signing/.gitignore +++ b/configs/signing/.gitignore @@ -1,2 +1,3 @@ release.keystore -signing.properties \ No newline at end of file +signing.properties +release-maven.txt \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 405fc75..d85d3cf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,6 +24,7 @@ firebaseCrashlytics = "18.3.3" firebaseAnalytics = "21.2.0" cameraX = "1.2.1" mlkitBarcode = "17.1.0" +nexusPublishing = "1.3.0" [libraries] # classpath plugin @@ -33,6 +34,7 @@ android_plugin = { group = "com.android.tools.build", name = "gradle", version.r testlogger_plugin = { group = "com.adarshr", name = "gradle-test-logger-plugin", version.ref = "testLoggerPlugin" } firebase_appdist_plugin = { group = "com.google.firebase", name = "firebase-appdistribution-gradle", version.ref = "firebaseAppDistPlugin" } firebase_crashlytics_plugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" } +nexus_publish_plugin = { group = "io.github.gradle-nexus", name = "publish-plugin", version.ref = "nexusPublishing" } google_services_plugin = { group = "com.google.gms", name = "google-services", version.ref = "googleServicesPlugin" } google_mlkit_barcode = { group = "com.google.mlkit", name = "barcode-scanning", version.ref = "mlkitBarcode" } @@ -85,4 +87,5 @@ detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektPlugin" } testlogger = { id = "com.adarshr.test-logger", version.ref = "testLoggerPlugin" } firebase_appdist = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistPlugin" } firebase_crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsPlugin" } -google_services = { id = "com.google.gms.google-services", version.ref = "googleServicesPlugin" } \ No newline at end of file +google_services = { id = "com.google.gms.google-services", version.ref = "googleServicesPlugin" } +nexus_publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexusPublishing" } \ No newline at end of file diff --git a/release-maven.txt b/release-maven.txt new file mode 100644 index 0000000..e69de29 diff --git a/sdk.camera/android/README.md b/sdk.camera/android/README.md index c65e555..a9b033f 100644 --- a/sdk.camera/android/README.md +++ b/sdk.camera/android/README.md @@ -37,14 +37,14 @@ On top of the optimization, the SDK Offers: ## 💻 Install ```kotlin -// Add the SDK maven repository to your gradle repositories +// [Optional]: Needed only if you have access to this repo maven { url = uri("https://maven.pkg.github.com/nyris/sdk-kmp") } -implementation("io.nyris.sdk:camera-view:1.1.0") -// Optional needed only when you need to use barcode scanning -implementation("io.nyris.sdk:camera-feature-barcode:1.1.0") +implementation("io.nyris.sdk:camera-view:1.0.0") +// [Optional]: needed only when you need to use barcode scanning +implementation("io.nyris.sdk:camera-feature-barcode:1.0.0") ``` ## 🏗️️ Usage diff --git a/sdk.camera/android/view/build.gradle.kts b/sdk.camera/android/view/build.gradle.kts index 2b3d790..1764ce8 100644 --- a/sdk.camera/android/view/build.gradle.kts +++ b/sdk.camera/android/view/build.gradle.kts @@ -62,6 +62,13 @@ dependencies { implementation(project(Modules.sdk_camera_feature_barcode_android)) } +tasks.create("publishCameraModulesToLocal") { + dependsOn(":sdk.camera:android:camera-core:publishAllPublicationsToLocalMavenRepository") + dependsOn(":sdk.camera:android:camera-feature-image:publishAllPublicationsToLocalMavenRepository") + dependsOn(":sdk.camera:android:camera-feature-barcode:publishAllPublicationsToLocalMavenRepository") + dependsOn(":sdk.camera:android:camera-view:publishAllPublicationsToLocalMavenRepository") +} + tasks.create("publishCameraModulesToGithub") { dependsOn(":sdk.camera:android:camera-core:publishAllPublicationsToGithubRepository") dependsOn(":sdk.camera:android:camera-feature-image:publishAllPublicationsToGithubRepository") @@ -69,9 +76,9 @@ tasks.create("publishCameraModulesToGithub") { dependsOn(":sdk.camera:android:camera-view:publishAllPublicationsToGithubRepository") } -tasks.create("publishCameraModulesToLocal") { - dependsOn(":sdk.camera:android:camera-core:publishAllPublicationsToLocalMavenRepository") - dependsOn(":sdk.camera:android:camera-feature-image:publishAllPublicationsToLocalMavenRepository") - dependsOn(":sdk.camera:android:camera-feature-barcode:publishAllPublicationsToLocalMavenRepository") - dependsOn(":sdk.camera:android:camera-view:publishAllPublicationsToLocalMavenRepository") -} +tasks.create("publishCameraModulesToSonaType") { + dependsOn(":sdk.camera:android:camera-core:publishAllPublicationsToSonatypeRepository") + dependsOn(":sdk.camera:android:camera-feature-image:publishAllPublicationsToSonatypeRepository") + dependsOn(":sdk.camera:android:camera-feature-barcode:publishAllPublicationsToSonatypeRepository") + dependsOn(":sdk.camera:android:camera-view:publishAllPublicationsToSonatypeRepository") +} \ No newline at end of file diff --git a/sdk.demos/android/build.gradle.kts b/sdk.demos/android/build.gradle.kts index b65895a..adb71ea 100644 --- a/sdk.demos/android/build.gradle.kts +++ b/sdk.demos/android/build.gradle.kts @@ -14,6 +14,7 @@ * limitations under the License. */ import io.nyris.gradle.utils.Modules +import io.nyris.gradle.utils.Vars plugins { id("io.nyris.gradle.app") @@ -32,7 +33,7 @@ android { } buildTypes.forEach { - it.buildConfigField("String", "API_KEY", "\"${System.getenv("PUBLIC_API_KEY")}\"") + it.buildConfigField("String", "API_KEY", "\"${Vars.PUBLIC_API_KEY}\"") } }