diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 47bedbe39..03ffc0f08 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -97,12 +97,12 @@ jobs: rm -f '/usr/local/bin/python3-config' rm -f '/usr/local/bin/python3.11-config' rm -f '/usr/local/bin/python3.12-config' - brew install --overwrite x86_64-unknown-linux-gnu + brew install --overwrite messense/macos-cross-toolchains/x86_64-unknown-linux-gnu - name: "Install Linux GNU for aarch64" if: matrix.os-type == 'macos' run: | - brew install --overwrite aarch64-unknown-linux-gnu + brew install --overwrite messense/macos-cross-toolchains/aarch64-unknown-linux-gnu - name: "Install Rust Targets" if: matrix.os-type == 'macos' @@ -125,10 +125,6 @@ jobs: if: matrix.os-type == 'linux' run: sudo apt install rustc build-essential -y - - name: "Install rust toolchain (Macos)" - if: matrix.os-type == 'macos' - run: brew install rustup - - name: "Install wasm-pack" run: cargo install wasm-pack @@ -145,6 +141,7 @@ jobs: run: ./gradlew koverHtmlReport koverXmlReport - name: Coveralls + if: matrix.os-type == 'linux' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ef1f473ad..875362058 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,10 @@ on: version: description: 'Version to release (e.g., 1.2.3)' required: true + branch: + description: 'Branch or ref to release from' + required: false + default: 'release/1.8.7' release_swift: description: 'Release Swift package?' type: boolean @@ -16,6 +20,23 @@ on: type: boolean required: false default: true + maven_local_task: + description: 'Gradle task used by the Maven local verification step' + type: choice + required: false + default: 'publishToMavenLocal' + options: + - 'publishToMavenLocal' + - ':secp256k1-kmp:publishToMavenLocal' + maven_publish_task: + description: 'Gradle task used by the Maven Central publish step' + type: choice + required: false + default: 'publishToMavenCentral' + options: + - 'publishToMavenCentral' + - ':secp256k1-kmp:publishToMavenCentral' + - ':secp256k1-kmp:publishAndReleaseToMavenCentral' release_ts: description: 'Release TypeScript package?' type: boolean @@ -58,8 +79,9 @@ jobs: - name: Install Dependencies run: | + brew tap messense/macos-cross-toolchains brew install messense/macos-cross-toolchains/aarch64-unknown-linux-gnu - brew install autoconf automake x86_64-unknown-linux-gnu + brew install autoconf automake messense/macos-cross-toolchains/x86_64-unknown-linux-gnu - name: Install Rust Targets run: | @@ -104,7 +126,7 @@ jobs: - name: Build Kotlin Multiplatform Maven Artifacts if: ${{ inputs.release_maven }} - run: ./gradlew publishToMavenLocal --no-configuration-cache + run: ./gradlew ${{ inputs.maven_local_task }} --no-configuration-cache - name: Build Kotlin Multiplatform NPM Artifacts if: ${{ inputs.release_ts }} @@ -146,7 +168,7 @@ jobs: if: ${{ inputs.release_maven }} env: ORG_GRADLE_PROJECT_autoRelease: true - run: ./gradlew publishToMavenCentral --no-configuration-cache + run: ./gradlew ${{ inputs.maven_publish_task }} --no-configuration-cache - name: NPM publish if: ${{ inputs.release_ts }} diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 2dbedf15e..925d2f61d 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -1,12 +1,13 @@ import dev.petuska.npm.publish.extension.domain.NpmAccess import dev.petuska.npm.publish.task.NpmPublishTask import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import java.net.URI plugins { alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.kotlin.multiplatform.library) + alias(libs.plugins.android.library) alias(libs.plugins.dokka) alias(libs.plugins.maven.publish) alias(libs.plugins.npm.publish) @@ -30,20 +31,13 @@ kover { kotlin { applyDefaultHierarchyTemplate() + @OptIn(ExperimentalKotlinGradlePluginApi::class) compilerOptions { freeCompilerArgs.addAll("-Xexpect-actual-classes") } jvm() - androidLibrary { - namespace = "org.hyperledger.identus.apollo" - compileSdk = - libs.versions.android.compileSdk - .get() - .toInt() - minSdk = - libs.versions.android.minSdk - .get() - .toInt() + androidTarget { + publishAllLibraryVariants() } iosArm64 { swiftCinterop("IOHKSecureRandomGeneration", name) @@ -81,7 +75,7 @@ kotlin { } } js(IR) { - outputModuleName = "apollo" + moduleName = "apollo" binaries.library() useCommonJs() generateTypeScriptDefinitions() @@ -174,6 +168,31 @@ kotlin { } } +android { + namespace = "org.hyperledger.identus.apollo" + compileSdk = + libs.versions.android.compileSdk + .get() + .toInt() + defaultConfig { + minSdk = + libs.versions.android.minSdk + .get() + .toInt() + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + publishing { + multipleVariants { + withSourcesJar() + withJavadocJar() + allVariants() + } + } +} + tasks.withType().configureEach { moduleName.set("Apollo") moduleVersion.set(rootProject.version.toString()) @@ -181,7 +200,7 @@ tasks.withType().configureEach { dokkaSourceSets { configureEach { jdkVersion.set(17) - languageVersion.set("1.9.22") + languageVersion.set("1.9.25") apiVersion.set("2.0") includes.from( "docs/Apollo.md", @@ -222,7 +241,13 @@ tasks.withType().configureEach { fun KotlinNativeTarget.swiftCinterop(library: String, platform: String) { compilations.getByName("main") { cinterops.create(library) { - extraOpts = listOf("-compiler-option", "-DNS_FORMAT_ARGUMENT(A)=") + extraOpts = + buildList { + addAll(listOf("-compiler-option", "-DNS_FORMAT_ARGUMENT(A)=")) + if (platform.endsWith("X64")) { + addAll(listOf("-compiler-option", "-D_Float16=float")) + } + } val iosLibsDir = rootProject.layout.projectDirectory.dir("iOSLibs") when (platform) { diff --git a/bip32-ed25519/build.gradle.kts b/bip32-ed25519/build.gradle.kts index df14495c6..3a5ebb846 100644 --- a/bip32-ed25519/build.gradle.kts +++ b/bip32-ed25519/build.gradle.kts @@ -4,7 +4,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackOutput plugins { alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.kotlin.multiplatform.library) + alias(libs.plugins.android.library) alias(libs.plugins.maven.publish) alias(libs.plugins.kover) } @@ -23,7 +23,6 @@ tasks.register("copyGeneratedKotlin") { description = "Copies Rust-generated Kotlin wrappers." duplicatesStrategy = DuplicatesStrategy.INCLUDE dependsOn("buildRustWrapper") - dependsOn("prepareAndroidMainArtProfile") from(wrapperOutputDir) into(layout.buildDirectory.dir("generated")) } @@ -74,10 +73,10 @@ tasks.register("copyAndroidJniLibs") { into(layout.buildDirectory.dir("jniLibs")) val abiMapping = mapOf( - "aarch64-linux-android" to "arm64-v8a", + "aarch64-linux-android" to "arm64-v8a", "armv7-linux-androideabi" to "armeabi-v7a", - "i686-linux-android" to "x86", - "x86_64-linux-android" to "x86_64" + "i686-linux-android" to "x86", + "x86_64-linux-android" to "x86_64" ) abiMapping.forEach { (triple, abi) -> from(wrapperDir.dir("target/$triple/release")) { @@ -110,10 +109,8 @@ kotlin { ) } } - androidLibrary { - namespace = "org.hyperledger.identus.apollo.bip32ed25519" - compileSdk = libs.versions.android.compileSdk.get().toInt() - minSdk = libs.versions.android.minSdk.get().toInt() + androidTarget { + publishAllLibraryVariants() } iosArm64 { binaries.framework { @@ -261,61 +258,42 @@ kotlin { } } } -// Wire the Rust .so files into the Android AAR. -// com.android.kotlin.multiplatform.library does not expose a standard android {} extension and -// the Variant Sources API does not correctly wire task dependencies for this plugin, so we -// use a post-bundle task that injects the .so files into the already-assembled AAR zip. -afterEvaluate { - val bundleTask = tasks.named("bundleAndroidMainAar") - - val injectJniLibsIntoAar by tasks.registering(Zip::class) { - group = "rust" - description = "Injects Rust .so files into the bip32-ed25519 AAR under jni//." - dependsOn(bundleTask, copyAndroidJniLibsProvider) - - val aarFile = bundleTask.map { task -> - task.outputs.files.singleFile - } - - // Start from the existing AAR contents - from(zipTree(aarFile)) - - // Add the .so files under jni/ (AGP's expected layout inside an AAR) - from(copyAndroidJniLibsProvider.map { it.destinationDir }) { - into("jni") - } - destinationDirectory.set(layout.buildDirectory.dir("outputs/aar-with-jni")) - archiveFileName.set("bip32-ed25519.aar") +android { + namespace = "org.hyperledger.identus.apollo.bip32ed25519" + compileSdk = libs.versions.android.compileSdk.get().toInt() + sourceSets["main"].jniLibs.srcDir(copyAndroidJniLibsProvider.map { it.destinationDir }) + defaultConfig { + minSdk = libs.versions.android.minSdk.get().toInt() } - - // Replace the original AAR with the enriched one - tasks.register("replaceAarWithJni") { - group = "rust" - description = "Overwrites the original AAR with the .so-enriched version." - dependsOn(injectJniLibsIntoAar) - from(injectJniLibsIntoAar.map { it.destinationDirectory }) - into(layout.buildDirectory.dir("outputs/aar")) + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } - - bundleTask.configure { - finalizedBy("replaceAarWithJni") + publishing { + multipleVariants { + withSourcesJar() + withJavadocJar() + allVariants() + } } +} - // Tell every Android publication task that reads the AAR to wait for the enriched version. - // Without this Gradle's validation detects an implicit dependency and fails. - val pubTaskPredicate = { t: Task -> - (t.name.startsWith("generateMetadataFileFor") || - t.name.startsWith("generatePomFileFor") || - t.name.startsWith("publish")) && - t.name.contains("Android", ignoreCase = true) +afterEvaluate { + tasks.matching { + it.name.contains("Release") || + it.name.contains("Debug") || + it.name.contains("Android") + }.configureEach { + if (name != copyGeneratedKotlinProvider.name) { + dependsOn(copyGeneratedKotlinProvider) + } } - tasks.matching(pubTaskPredicate).configureEach { - dependsOn("replaceAarWithJni") + tasks.matching { it.name.startsWith("merge") && it.name.endsWith("JniLibFolders") }.configureEach { + dependsOn(copyAndroidJniLibsProvider) } } - // === Group: Rust tasks Tasks === tasks.register("buildRustWrapper") { group = "build" diff --git a/build.gradle.kts b/build.gradle.kts index ecbe3b504..55d53063b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ plugins { alias(libs.plugins.kotlin.multiplatform) apply false - alias(libs.plugins.android.kotlin.multiplatform.library) apply false + alias(libs.plugins.android.library) apply false alias(libs.plugins.maven.publish) apply false alias(libs.plugins.kover) apply false alias(libs.plugins.dokka) apply false diff --git a/gradle.properties b/gradle.properties index 77a6ac921..60eacdd8c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.8.7 +version = 1.8.8 # Gradle org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx4096M" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 485c9cd4d..f1476bbc2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,14 +1,14 @@ [versions] -kotlin = "2.1.20" -agp = "8.11.0" +kotlin = "1.9.25" +agp = "8.2.2" dokka = "1.9.20" ktlint = "12.3.0" kover = "0.9.7" vanniktech-maven-publish = "0.33.0" npm-publish = "3.5.3" -swiftpackage = "2.2.4" +swiftpackage = "2.2.2" secp256k1-kmp = "0.16.0" -secp256k1-kmp-android = "0.19.0" +secp256k1-kmp-android = "0.16.0" android-minSdk = "24" android-compileSdk = "34" @@ -34,7 +34,7 @@ kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotl [plugins] kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } -android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } +android-library = { id = "com.android.library", version.ref = "agp" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } diff --git a/secp256k1-kmp/build.gradle.kts b/secp256k1-kmp/build.gradle.kts index 250969879..582bc3e47 100644 --- a/secp256k1-kmp/build.gradle.kts +++ b/secp256k1-kmp/build.gradle.kts @@ -1,5 +1,6 @@ plugins { alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.maven.publish) } kotlin { @@ -59,3 +60,44 @@ kotlin { } } } + +mavenPublishing { + val shouldAutoRelease = project.findProperty("autoRelease")?.toString()?.toBoolean() ?: false + publishToMavenCentral(automaticRelease = shouldAutoRelease) + val hasSigningCredentials = project.hasProperty("signing.keyId") || + project.hasProperty("signingInMemoryKey") || + System.getenv("ORG_GRADLE_PROJECT_signingInMemoryKey") != null || + System.getenv("GPG_KEY_ID") != null + if (hasSigningCredentials) { + signAllPublications() + } + coordinates(group.toString(), "secp256k1-kmp", rootProject.version.toString()) + pom { + name.set("Identus secp256k1-kmp") + description.set("Native secp256k1 Kotlin Multiplatform bindings used by Identus Apollo.") + url.set("https://hyperledger-identus.github.io/docs/") + organization { + name.set("Hyperledger") + url.set("https://www.hyperledger.org/") + } + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("hyperledger-identus") + name.set("Hyperledger Identus") + organization.set("Hyperledger") + roles.add("developer") + } + } + scm { + connection.set("scm:git:git://github.com/hyperledger-identus/apollo.git") + developerConnection.set("scm:git:ssh://git@github.com/hyperledger-identus/apollo.git") + url.set("https://github.com/hyperledger-identus/apollo") + } + } +}