Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/api-compat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: API Compatibility Check
on:
pull_request:
permissions:
contents: read
jobs:
api-compat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
with:
distribution: temurin
java-version: '17'

- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0

- name: Check API Compatibility
run: ./gradlew :device-sdk:japicmp
6 changes: 5 additions & 1 deletion dev-bin/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ perl -pi -e "s/version = \"[^\"]+\"/version = \"$version\"/" build.gradle.kts
# Update version in README.md
perl -pi -e "s/com\.maxmind\.device:device-sdk:[0-9]+\.[0-9]+\.[0-9]+[a-zA-Z0-9\-]*/com.maxmind.device:device-sdk:$version/g" README.md

# Update baselineVersion in device-sdk/build.gradle.kts for API compatibility checking
# This ensures the next PR compares against this newly released version
perl -pi -e "s/val baselineVersion = \"[^\"]+\"/val baselineVersion = \"$version\"/" device-sdk/build.gradle.kts

git diff

read -r -n 1 -p "Commit changes? (y/n) " should_commit
Expand All @@ -135,7 +139,7 @@ if [ "$should_commit" != "y" ]; then
exit 1
fi

git add build.gradle.kts README.md
git add build.gradle.kts README.md device-sdk/build.gradle.kts
git commit -m "Preparing for $version"

# Build and publish to Maven Central
Expand Down
58 changes: 58 additions & 0 deletions device-sdk/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.net.URI

plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
Expand All @@ -8,6 +10,7 @@ plugins {
alias(libs.plugins.maven.publish)
signing
id("tech.apter.junit5.jupiter.robolectric-extension-gradle-plugin") version "0.9.0"
id("me.champeau.gradle.japicmp") version "0.4.5"
}

android {
Expand Down Expand Up @@ -168,3 +171,58 @@ mavenPublishing {
signing {
useGpgCmd()
}

// API compatibility checking with japicmp
// Compares the current build against the latest released version on Maven Central
// Update this version after each release (the release script should do this automatically)
val baselineVersion = "0.1.0"

// Download baseline AAR directly from Maven Central to avoid local project resolution
val downloadBaselineAar by tasks.registering {
val outputFile = layout.buildDirectory.file("japicmp/baseline.aar")
outputs.file(outputFile)
doLast {
val url = "https://repo1.maven.org/maven2/com/maxmind/device/device-sdk/$baselineVersion/device-sdk-$baselineVersion.aar"
val destFile = outputFile.get().asFile
destFile.parentFile.mkdirs()
URI(url).toURL().openStream().use { input ->
destFile.outputStream().use { output ->
input.copyTo(output)
}
}
logger.lifecycle("Downloaded baseline AAR from $url")
}
}

// Extract classes.jar from baseline AAR for comparison
val extractBaselineClasses by tasks.registering(Copy::class) {
dependsOn(downloadBaselineAar)
from(zipTree(layout.buildDirectory.file("japicmp/baseline.aar"))) {
include("classes.jar")
}
into(layout.buildDirectory.dir("japicmp/baseline"))
}

// Extract classes.jar from current AAR for comparison
val extractCurrentClasses by tasks.registering(Copy::class) {
dependsOn("bundleReleaseAar")
from(zipTree(layout.buildDirectory.file("outputs/aar/device-sdk-release.aar"))) {
include("classes.jar")
}
into(layout.buildDirectory.dir("japicmp/current"))
}

tasks.register<me.champeau.gradle.japicmp.JapicmpTask>("japicmp") {
dependsOn(extractBaselineClasses, extractCurrentClasses)
oldClasspath.from(layout.buildDirectory.file("japicmp/baseline/classes.jar"))
newClasspath.from(layout.buildDirectory.file("japicmp/current/classes.jar"))
oldArchives.from(layout.buildDirectory.file("japicmp/baseline/classes.jar"))
newArchives.from(layout.buildDirectory.file("japicmp/current/classes.jar"))
accessModifier.set("public")
onlyModified.set(true)
failOnModification.set(true)
includeSynthetic.set(false)
ignoreMissingClasses.set(true)
txtOutputFile.set(layout.buildDirectory.file("japicmp/report.txt"))
htmlOutputFile.set(layout.buildDirectory.file("japicmp/report.html"))
}
Loading