From c84f189351ace9d8d7d4940530f35b747415521e Mon Sep 17 00:00:00 2001 From: Seokju Na Date: Sun, 21 Jun 2026 13:35:54 +0900 Subject: [PATCH] add publish workflow --- .github/workflows/publish.yaml | 30 ++++++++++++++++++++++ gradle.properties | 1 - gradle/libs.versions.toml | 10 +++++--- lib/build.gradle.kts | 47 ++++++++++++++++++++++++++++++++++ lib/consumer-rules.pro | 22 +++++++++++----- 5 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..3956a97 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,30 @@ +name: publish +on: + push: + tags: + - 'v*' +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false +permissions: + contents: read +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 + - uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # 4.0.1 + - name: Install ffi + run: node scripts/install.mjs + env: + GITHUB_TOKEN: ${{ github.token }} + - name: Derive version from tag + # Strip the leading "v": refs/tags/v0.1.0 -> 0.1.0 + run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV" + - name: Publish to Maven Central + run: ./gradlew :lib:publishToMavenCentral -PVERSION="$VERSION" --no-configuration-cache + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_IN_MEMORY_KEY_PASSWORD }} diff --git a/gradle.properties b/gradle.properties index 15050e9..d4380a8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,4 +9,3 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=1g -Dfile.encoding=UTF-8 # Required by the androidx.webkit dependency (optional service-worker interception). android.useAndroidX=true - diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f0ee802..be7d445 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,9 @@ androidx-webkit = "1.12.1" jna = "5.17.0" kotlin = "2.3.21" kotlinx-coroutines = "1.10.2" +# 0.35.0 is the last release whose minimum AGP is 8.2.2 (works with our AGP +# 8.10.1); 0.36.0+ require AGP 8.13.0. It targets the Central Portal by default. +maven-publish = "0.35.0" [libraries] androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" } @@ -18,6 +21,7 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-corou kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } [plugins] -android-application = { id = "com.android.application", version.ref = "android-gradle-plugin" } -android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } \ No newline at end of file +android-application = { id = "com.android.application", version.ref = "android-gradle-plugin" } +android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "maven-publish" } \ No newline at end of file diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index c051f79..d99f85e 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -1,8 +1,13 @@ +import com.vanniktech.maven.publish.AndroidSingleVariantLibrary + plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) + alias(libs.plugins.vanniktech.maven.publish) } +val publishVersion = (findProperty("VERSION") as String?) ?: "0.0.0-LOCAL" + android { namespace = "dev.wvb" compileSdk = 35 @@ -43,3 +48,45 @@ dependencies { implementation(libs.androidx.annotation) implementation(libs.androidx.webkit) } + +mavenPublishing { + configure( + AndroidSingleVariantLibrary( + variant = "release", + sourcesJar = true, + publishJavadocJar = true, + ), + ) + publishToMavenCentral() + signAllPublications() + + coordinates("dev.wvb", "webview-bundle-android", publishVersion) + + pom { + name = "webview-bundle-android" + description = "Android Kotlin package for WebViewBundle." + inceptionYear = "2024" + url = "https://github.com/webview-bundle/webview-bundle-android" + licenses { + license { + name = "MIT License" + url = "https://github.com/webview-bundle/webview-bundle-android/blob/main/LICENSE" + distribution = + "https://github.com/webview-bundle/webview-bundle-android/blob/main/LICENSE" + } + } + developers { + developer { + id = "seokju-na" + name = "Seokju Na" + url = "https://github.com/seokju-na" + } + } + scm { + url = "https://github.com/webview-bundle/webview-bundle-android" + connection = "scm:git:git://github.com/webview-bundle/webview-bundle-android.git" + developerConnection = + "scm:git:ssh://git@github.com/webview-bundle/webview-bundle-android.git" + } + } +} diff --git a/lib/consumer-rules.pro b/lib/consumer-rules.pro index a9457ec..21f8119 100644 --- a/lib/consumer-rules.pro +++ b/lib/consumer-rules.pro @@ -1,6 +1,16 @@ -# The `wvbAndroid` invoke bridge is reached only from JavaScript via -# @JavascriptInterface, so R8 sees no Kotlin/Java caller and would otherwise be -# free to strip or rename the exposed method in a minified consumer app. --keepclasseswithmembers,includedescriptorclasses class dev.wvb.** { - @android.webkit.JavascriptInterface ; -} +# WebViewBundle's native FFI bindings (lib/src/main/kotlin/dev/wvb/wvb_ffi.kt) +# are UniFFI-generated and call into the native library through JNA. JNA maps the +# Rust structs/callbacks by reflection and reads the field names from +# @Structure.FieldOrder annotations, so R8 in a minified consumer app must not +# rename/strip these classes, drop their members, or remove the annotations — any +# of which breaks the FFI at runtime (UnsatisfiedLinkError / struct mismatch). +# +# JNA does not bundle these rules in its own AAR, so the library ships them here +# (they are packaged into the published AAR and applied to consumers automatically). +# This is the same set Mozilla's UniFFI-based SDKs publish: +# https://github.com/mozilla/application-services/blob/main/proguard-rules-consumer-jna.pro +-dontwarn java.awt.* +-keepattributes RuntimeVisibleAnnotations,RuntimeInvisibleAnnotations,RuntimeVisibleTypeAnnotations,RuntimeInvisibleTypeAnnotations,AnnotationDefault,InnerClasses,EnclosingMethod,Signature +-keep class com.sun.jna.* { *; } +-keep class * extends com.sun.jna.* { *; } +-keepclassmembers class * extends com.sun.jna.* { public *; }