Skip to content

Commit 1f21863

Browse files
committed
chore: enable Kotlin explicitApi() and Binary Compatibility Validator (.api dumps)
- Enable kotlin explicitApi() across published modules (:library, :clustering, :data, :heatmaps, :ui) - Add explicit public visibility and return types to all public Kotlin symbols across modules - Configure Binary Compatibility Validator (BCV) for AGP 9.3 via build-logic convention plugin and root aggregate tasks - Generate and commit baseline .api dumps for :library, :clustering, :data, :heatmaps, and :ui - Add apiCheck to the CI Pull Request test workflow Fixes #1794
1 parent e7d9d13 commit 1f21863

98 files changed

Lines changed: 4680 additions & 801 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/test.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ jobs:
4646
run: echo "MAPS_API_KEY=dummy" > secrets.properties
4747

4848
- name: Build modules
49-
run: ./gradlew build koverXmlReportDebug --stacktrace
49+
run: ./gradlew build apiCheck koverXmlReportDebug --stacktrace

‎build-logic/convention/build.gradle.kts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ dependencies {
3030
implementation(libs.dokka.gradle.plugin)
3131
implementation(libs.kover.gradle.plugin)
3232
implementation(libs.gradle.maven.publish.plugin)
33+
implementation(libs.binary.compatibility.validator)
3334
}
3435

3536
gradlePlugin {

‎build-logic/convention/src/main/kotlin/PublishingConventionPlugin.kt‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
import com.vanniktech.maven.publish.AndroidSingleVariantLibrary
1919
import com.vanniktech.maven.publish.MavenPublishBaseExtension
2020
import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension
21+
import kotlinx.validation.KotlinApiBuildTask
22+
import kotlinx.validation.KotlinApiCompareTask
2123
import org.gradle.api.Plugin
2224
import org.gradle.api.Project
25+
import org.gradle.api.tasks.Copy
2326
import org.gradle.kotlin.dsl.*
2427

2528
class PublishingConventionPlugin : Plugin<Project> {
@@ -28,6 +31,7 @@ class PublishingConventionPlugin : Plugin<Project> {
2831
applyPlugins()
2932
configureKover()
3033
configureVanniktechPublishing()
34+
configureBinaryCompatibilityValidator()
3135
}
3236
}
3337

@@ -106,4 +110,65 @@ class PublishingConventionPlugin : Plugin<Project> {
106110
}
107111
}
108112
}
113+
114+
private fun Project.configureBinaryCompatibilityValidator() {
115+
val ignoredProjects = setOf("demo", "visual-testing", "lint-checks", "maps-utils")
116+
if (name in ignoredProjects) return
117+
118+
val projectName = name
119+
val apiFile = layout.projectDirectory.file("api/$projectName.api")
120+
val buildApiFile = layout.buildDirectory.file("api/$projectName.api")
121+
122+
afterEvaluate {
123+
val bundleTask = tasks.findByName("bundleLibCompileToJarRelease") ?: return@afterEvaluate
124+
val classesJar = layout.buildDirectory.file(
125+
"intermediates/compile_library_classes_jar/release/bundleLibCompileToJarRelease/classes.jar"
126+
)
127+
128+
val apiBuild = tasks.register<KotlinApiBuildTask>("apiBuild") {
129+
group = "verification"
130+
description = "Builds public API declaration for $projectName."
131+
inputJar.set(classesJar)
132+
outputApiFile.set(buildApiFile)
133+
ignoredClasses.addAll(
134+
"com.google.maps.android.R",
135+
"com.google.maps.android.clustering.R",
136+
"com.google.maps.android.data.R",
137+
"com.google.maps.android.heatmaps.R",
138+
"com.google.maps.android.ui.R",
139+
"com.google.maps.android.BuildConfig",
140+
"com.google.maps.android.clustering.BuildConfig",
141+
"com.google.maps.android.data.BuildConfig",
142+
"com.google.maps.android.heatmaps.BuildConfig",
143+
"com.google.maps.android.ui.BuildConfig",
144+
)
145+
dependsOn(bundleTask)
146+
}
147+
148+
val apiDump = tasks.register<Copy>("apiDump") {
149+
group = "verification"
150+
description = "Syncs public API declarations of $projectName to the project api/ directory."
151+
from(apiBuild.flatMap { it.outputApiFile })
152+
into(apiFile.asFile.parentFile)
153+
dependsOn(apiBuild)
154+
}
155+
156+
val apiCheck = tasks.register<KotlinApiCompareTask>("apiCheck") {
157+
group = "verification"
158+
description = "Checks public API declarations of $projectName against the committed api/$projectName.api."
159+
projectApiFile.set(apiFile)
160+
generatedApiFile.set(apiBuild.flatMap { it.outputApiFile })
161+
dependsOn(apiBuild)
162+
}
163+
164+
tasks.findByName("check")?.dependsOn(apiCheck)
165+
166+
rootProject.tasks.matching { it.name == "apiDump" }.configureEach {
167+
dependsOn(apiDump)
168+
}
169+
rootProject.tasks.matching { it.name == "apiCheck" }.configureEach {
170+
dependsOn(apiCheck)
171+
}
172+
}
173+
}
109174
}

‎build.gradle.kts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@ import java.util.Properties
1919

2020
plugins {
2121
id("com.vanniktech.maven.publish") version libs.versions.gradleMavenPublishPlugin.get() apply false
22+
alias(libs.plugins.binary.compatibility.validator)
23+
}
24+
25+
apiValidation {
26+
ignoredProjects += listOf("demo", "visual-testing", "lint-checks", "maps-utils")
27+
}
28+
29+
val apiDump = tasks.register("apiDump") {
30+
group = "verification"
31+
description = "Dumps public API declarations for all library modules."
32+
}
33+
34+
val apiCheck = tasks.register("apiCheck") {
35+
group = "verification"
36+
description = "Checks that public API declarations match the committed .api files."
2237
}
2338

2439
buildscript {

0 commit comments

Comments
 (0)