diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8a69c7dc52..c0994dbbc1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -57,8 +57,14 @@ jobs: if: matrix.os == 'ubuntu-latest' run: sudo apt-get install -y libtinfo5 - # Build unless this is a cross-compile. - - run: ./gradlew build --stacktrace + # Build unless this is a cross-compile (we can't test cross-compiled code) + - name: Build Zipline + run: ./gradlew build --stacktrace + if: matrix.arch == 'amd64' || matrix.arch == 'x86_64' + + # Build unless this is a cross-compile + - name: Build samples + run: ./gradlew -p samples check --stacktrace if: matrix.arch == 'amd64' || matrix.arch == 'x86_64' - uses: actions/upload-artifact@v3 diff --git a/build.gradle.kts b/build.gradle.kts index 1a914bf085..1d84cca778 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -112,7 +112,7 @@ allprojects { Visibility.PROTECTED )) reportUndocumented.set(false) - jdkVersion.set(8) + jdkVersion.set(11) perPackageOption { matchingRegex.set("app\\.cash\\.zipline\\.internal\\..*") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cde3c052f2..8a07c93cfa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] androidx-compose = "1.4.3" -androidx-compose-compiler = "1.4.7" +androidx-compose-compiler = "1.4.5" auto-service="1.1.1" compileSdk = "33" http4k = "4.48.0.0" @@ -22,7 +22,7 @@ androidx-annotation = { module = "androidx.annotation:annotation", version = "1. androidx-appCompat = { module = "androidx.appcompat:appcompat", version = "1.6.1" } # This isn't strictly used, but allows Renovate to see us using the Compose Compiler artifact androidx-compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "androidx-compose-compiler" } -androidx-compose-material = { module = "androidx.compose.material:material", version = "androidx-compose" } +androidx-compose-material = { module = "androidx.compose.material:material", version.ref = "androidx-compose" } androidx-compose-ui = { module = "androidx.compose.ui:ui", version.ref = "androidx-compose" } androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "androidx-compose" } androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "androidx-compose" } diff --git a/samples/build.gradle.kts b/samples/build.gradle.kts index bf57828083..0c00a8f10b 100644 --- a/samples/build.gradle.kts +++ b/samples/build.gradle.kts @@ -1,3 +1,7 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + buildscript { dependencies { classpath(libs.android.gradle.plugin) @@ -20,3 +24,21 @@ allprojects { google() } } + +allprojects { + plugins.withId("org.jetbrains.kotlin.multiplatform") { + configure { + jvmToolchain(11) + } + } + plugins.withId("org.jetbrains.kotlin.jvm") { + configure { + jvmToolchain(11) + } + } + plugins.withId("org.jetbrains.kotlin.android") { + configure { + jvmToolchain(11) + } + } +} diff --git a/samples/trivia/trivia-shared/api/zipline-api.toml b/samples/trivia/trivia-shared/api/zipline-api.toml new file mode 100644 index 0000000000..30a8bb5e9c --- /dev/null +++ b/samples/trivia/trivia-shared/api/zipline-api.toml @@ -0,0 +1,12 @@ +[app.cash.zipline.samples.trivia.TriviaService] + +functions = [ + # fun answer(kotlin.Int, kotlin.Int, kotlin.String): app.cash.zipline.samples.trivia.AnswerResult + "zqfiWcT7", + + # fun close(): kotlin.Unit + "moYx+T3e", + + # fun games(): kotlin.collections.List + "CpVBWiWi", +] diff --git a/samples/world-clock/android/build.gradle.kts b/samples/world-clock/android/build.gradle.kts index 962116692f..413029bddc 100644 --- a/samples/world-clock/android/build.gradle.kts +++ b/samples/world-clock/android/build.gradle.kts @@ -11,14 +11,13 @@ android { defaultConfig { applicationId = "com.example.zipline.worldclock" - minSdk = 21 - targetSdk = 33 + minSdk = libs.versions.compileSdk.get().toInt() } compileOptions { isCoreLibraryDesugaringEnabled = true - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } buildFeatures { diff --git a/samples/world-clock/presenters/api/zipline-api.toml b/samples/world-clock/presenters/api/zipline-api.toml new file mode 100644 index 0000000000..a442fa16d2 --- /dev/null +++ b/samples/world-clock/presenters/api/zipline-api.toml @@ -0,0 +1,19 @@ +[app.cash.zipline.samples.worldclock.WorldClockHost] + +functions = [ + # fun close(): kotlin.Unit + "moYx+T3e", + + # fun timeZones(): kotlin.collections.List + "GaZNl/pB", +] + +[app.cash.zipline.samples.worldclock.WorldClockPresenter] + +functions = [ + # fun close(): kotlin.Unit + "moYx+T3e", + + # fun models(kotlinx.coroutines.flow.Flow): kotlinx.coroutines.flow.Flow + "GXtzhRC8", +] diff --git a/samples/world-clock/presenters/build.gradle.kts b/samples/world-clock/presenters/build.gradle.kts index 0129c24957..5a69cad75b 100644 --- a/samples/world-clock/presenters/build.gradle.kts +++ b/samples/world-clock/presenters/build.gradle.kts @@ -52,6 +52,13 @@ kotlin { android { compileSdk = libs.versions.compileSdk.get().toInt() namespace = "app.cash.zipline.samples.worldclock.presenters" + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } } zipline { diff --git a/zipline-gradle-plugin/build.gradle.kts b/zipline-gradle-plugin/build.gradle.kts index 164f64475a..58fbb12871 100644 --- a/zipline-gradle-plugin/build.gradle.kts +++ b/zipline-gradle-plugin/build.gradle.kts @@ -64,12 +64,19 @@ gradlePlugin { tasks { test { + // The test in 'src/test/projects/android' needs Java 17+. + javaLauncher.set( + project.javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(17)) + } + ) systemProperty("ziplineVersion", project.version) dependsOn(":zipline-bytecode:publishAllPublicationsToTestMavenRepository") dependsOn(":zipline-gradle-plugin:publishAllPublicationsToTestMavenRepository") dependsOn(":zipline-kotlin-plugin:publishAllPublicationsToTestMavenRepository") dependsOn(":zipline-loader:publishJvmPublicationToTestMavenRepository") dependsOn(":zipline-loader:publishKotlinMultiplatformPublicationToTestMavenRepository") + dependsOn(":zipline:publishAndroidReleasePublicationToTestMavenRepository") dependsOn(":zipline:publishJsPublicationToTestMavenRepository") dependsOn(":zipline:publishJvmPublicationToTestMavenRepository") dependsOn(":zipline:publishKotlinMultiplatformPublicationToTestMavenRepository") diff --git a/zipline-gradle-plugin/src/main/kotlin/app/cash/zipline/gradle/ZiplinePlugin.kt b/zipline-gradle-plugin/src/main/kotlin/app/cash/zipline/gradle/ZiplinePlugin.kt index 98952b8406..1e86671fb2 100644 --- a/zipline-gradle-plugin/src/main/kotlin/app/cash/zipline/gradle/ZiplinePlugin.kt +++ b/zipline-gradle-plugin/src/main/kotlin/app/cash/zipline/gradle/ZiplinePlugin.kt @@ -15,8 +15,10 @@ */ package app.cash.zipline.gradle +import app.cash.zipline.gradle.ZiplineApiValidationTask.Mode import app.cash.zipline.loader.SignatureAlgorithmId import org.gradle.api.Project +import org.gradle.api.Task import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension @@ -77,11 +79,15 @@ class ZiplinePlugin : KotlinCompilerPluginSupportPlugin { } } + val ziplineApiCheck = target.tasks.register("ziplineApiCheck") + target.tasks.named("check").configure { checkTask -> + checkTask.dependsOn(ziplineApiCheck) + } + val ziplineApiDump = target.tasks.register("ziplineApiDump") target.tasks.withType(KotlinCompile::class.java) { kotlinCompile -> - if (kotlinCompile.name == "compileKotlinJvm") { - registerZiplineApiTask(target, kotlinCompile, ZiplineApiValidationTask.Mode.Check) - registerZiplineApiTask(target, kotlinCompile, ZiplineApiValidationTask.Mode.Dump) - } + if ("Test" in kotlinCompile.name) return@withType + registerZiplineApiTask(target, kotlinCompile, Mode.Check, ziplineApiCheck) + registerZiplineApiTask(target, kotlinCompile, Mode.Dump, ziplineApiDump) } } @@ -117,18 +123,17 @@ class ZiplinePlugin : KotlinCompilerPluginSupportPlugin { private fun registerZiplineApiTask( project: Project, compileTask: KotlinCompileTool, - mode: ZiplineApiValidationTask.Mode, + mode: Mode, + rollupTask: TaskProvider, ) { val task = project.tasks.register( - "ziplineApi$mode", + "${compileTask.name}ZiplineApi$mode", // Like 'compileKotlinJvmZiplineApiCheck' ZiplineApiValidationTask::class.java, mode, ) - if (mode == ZiplineApiValidationTask.Mode.Check) { - project.tasks.named("check").configure { checkTask -> - checkTask.dependsOn(task) - } + rollupTask.configure { + it.dependsOn(task) } task.configure { task -> diff --git a/zipline-gradle-plugin/src/test/kotlin/app/cash/zipline/gradle/ZiplinePluginTest.kt b/zipline-gradle-plugin/src/test/kotlin/app/cash/zipline/gradle/ZiplinePluginTest.kt index ad8c357190..fdddd02341 100644 --- a/zipline-gradle-plugin/src/test/kotlin/app/cash/zipline/gradle/ZiplinePluginTest.kt +++ b/zipline-gradle-plugin/src/test/kotlin/app/cash/zipline/gradle/ZiplinePluginTest.kt @@ -407,6 +407,22 @@ class ZiplinePluginTest { } } + /** Confirm ziplineApiDump tasks are available on non-JVM projects. */ + @Test + fun ziplineApiDumpOnAndroidProject() { + val projectDir = File("src/test/projects/android") + val ziplineApiToml = projectDir.resolve("lib/api/zipline-api.toml") + ziplineApiToml.delete() // In case a previous execution crashed. + + try { + val taskName = ":lib:ziplineApiDump" + createRunner(projectDir, "clean", taskName).build() + assertThat(ziplineApiToml.exists()).isTrue() + } finally { + ziplineApiToml.delete() + } + } + private fun createRunner(projectDir: File, vararg taskNames: String): GradleRunner { val gradleRoot = projectDir.resolve("gradle").also { it.mkdir() } File("../gradle/wrapper").copyRecursively(gradleRoot.resolve("wrapper"), true) diff --git a/zipline-gradle-plugin/src/test/projects/android/build.gradle.kts b/zipline-gradle-plugin/src/test/projects/android/build.gradle.kts new file mode 100644 index 0000000000..30c3b3e904 --- /dev/null +++ b/zipline-gradle-plugin/src/test/projects/android/build.gradle.kts @@ -0,0 +1,24 @@ +buildscript { + repositories { + maven { + url = file("$rootDir/../../../../../build/testMaven").toURI() + } + mavenCentral() + google() + } + dependencies { + classpath("app.cash.zipline:zipline-gradle-plugin:${project.property("ziplineVersion")}") + classpath(libs.android.gradle.plugin) + classpath(libs.kotlin.gradle.plugin) + } +} + +allprojects { + repositories { + maven { + url = file("$rootDir/../../../../../build/testMaven").toURI() + } + mavenCentral() + google() + } +} diff --git a/zipline-gradle-plugin/src/test/projects/android/gradle.properties b/zipline-gradle-plugin/src/test/projects/android/gradle.properties new file mode 100644 index 0000000000..09df15edb6 --- /dev/null +++ b/zipline-gradle-plugin/src/test/projects/android/gradle.properties @@ -0,0 +1,2 @@ +kotlin.js.compiler=ir +android.useAndroidX=true diff --git a/zipline-gradle-plugin/src/test/projects/android/lib/build.gradle.kts b/zipline-gradle-plugin/src/test/projects/android/lib/build.gradle.kts new file mode 100644 index 0000000000..99ec5e0cea --- /dev/null +++ b/zipline-gradle-plugin/src/test/projects/android/lib/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + kotlin("multiplatform") + id("com.android.library") + id("app.cash.zipline") +} + +kotlin { + android() + js { + browser() + binaries.executable() + } + + sourceSets { + commonMain { + dependencies { + implementation("app.cash.zipline:zipline:${project.property("ziplineVersion")}") + } + } + } +} + +android { + namespace = "app.cash.zipline.tests.android" + compileSdk = libs.versions.compileSdk.get().toInt() +} diff --git a/zipline-gradle-plugin/src/test/projects/android/lib/src/commonMain/kotlin/app/cash/zipline/tests/GreetService.kt b/zipline-gradle-plugin/src/test/projects/android/lib/src/commonMain/kotlin/app/cash/zipline/tests/GreetService.kt new file mode 100644 index 0000000000..6ee1e44557 --- /dev/null +++ b/zipline-gradle-plugin/src/test/projects/android/lib/src/commonMain/kotlin/app/cash/zipline/tests/GreetService.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 Cash App + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.cash.zipline.tests + +import app.cash.zipline.ZiplineService + +interface GreetService : ZiplineService { + fun greet(name: String): String +} diff --git a/zipline-gradle-plugin/src/test/projects/android/settings.gradle.kts b/zipline-gradle-plugin/src/test/projects/android/settings.gradle.kts new file mode 100644 index 0000000000..78eeed4af8 --- /dev/null +++ b/zipline-gradle-plugin/src/test/projects/android/settings.gradle.kts @@ -0,0 +1,9 @@ +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../../../../gradle/libs.versions.toml")) + } + } +} + +include(":lib")