From be7327d21eefc72be342e401a1707997d789becf Mon Sep 17 00:00:00 2001 From: Matthew Nelson Date: Sat, 31 Aug 2024 02:28:12 -0400 Subject: [PATCH 1/2] Enable klib api validation --- build.gradle.kts | 5 ++ gradle/libs.versions.toml | 2 +- library/hmac/hmac-md/api/hmac-md.klib.api | 11 ++++ library/hmac/hmac-md5/api/hmac-md5.klib.api | 8 +++ library/hmac/hmac-sha1/api/hmac-sha1.klib.api | 11 ++++ library/hmac/hmac-sha2/api/hmac-sha2.klib.api | 30 +++++++++++ library/hmac/hmac-sha3/api/hmac-sha3.klib.api | 39 +++++++++++++++ library/hmac/hmac/api/hmac.klib.api | 9 ++++ library/kmac/api/kmac.klib.api | 50 +++++++++++++++++++ test-android/api/test-android.klib.api | 0 10 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 library/hmac/hmac-md/api/hmac-md.klib.api create mode 100644 library/hmac/hmac-md5/api/hmac-md5.klib.api create mode 100644 library/hmac/hmac-sha1/api/hmac-sha1.klib.api create mode 100644 library/hmac/hmac-sha2/api/hmac-sha2.klib.api create mode 100644 library/hmac/hmac-sha3/api/hmac-sha3.klib.api create mode 100644 library/hmac/hmac/api/hmac.klib.api create mode 100644 library/kmac/api/kmac.klib.api create mode 100644 test-android/api/test-android.klib.api diff --git a/build.gradle.kts b/build.gradle.kts index 90b4085..5360dd4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,6 +44,11 @@ plugins.withType { } apiValidation { + // Only enable when selectively enabled targets are not being passed via cli. + // See https://github.com/Kotlin/binary-compatibility-validator/issues/269 + @OptIn(kotlinx.validation.ExperimentalBCVApi::class) + klib.enabled = findProperty("KMP_TARGETS") == null + if (findProperty("CHECK_PUBLICATION") != null) { ignoredProjects.add("check-publication") } else { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index abe1fee..2f645e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] gradle-android = "8.2.2" -gradle-binary-compat = "0.14.0" +gradle-binary-compat = "0.16.3" gradle-kmp-configuration = "0.3.2" gradle-kotlin = "1.9.24" gradle-publish-maven = "0.29.0" diff --git a/library/hmac/hmac-md/api/hmac-md.klib.api b/library/hmac/hmac-md/api/hmac-md.klib.api new file mode 100644 index 0000000..ca85891 --- /dev/null +++ b/library/hmac/hmac-md/api/hmac-md.klib.api @@ -0,0 +1,11 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +final class org.kotlincrypto.macs.hmac.md/HmacMD5 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.md/HmacMD5|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.md/HmacMD5.|(kotlin.ByteArray){}[0] +} diff --git a/library/hmac/hmac-md5/api/hmac-md5.klib.api b/library/hmac/hmac-md5/api/hmac-md5.klib.api new file mode 100644 index 0000000..e3c7841 --- /dev/null +++ b/library/hmac/hmac-md5/api/hmac-md5.klib.api @@ -0,0 +1,8 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: diff --git a/library/hmac/hmac-sha1/api/hmac-sha1.klib.api b/library/hmac/hmac-sha1/api/hmac-sha1.klib.api new file mode 100644 index 0000000..54e14aa --- /dev/null +++ b/library/hmac/hmac-sha1/api/hmac-sha1.klib.api @@ -0,0 +1,11 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +final class org.kotlincrypto.macs.hmac.sha1/HmacSHA1 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha1/HmacSHA1|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha1/HmacSHA1.|(kotlin.ByteArray){}[0] +} diff --git a/library/hmac/hmac-sha2/api/hmac-sha2.klib.api b/library/hmac/hmac-sha2/api/hmac-sha2.klib.api new file mode 100644 index 0000000..8db8531 --- /dev/null +++ b/library/hmac/hmac-sha2/api/hmac-sha2.klib.api @@ -0,0 +1,30 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +final class org.kotlincrypto.macs.hmac.sha2/HmacSHA224 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha2/HmacSHA224|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha2/HmacSHA224.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha2/HmacSHA256 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha2/HmacSHA256|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha2/HmacSHA256.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha2/HmacSHA384 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha2/HmacSHA384|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha2/HmacSHA384.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha2/HmacSHA512 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha2/HmacSHA512|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha2/HmacSHA512.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha2/HmacSHA512t : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha2/HmacSHA512t|null[0] + constructor (kotlin/ByteArray, kotlin/Int) // org.kotlincrypto.macs.hmac.sha2/HmacSHA512t.|(kotlin.ByteArray;kotlin.Int){}[0] +} + +final fun org.kotlincrypto.macs.hmac.sha2/HmacSHA512_224(kotlin/ByteArray): org.kotlincrypto.macs.hmac.sha2/HmacSHA512t // org.kotlincrypto.macs.hmac.sha2/HmacSHA512_224|HmacSHA512_224(kotlin.ByteArray){}[0] +final fun org.kotlincrypto.macs.hmac.sha2/HmacSHA512_256(kotlin/ByteArray): org.kotlincrypto.macs.hmac.sha2/HmacSHA512t // org.kotlincrypto.macs.hmac.sha2/HmacSHA512_256|HmacSHA512_256(kotlin.ByteArray){}[0] diff --git a/library/hmac/hmac-sha3/api/hmac-sha3.klib.api b/library/hmac/hmac-sha3/api/hmac-sha3.klib.api new file mode 100644 index 0000000..5ff2195 --- /dev/null +++ b/library/hmac/hmac-sha3/api/hmac-sha3.klib.api @@ -0,0 +1,39 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +final class org.kotlincrypto.macs.hmac.sha3/HmacKeccak224 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacKeccak224|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacKeccak224.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacKeccak256 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacKeccak256|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacKeccak256.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacKeccak384 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacKeccak384|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacKeccak384.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacKeccak512 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacKeccak512|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacKeccak512.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacSHA3_224 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_224|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_224.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacSHA3_256 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_256|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_256.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacSHA3_384 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_384|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_384.|(kotlin.ByteArray){}[0] +} + +final class org.kotlincrypto.macs.hmac.sha3/HmacSHA3_512 : org.kotlincrypto.macs.hmac/Hmac { // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_512|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.hmac.sha3/HmacSHA3_512.|(kotlin.ByteArray){}[0] +} diff --git a/library/hmac/hmac/api/hmac.klib.api b/library/hmac/hmac/api/hmac.klib.api new file mode 100644 index 0000000..f7215ad --- /dev/null +++ b/library/hmac/hmac/api/hmac.klib.api @@ -0,0 +1,9 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +abstract class org.kotlincrypto.macs.hmac/Hmac : org.kotlincrypto.core.mac/Mac // org.kotlincrypto.macs.hmac/Hmac|null[0] diff --git a/library/kmac/api/kmac.klib.api b/library/kmac/api/kmac.klib.api new file mode 100644 index 0000000..6ce74b6 --- /dev/null +++ b/library/kmac/api/kmac.klib.api @@ -0,0 +1,50 @@ +// Klib ABI Dump +// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +final class org.kotlincrypto.macs.kmac/KMAC128 : org.kotlincrypto.macs.kmac/Kmac { // org.kotlincrypto.macs.kmac/KMAC128|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.kmac/KMAC128.|(kotlin.ByteArray){}[0] + constructor (kotlin/ByteArray, kotlin/ByteArray?) // org.kotlincrypto.macs.kmac/KMAC128.|(kotlin.ByteArray;kotlin.ByteArray?){}[0] + constructor (kotlin/ByteArray, kotlin/ByteArray?, kotlin/Int) // org.kotlincrypto.macs.kmac/KMAC128.|(kotlin.ByteArray;kotlin.ByteArray?;kotlin.Int){}[0] + + final object Companion : org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory { // org.kotlincrypto.macs.kmac/KMAC128.Companion|null[0] + final const val MAC_LENGTH // org.kotlincrypto.macs.kmac/KMAC128.Companion.MAC_LENGTH|(){}[0] + final fun (): kotlin/Int // org.kotlincrypto.macs.kmac/KMAC128.Companion.MAC_LENGTH.|(){}[0] + + final fun xOf(kotlin/ByteArray, kotlin/ByteArray? =...): org.kotlincrypto.core.xof/Xof // org.kotlincrypto.macs.kmac/KMAC128.Companion.xOf|xOf(kotlin.ByteArray;kotlin.ByteArray?){}[0] + } +} + +final class org.kotlincrypto.macs.kmac/KMAC256 : org.kotlincrypto.macs.kmac/Kmac { // org.kotlincrypto.macs.kmac/KMAC256|null[0] + constructor (kotlin/ByteArray) // org.kotlincrypto.macs.kmac/KMAC256.|(kotlin.ByteArray){}[0] + constructor (kotlin/ByteArray, kotlin/ByteArray?) // org.kotlincrypto.macs.kmac/KMAC256.|(kotlin.ByteArray;kotlin.ByteArray?){}[0] + constructor (kotlin/ByteArray, kotlin/ByteArray?, kotlin/Int) // org.kotlincrypto.macs.kmac/KMAC256.|(kotlin.ByteArray;kotlin.ByteArray?;kotlin.Int){}[0] + + final object Companion : org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory { // org.kotlincrypto.macs.kmac/KMAC256.Companion|null[0] + final const val MAC_LENGTH // org.kotlincrypto.macs.kmac/KMAC256.Companion.MAC_LENGTH|(){}[0] + final fun (): kotlin/Int // org.kotlincrypto.macs.kmac/KMAC256.Companion.MAC_LENGTH.|(){}[0] + + final fun xOf(kotlin/ByteArray, kotlin/ByteArray? =...): org.kotlincrypto.core.xof/Xof // org.kotlincrypto.macs.kmac/KMAC256.Companion.xOf|xOf(kotlin.ByteArray;kotlin.ByteArray?){}[0] + } +} + +sealed class org.kotlincrypto.macs.kmac/Kmac : org.kotlincrypto.core.mac/Mac, org.kotlincrypto.core.xof/XofAlgorithm { // org.kotlincrypto.macs.kmac/Kmac|null[0] + constructor (kotlin/ByteArray, kotlin/ByteArray?, kotlin/Int, kotlin/Int, kotlin/Boolean) // org.kotlincrypto.macs.kmac/Kmac.|(kotlin.ByteArray;kotlin.ByteArray?;kotlin.Int;kotlin.Int;kotlin.Boolean){}[0] + constructor (org.kotlincrypto.core.mac/Mac.Engine) // org.kotlincrypto.macs.kmac/Kmac.|(org.kotlincrypto.core.mac.Mac.Engine){}[0] + + sealed class <#A1: org.kotlincrypto.macs.kmac/Kmac> KMACXofFactory : org.kotlincrypto.core.xof/XofFactory<#A1> { // org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory|null[0] + constructor () // org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory.|(){}[0] + + final inner class KMACXof : org.kotlincrypto.core.xof/XofFactory.XofDelegate<#A1> { // org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory.KMACXof|null[0] + constructor (#A1) // org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory.KMACXof.|(2:0){}[0] + + final fun copy(): org.kotlincrypto.core.xof/Xof<#A1> // org.kotlincrypto.macs.kmac/Kmac.KMACXofFactory.KMACXof.copy|copy(){}[0] + } + } + + final object Companion // org.kotlincrypto.macs.kmac/Kmac.Companion|null[0] +} diff --git a/test-android/api/test-android.klib.api b/test-android/api/test-android.klib.api new file mode 100644 index 0000000..e69de29 From e2dc7f4bc78fb46f2108d215a1f40bf819419035 Mon Sep 17 00:00:00 2001 From: Matthew Nelson Date: Sat, 31 Aug 2024 02:29:07 -0400 Subject: [PATCH 2/2] Add CI check for API compatibility --- .github/workflows/CI.yml | 41 +++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 964b65d..9dcbe7f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -11,6 +11,7 @@ jobs: fail-fast: false matrix: os: [ macos-latest, ubuntu-latest, windows-latest ] + java-version: [ 11, 19 ] runs-on: ${{ matrix.os }} @@ -42,33 +43,43 @@ jobs: key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('gradle/libs.versions.toml') }} restore-keys: ${{ runner.os }}-gradle-caches- - # Windows does not build ANDROID, but needs Java 11 for JPMS Multi-Release Jar build - - name: Setup JDK 11 - if: matrix.os == 'windows-latest' + - name: Setup JDK uses: actions/setup-java@v3.4.0 with: distribution: 'zulu' - java-version: 11 + java-version: ${{ matrix.java-version }} - - name: Setup JDK 19 - if: matrix.os != 'windows-latest' - uses: actions/setup-java@v3.4.0 - with: - distribution: 'zulu' - java-version: 19 + - name: Check API Compatibility + if: matrix.os == 'macos-latest' && matrix.java-version == 19 + run: > + ./gradlew apiCheck --stacktrace - name: Run macOS Tests - if: matrix.os == 'macos-latest' + if: matrix.os == 'macos-latest' && matrix.java-version == 19 run: > ./gradlew check --stacktrace - -PKMP_TARGETS="JVM,JS,IOS_ARM64,IOS_X64,IOS_SIMULATOR_ARM64,MACOS_ARM64,MACOS_X64,TVOS_ARM64,TVOS_X64,TVOS_SIMULATOR_ARM64,WATCHOS_ARM32,WATCHOS_ARM64,WATCHOS_DEVICE_ARM64,WATCHOS_X64,WATCHOS_SIMULATOR_ARM64,WASM_JS,WASM_WASI" + -PKMP_TARGETS="IOS_ARM64,IOS_X64,IOS_SIMULATOR_ARM64,JVM,MACOS_ARM64,MACOS_X64,TVOS_ARM64,TVOS_X64,TVOS_SIMULATOR_ARM64,WATCHOS_ARM32,WATCHOS_ARM64,WATCHOS_DEVICE_ARM64,WATCHOS_X64,WATCHOS_SIMULATOR_ARM64" + + - name: Run macOS Java11 Tests + if: matrix.os == 'macos-latest' && matrix.java-version == 11 + run: > + ./gradlew check --stacktrace + -PKMP_TARGETS="JS,JVM,WASM_JS,WASM_WASI" + - name: Run Linux Tests - if: matrix.os == 'ubuntu-latest' + if: matrix.os == 'ubuntu-latest' && matrix.java-version == 19 + run: > + ./gradlew check --stacktrace + -PKMP_TARGETS="ANDROID,ANDROID_ARM32,ANDROID_ARM64,ANDROID_X64,ANDROID_X86,JVM,LINUX_ARM64,LINUX_X64" + + - name: Run Linux Java11 Tests + if: matrix.os == 'ubuntu-latest' && matrix.java-version == 11 run: > ./gradlew check --stacktrace - -PKMP_TARGETS="JVM,JS,ANDROID,ANDROID_ARM32,ANDROID_ARM64,ANDROID_X64,ANDROID_X86,LINUX_ARM64,LINUX_X64,WASM_JS,WASM_WASI" + -PKMP_TARGETS="JS,JVM,WASM_JS,WASM_WASI" + - name: Run Windows Tests - if: matrix.os == 'windows-latest' + if: matrix.os == 'windows-latest' && matrix.java-version == 11 run: > ./gradlew check --stacktrace -PKMP_TARGETS="JVM,JS,MINGW_X64,WASM_JS,WASM_WASI"