From a3c7c43ddbbc0f0e48ea1ec0f3280ef2e6112470 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Aug 2025 09:21:59 +0200 Subject: [PATCH 01/35] Update dependency gradle to v8.14.3 (#458) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4a0d6896..a3cabd9d 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ fladle { } tasks.wrapper.configure { - gradleVersion = '8.13' + gradleVersion = '8.14.3' } def isNonStable = { String version -> diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37f853b1..d4081da4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 71a0390b4dbff4568b07f8582df64a7e7111789f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Aug 2025 21:28:35 +0200 Subject: [PATCH 02/35] Update plugin com.gradle.develocity to v4.1.1 (#460) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 1fc5400d..110cffb3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,7 +7,7 @@ pluginManagement { } plugins { - id "com.gradle.develocity" version "4.1" + id "com.gradle.develocity" version "4.1.1" } include ':android-library-no-tests' From 14d352a5d5bc84ebe294c8912d44238be6a0653d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 24 Aug 2025 07:30:43 +0200 Subject: [PATCH 03/35] Update actions/checkout action to v5 (#461) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-build.yml | 2 +- .github/workflows/mkdocs-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 6d009949..aaa1a251 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -5,7 +5,7 @@ jobs: name: "Building" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: gradle/actions/wrapper-validation@v4 - name: "Set up JDK 11" uses: actions/setup-java@v4 diff --git a/.github/workflows/mkdocs-deploy.yml b/.github/workflows/mkdocs-deploy.yml index 959ef67e..598d0894 100644 --- a/.github/workflows/mkdocs-deploy.yml +++ b/.github/workflows/mkdocs-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout master - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Deploy docs uses: mhausenblas/mkdocs-deploy-gh-pages@1.26 From 0d2bdb87461bf77cd11dfd69c2c9e8fa1b6e3b6e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 24 Aug 2025 18:36:00 +0200 Subject: [PATCH 04/35] Update actions/setup-java action to v5 (#462) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index aaa1a251..72953930 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v5 - uses: gradle/actions/wrapper-validation@v4 - name: "Set up JDK 11" - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '11' From e1ffa74fd2645c84b25581feeb5b5f2bc7636275 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 16:54:21 +0200 Subject: [PATCH 05/35] Update publishing to maven central. --- docs/releasing.md | 9 ++-- fladle-plugin/build.gradle.kts | 86 +++++++++++----------------------- gradle/libs.versions.toml | 2 + 3 files changed, 35 insertions(+), 62 deletions(-) diff --git a/docs/releasing.md b/docs/releasing.md index 570fe6ce..4ef72ced 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -36,9 +36,10 @@ git tag v{{ fladle.next_release }} git push origin v{{ fladle.next_release }} ``` -* Upload to Maven Central +* Upload to Maven Central (this must run in two separate commands since they are from two different namespaces) ``` bash -./gradlew :fladle-plugin:publishAllPublicationsToMavenRepository -Pfladle.releaseMode -Dorg.gradle.internal.publish.checksums.insecure=true +./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.release +./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.release ``` * Upload to Gradle Plugin Portal ```bash @@ -46,8 +47,8 @@ git push origin v{{ fladle.next_release }} ``` * Release to Maven Central - * Login to Sonatype OSS Nexus: [https://oss.sonatype.org/](https://oss.sonatype.org/) - * Click on **Staging Repositories** + * Login to Maven Central Repository: [https://central.sonatype.com/](https://oss.sonatype.com/) + * Click on **Publish** * Merge the release branch to master ``` diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index d0bfac50..d5e7cf7c 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -15,8 +15,7 @@ plugins { `java-gradle-plugin` alias(libs.plugins.gradle.plugin.publish) alias(libs.plugins.kotlinter) - `maven-publish` - signing + alias(libs.plugins.vanniktech.publish) } // See https://github.com/slackhq/keeper/pull/11#issuecomment-579544375 for context @@ -57,66 +56,37 @@ gradlePlugin { } } -val isReleaseBuild : Boolean = !version.toString().endsWith("SNAPSHOT") +java { + withJavadocJar() + withSourcesJar() +} -val sonatypeUsername : String? by project -val sonatypePassword : String? by project +mavenPublishing { + publishToMavenCentral() + signAllPublications() -publishing { - repositories { - repositories { - maven { - val releasesRepoUrl = uri("https://central.sonatype.com/api/v1/publisher/deployments/upload/") - val snapshotsRepoUrl = uri("https://central.sonatype.com/repository/maven-snapshots/") - url = if (isReleaseBuild) releasesRepoUrl else snapshotsRepoUrl - credentials { - username = sonatypeUsername - password = sonatypePassword - } + pom { + name.set("Fladle") + description.set(project.description) + url.set("https://github.com/runningcode/fladle") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") } } - } - publications { - afterEvaluate { - named("fladlePluginMarkerMaven") { - pom.configureForFladle("Fladle") + developers { + developer { + id.set("runningcode") + name.set("Nelson Osacky") } - - named("pluginMaven") { - pom.configureForFladle("Fladle") - } - named("fulladlePluginMarkerMaven") { - pom.configureForFladle("Fulladle") - } - } - } -} - -signing { - isRequired = isReleaseBuild -} - -fun org.gradle.api.publish.maven.MavenPom.configureForFladle(pluginName: String) { - name.set(pluginName) - description.set(project.description) - url.set("https://github.com/runningcode/fladle") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") } - } - developers { - developer { - id.set("runningcode") - name.set("Nelson Osacky") + scm { + connection.set("scm:git:git://github.com/runningcode/fladle.git") + developerConnection.set("scm:git:ssh://github.com/runningcode/fladle.git") + url.set("https://github.com/runningcode/fladle") } } - scm { - connection.set("scm:git:git://github.com/runningcode/fladle.git") - developerConnection.set("scm:git:ssh://github.com/runningcode/fladle.git") - url.set("https://github.com/runningcode/fladle") - } } tasks.withType(Test::class.java).configureEach { @@ -134,10 +104,10 @@ tasks.withType(ValidatePlugins::class.java).configureEach { // Ensure Java 11 Compatibility. See https://github.com/runningcode/fladle/issues/246 tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).configureEach { - kotlinOptions { - jvmTarget = "11" - languageVersion = "1.7" - apiVersion = "1.7" + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11) + languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9064b167..1b5e6f7d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,8 @@ kotlinter = { id = "org.jmailen.kotlinter", version = "4.0.0" } gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "1.3.1" } +vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.34.0" } + kgp = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin"} agp = { id = "com.android.application", version.ref = "agp-version"} From cc3b401c695eb1977dfc9b0e12f35627baea1462 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 17:03:15 +0200 Subject: [PATCH 06/35] Prepare for next development iteration --- fladle-plugin/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index d5e7cf7c..b723fec3 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -1,7 +1,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent group = "com.osacky.flank.gradle" -version = "0.19.0" +version = "0.19.1-SNAPSHOT" description = "Easily Scale your Android Instrumentation Tests with Firebase Test Lab with Flank" repositories { From 72d08066f4dbb47e8f26c3da096ae6691d7de869 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 17:14:09 +0200 Subject: [PATCH 07/35] Update target sdk to 35 (#399) --- android-library-no-tests/build.gradle.kts | 2 +- .../flank/gradle/integration/FulladlePluginIntegrationTest.kt | 2 +- .../flank/gradle/integration/SanityWithAutoConfigureTest.kt | 2 +- .../java/com/osacky/flank/gradle/integration/VariantTests.kt | 4 ++-- .../resources/android-library-project-flavors/build.gradle | 4 ++-- .../src/test/resources/android-library-project/build.gradle | 4 ++-- .../src/test/resources/android-project-flavors/build.gradle | 4 ++-- fladle-plugin/src/test/resources/android-project/build.gradle | 4 ++-- .../src/test/resources/android-project2/build.gradle | 4 ++-- sample-android-library/build.gradle.kts | 2 +- sample-flavors-kotlin/build.gradle.kts | 2 +- sample-kotlin/build.gradle.kts | 2 +- sample/build.gradle | 4 ++-- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/android-library-no-tests/build.gradle.kts b/android-library-no-tests/build.gradle.kts index bed1b75d..a730466a 100644 --- a/android-library-no-tests/build.gradle.kts +++ b/android-library-no-tests/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } android { - compileSdk = 33 + compileSdk = 34 namespace = "com.osacky.flank.gradle.sample.library" defaultConfig { minSdk = 23 diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt index 6706b2e2..f0c21b46 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt @@ -941,7 +941,7 @@ class FulladlePluginIntegrationTest { id "com.android.application" } android { - compileSdk 33 + compileSdk 34 namespace "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt index 5db13232..64a5b67c 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt @@ -13,7 +13,7 @@ private const val COMMON_SCRIPT_PART = """ } android { - compileSdk 33 + compileSdk 34 namespace "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt index c0f9a0c5..b3139982 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt @@ -161,12 +161,12 @@ class VariantTests { mavenCentral() } android { - compileSdk 33 + compileSdk 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle b/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle index 73bcc57c..26fbdc39 100644 --- a/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle +++ b/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle @@ -3,10 +3,10 @@ plugins { } android { - compileSdk 33 + compileSdk 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-library-project/build.gradle b/fladle-plugin/src/test/resources/android-library-project/build.gradle index 7890fc20..966280e0 100644 --- a/fladle-plugin/src/test/resources/android-library-project/build.gradle +++ b/fladle-plugin/src/test/resources/android-library-project/build.gradle @@ -3,10 +3,10 @@ plugins { } android { - compileSdk 33 + compileSdk 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-project-flavors/build.gradle b/fladle-plugin/src/test/resources/android-project-flavors/build.gradle index f9e08150..feb12779 100644 --- a/fladle-plugin/src/test/resources/android-project-flavors/build.gradle +++ b/fladle-plugin/src/test/resources/android-project-flavors/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdk 33 + compileSdk 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-project/build.gradle b/fladle-plugin/src/test/resources/android-project/build.gradle index 3d71caaf..63157df7 100644 --- a/fladle-plugin/src/test/resources/android-project/build.gradle +++ b/fladle-plugin/src/test/resources/android-project/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdk 33 + compileSdk 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-project2/build.gradle b/fladle-plugin/src/test/resources/android-project2/build.gradle index 3cb2fa25..f3879001 100644 --- a/fladle-plugin/src/test/resources/android-project2/build.gradle +++ b/fladle-plugin/src/test/resources/android-project2/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdk 33 + compileSdk 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/sample-android-library/build.gradle.kts b/sample-android-library/build.gradle.kts index 751c6fca..39d747ad 100644 --- a/sample-android-library/build.gradle.kts +++ b/sample-android-library/build.gradle.kts @@ -18,7 +18,7 @@ fulladleModuleConfig { android { namespace = "com.osacky.flank.gradle.sample" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 23 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/sample-flavors-kotlin/build.gradle.kts b/sample-flavors-kotlin/build.gradle.kts index 551677fc..e87cb46f 100644 --- a/sample-flavors-kotlin/build.gradle.kts +++ b/sample-flavors-kotlin/build.gradle.kts @@ -6,7 +6,7 @@ plugins { android { namespace = "com.osacky.flank.gradle.sample.kotlin" - compileSdk = 33 + compileSdk = 34 defaultConfig { applicationId = "com.osacky.flank.gradle.sample.kotlin" minSdk = 23 diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/build.gradle.kts index 1e08d49e..da97ef22 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/build.gradle.kts @@ -6,7 +6,7 @@ plugins { android { namespace = "com.osacky.flank.gradle.sample.kotlin" - compileSdk = 33 + compileSdk = 34 defaultConfig { applicationId = "com.osacky.flank.gradle.sample.kotlin" minSdk = 23 diff --git a/sample/build.gradle b/sample/build.gradle index c2fc7529..8da390a9 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'kotlin-android' apply plugin: 'com.osacky.fladle' android { - compileSdk = 33 + compileSdk = 34 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From dbf364c4a60ab6d1879900dcbd8f81e47d1288cf Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 17:16:05 +0200 Subject: [PATCH 08/35] Fix passwords for publishing to maven central. --- .github/workflows/gradle-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 72953930..3424c563 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -18,4 +18,4 @@ jobs: run: ./gradlew assembleDebug assembleDebugAndroidTest printYml check :fladle-plugin:check - name: Publish Snapshot if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - run: ./gradlew :fladle-plugin:publishAllPublicationsToMavenRepository -Pfladle.releaseMode -PsonatypeUsername=${{ secrets.SONATYPE_USERNAME }} -PsonatypePassword=${{ secrets.SONATYPE_PASSWORD }} + run: ./gradlew :fladle-plugin:publishAllPublicationsToMavenRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralUsername=${{ secrets.SONATYPE_PASSWORD }} From f95a8ce0f30fae7f58f373922876903b20281ce8 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 17:18:30 +0200 Subject: [PATCH 09/35] Fix snapshot publication task --- .github/workflows/gradle-build.yml | 7 +++++-- docs/releasing.md | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 3424c563..9f940359 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -16,6 +16,9 @@ jobs: name: Setup Gradle - name: Check Fladle run: ./gradlew assembleDebug assembleDebugAndroidTest printYml check :fladle-plugin:check - - name: Publish Snapshot + - name: Publish Marker Snapshot if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - run: ./gradlew :fladle-plugin:publishAllPublicationsToMavenRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralUsername=${{ secrets.SONATYPE_PASSWORD }} + run: ./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository :fladle-plugin:publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralUsername=${{ secrets.SONATYPE_PASSWORD }} + - name: Publish Plugin Snapshot + if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} + run: ./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralUsername=${{ secrets.SONATYPE_PASSWORD }} diff --git a/docs/releasing.md b/docs/releasing.md index 4ef72ced..d718d59a 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -38,7 +38,7 @@ git push origin v{{ fladle.next_release }} * Upload to Maven Central (this must run in two separate commands since they are from two different namespaces) ``` bash -./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.release +./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository :fladle-plugin:publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.release ./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.release ``` * Upload to Gradle Plugin Portal From ceae48c0044a5ec5a250c7fd056723de38a176b6 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 17:43:51 +0200 Subject: [PATCH 10/35] Revert "Update target sdk to 35 (#399)" This reverts commit 72d08066f4dbb47e8f26c3da096ae6691d7de869. --- android-library-no-tests/build.gradle.kts | 2 +- .../flank/gradle/integration/FulladlePluginIntegrationTest.kt | 2 +- .../flank/gradle/integration/SanityWithAutoConfigureTest.kt | 2 +- .../java/com/osacky/flank/gradle/integration/VariantTests.kt | 4 ++-- .../resources/android-library-project-flavors/build.gradle | 4 ++-- .../src/test/resources/android-library-project/build.gradle | 4 ++-- .../src/test/resources/android-project-flavors/build.gradle | 4 ++-- fladle-plugin/src/test/resources/android-project/build.gradle | 4 ++-- .../src/test/resources/android-project2/build.gradle | 4 ++-- sample-android-library/build.gradle.kts | 2 +- sample-flavors-kotlin/build.gradle.kts | 2 +- sample-kotlin/build.gradle.kts | 2 +- sample/build.gradle | 4 ++-- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/android-library-no-tests/build.gradle.kts b/android-library-no-tests/build.gradle.kts index a730466a..bed1b75d 100644 --- a/android-library-no-tests/build.gradle.kts +++ b/android-library-no-tests/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } android { - compileSdk = 34 + compileSdk = 33 namespace = "com.osacky.flank.gradle.sample.library" defaultConfig { minSdk = 23 diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt index f0c21b46..6706b2e2 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt @@ -941,7 +941,7 @@ class FulladlePluginIntegrationTest { id "com.android.application" } android { - compileSdk 34 + compileSdk 33 namespace "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt index 64a5b67c..5db13232 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/SanityWithAutoConfigureTest.kt @@ -13,7 +13,7 @@ private const val COMMON_SCRIPT_PART = """ } android { - compileSdk 34 + compileSdk 33 namespace "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt index b3139982..c0f9a0c5 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt @@ -161,12 +161,12 @@ class VariantTests { mavenCentral() } android { - compileSdk 34 + compileSdk 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle b/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle index 26fbdc39..73bcc57c 100644 --- a/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle +++ b/fladle-plugin/src/test/resources/android-library-project-flavors/build.gradle @@ -3,10 +3,10 @@ plugins { } android { - compileSdk 34 + compileSdk 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-library-project/build.gradle b/fladle-plugin/src/test/resources/android-library-project/build.gradle index 966280e0..7890fc20 100644 --- a/fladle-plugin/src/test/resources/android-library-project/build.gradle +++ b/fladle-plugin/src/test/resources/android-library-project/build.gradle @@ -3,10 +3,10 @@ plugins { } android { - compileSdk 34 + compileSdk 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-project-flavors/build.gradle b/fladle-plugin/src/test/resources/android-project-flavors/build.gradle index feb12779..f9e08150 100644 --- a/fladle-plugin/src/test/resources/android-project-flavors/build.gradle +++ b/fladle-plugin/src/test/resources/android-project-flavors/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdk 34 + compileSdk 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-project/build.gradle b/fladle-plugin/src/test/resources/android-project/build.gradle index 63157df7..3d71caaf 100644 --- a/fladle-plugin/src/test/resources/android-project/build.gradle +++ b/fladle-plugin/src/test/resources/android-project/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdk 34 + compileSdk 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/fladle-plugin/src/test/resources/android-project2/build.gradle b/fladle-plugin/src/test/resources/android-project2/build.gradle index f3879001..3cb2fa25 100644 --- a/fladle-plugin/src/test/resources/android-project2/build.gradle +++ b/fladle-plugin/src/test/resources/android-project2/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdk 34 + compileSdk 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/sample-android-library/build.gradle.kts b/sample-android-library/build.gradle.kts index 39d747ad..751c6fca 100644 --- a/sample-android-library/build.gradle.kts +++ b/sample-android-library/build.gradle.kts @@ -18,7 +18,7 @@ fulladleModuleConfig { android { namespace = "com.osacky.flank.gradle.sample" - compileSdk = 34 + compileSdk = 33 defaultConfig { minSdk = 23 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/sample-flavors-kotlin/build.gradle.kts b/sample-flavors-kotlin/build.gradle.kts index e87cb46f..551677fc 100644 --- a/sample-flavors-kotlin/build.gradle.kts +++ b/sample-flavors-kotlin/build.gradle.kts @@ -6,7 +6,7 @@ plugins { android { namespace = "com.osacky.flank.gradle.sample.kotlin" - compileSdk = 34 + compileSdk = 33 defaultConfig { applicationId = "com.osacky.flank.gradle.sample.kotlin" minSdk = 23 diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/build.gradle.kts index da97ef22..1e08d49e 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/build.gradle.kts @@ -6,7 +6,7 @@ plugins { android { namespace = "com.osacky.flank.gradle.sample.kotlin" - compileSdk = 34 + compileSdk = 33 defaultConfig { applicationId = "com.osacky.flank.gradle.sample.kotlin" minSdk = 23 diff --git a/sample/build.gradle b/sample/build.gradle index 8da390a9..c2fc7529 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'kotlin-android' apply plugin: 'com.osacky.fladle' android { - compileSdk = 34 + compileSdk = 33 namespace = "com.osacky.flank.gradle.sample" defaultConfig { applicationId "com.osacky.flank.gradle.sample" minSdk 23 - targetSdk 34 + targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From 00e13ffae7b6ea3f471110b3f25a955c776c30a2 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 30 Aug 2025 18:01:13 +0200 Subject: [PATCH 11/35] Fix GitHub Actions publishing parameters - Change duplicate -PmavenCentralUsername to -PmavenCentralPassword - This was causing publishing failures due to missing mavenCentralPassword parameter --- .github/workflows/gradle-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 9f940359..3dbdde16 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -18,7 +18,7 @@ jobs: run: ./gradlew assembleDebug assembleDebugAndroidTest printYml check :fladle-plugin:check - name: Publish Marker Snapshot if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - run: ./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository :fladle-plugin:publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralUsername=${{ secrets.SONATYPE_PASSWORD }} + run: ./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository :fladle-plugin:publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralPassword=${{ secrets.SONATYPE_PASSWORD }} - name: Publish Plugin Snapshot if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - run: ./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralUsername=${{ secrets.SONATYPE_PASSWORD }} + run: ./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralPassword=${{ secrets.SONATYPE_PASSWORD }} From 3644ff3fd1ea81fb51374b28ab03cdb7d7809b54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 15:23:46 +0200 Subject: [PATCH 12/35] Update kotlin monorepo to v2.2.10 (#438) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1b5e6f7d..662de2a5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" -kotlin = "2.0.21" +kotlin = "2.2.10" agp-version = "7.4.2" flank-version = "23.10.1" From 6511c41b4da1a3ec42a416951db4dfdaa64b3452 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:35:38 +0200 Subject: [PATCH 13/35] Update plugin gradle-plugin-publish to v2 (#467) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 662de2a5..6a44f838 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ ben-manes-versions = { id = "com.github.ben-manes.versions", version = "0.51.0" kotlinter = { id = "org.jmailen.kotlinter", version = "4.0.0" } -gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "1.3.1" } +gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.0.0" } vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.34.0" } From e91a129a4bd2ec3d8fe2699f01eb09389ac32432 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:48:59 +0200 Subject: [PATCH 14/35] Update kotlin monorepo to v2.2.20 (#468) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6a44f838..b9fd51be 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" -kotlin = "2.2.10" +kotlin = "2.2.20" agp-version = "7.4.2" flank-version = "23.10.1" From c59e694c520a2c59442a1f2c29054fe78722a9c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:41:43 +0200 Subject: [PATCH 15/35] Update dependency com.google.truth:truth to v1.4.5 (#469) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b9fd51be..b5ae7fa6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -57,4 +57,4 @@ kotlin-stdlib-jdk7 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk gradle-enterprise = { module = "com.gradle:develocity-gradle-plugin", version = "3.19.2" } -truth = "com.google.truth:truth:1.4.4" +truth = "com.google.truth:truth:1.4.5" From 47f9f5f19195c4b5e434513d317cdffef0aa3231 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 22:04:28 +0200 Subject: [PATCH 16/35] Update plugin com.gradle.develocity to v4.2.2 (#470) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 110cffb3..d485de62 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,7 +7,7 @@ pluginManagement { } plugins { - id "com.gradle.develocity" version "4.1.1" + id "com.gradle.develocity" version "4.2.2" } include ':android-library-no-tests' From 7838a4bebd8ecbc2d1dc3de5876c1fe74adda6db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 20:34:09 +0100 Subject: [PATCH 17/35] Update gradle/actions action to v5 (#471) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 3dbdde16..5ef79366 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -6,13 +6,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - - uses: gradle/actions/wrapper-validation@v4 + - uses: gradle/actions/wrapper-validation@v5 - name: "Set up JDK 11" uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '11' - - uses: gradle/actions/setup-gradle@v4 + - uses: gradle/actions/setup-gradle@v5 name: Setup Gradle - name: Check Fladle run: ./gradlew assembleDebug assembleDebugAndroidTest printYml check :fladle-plugin:check From 003228c7e726b1c94b4057222051971fbfb4693f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 20:46:03 +0100 Subject: [PATCH 18/35] Update kotlin monorepo to v2.2.21 (#472) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b5ae7fa6..4ded2568 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" -kotlin = "2.2.20" +kotlin = "2.2.21" agp-version = "7.4.2" flank-version = "23.10.1" From ddd852d7dc8f729f6c38e1eabef849f4f7744ea7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 22:07:14 +0100 Subject: [PATCH 19/35] Update plugin vanniktech-publish to v0.35.0 (#473) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ded2568..6ccba2c1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ kotlinter = { id = "org.jmailen.kotlinter", version = "4.0.0" } gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.0.0" } -vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.34.0" } +vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.35.0" } kgp = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin"} agp = { id = "com.android.application", version.ref = "agp-version"} From 4ae269cc3a3a2bb7b212175a100bc9f1a5f64f16 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 16:58:03 +0100 Subject: [PATCH 20/35] Update actions/checkout action to v6 (#474) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-build.yml | 2 +- .github/workflows/mkdocs-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 5ef79366..76127e26 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -5,7 +5,7 @@ jobs: name: "Building" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: gradle/actions/wrapper-validation@v5 - name: "Set up JDK 11" uses: actions/setup-java@v5 diff --git a/.github/workflows/mkdocs-deploy.yml b/.github/workflows/mkdocs-deploy.yml index 598d0894..099a4d32 100644 --- a/.github/workflows/mkdocs-deploy.yml +++ b/.github/workflows/mkdocs-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout master - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Deploy docs uses: mhausenblas/mkdocs-deploy-gh-pages@1.26 From cd3dee2b2462f4121e7d52b53882a464fd82e6c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:29:49 +0100 Subject: [PATCH 21/35] Update plugin com.gradle.develocity to v4.3 (#475) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index d485de62..bac20682 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,7 +7,7 @@ pluginManagement { } plugins { - id "com.gradle.develocity" version "4.2.2" + id "com.gradle.develocity" version "4.3" } include ':android-library-no-tests' From f991f6cf3004d7c992d769ee9f78993300a22b1f Mon Sep 17 00:00:00 2001 From: Veyndan Stuart Date: Fri, 13 Feb 2026 17:57:59 +0100 Subject: [PATCH 22/35] Bump min-supported JDK to 17 (#479) --- .github/workflows/gradle-build.yml | 4 ++-- android-library-no-tests/build.gradle.kts | 6 +++--- docs/changelog.md | 2 ++ fladle-plugin/build.gradle.kts | 6 +++--- .../osacky/flank/gradle/FladlePluginDelegate.kt | 2 +- .../FlankGradlePluginIntegrationTest.kt | 14 +++++++------- sample-android-library/build.gradle.kts | 6 +++--- sample-flavors-kotlin/build.gradle.kts | 6 +++--- sample-kotlin/build.gradle.kts | 6 +++--- sample/build.gradle | 6 +++--- 10 files changed, 30 insertions(+), 28 deletions(-) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 76127e26..e65aed0d 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -7,11 +7,11 @@ jobs: steps: - uses: actions/checkout@v6 - uses: gradle/actions/wrapper-validation@v5 - - name: "Set up JDK 11" + - name: "Set up JDK 17" uses: actions/setup-java@v5 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: gradle/actions/setup-gradle@v5 name: Setup Gradle - name: Check Fladle diff --git a/android-library-no-tests/build.gradle.kts b/android-library-no-tests/build.gradle.kts index bed1b75d..b71a13a8 100644 --- a/android-library-no-tests/build.gradle.kts +++ b/android-library-no-tests/build.gradle.kts @@ -11,14 +11,14 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } diff --git a/docs/changelog.md b/docs/changelog.md index c7095960..af64fd40 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,6 +1,8 @@ # Changelog ## Unreleased +* Minimum required JVM version is now 17. +* Minimum supported Gradle version is now 7.3. ## 0.18.0 * Use non-deprecated device models and versions in default config. [PR](https://github.com/runningcode/fladle/pull/446) Thanks [Kaibolay](https://github.com/kaibolay) diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index b723fec3..b0fe4eb1 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -102,10 +102,10 @@ tasks.withType(ValidatePlugins::class.java).configureEach { enableStricterValidation.set(true) } -// Ensure Java 11 Compatibility. See https://github.com/runningcode/fladle/issues/246 +// Ensure Java 17 Compatibility. See https://github.com/runningcode/fladle/issues/246 tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).configureEach { compilerOptions { - jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11) + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) } @@ -113,6 +113,6 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).conf java { toolchain { - languageVersion.set(JavaLanguageVersion.of(11)) + languageVersion.set(JavaLanguageVersion.of(17)) } } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt index ea878e0f..6d3c1f92 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt @@ -219,7 +219,7 @@ class FladlePluginDelegate { get() = configurations.getByName(FLADLE_CONFIG) companion object { - val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("6.5") + val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("7.3") const val TASK_GROUP = "fladle" const val FLADLE_CONFIG = "fladle" diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt index 66f8cd8f..1a1ff22d 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt @@ -11,8 +11,8 @@ class FlankGradlePluginIntegrationTest { @get:Rule var testProjectRoot = TemporaryFolder() - val minSupportGradleVersion = "6.5" - val oldVersion = "6.4" + val minSupportGradleVersion = "7.3" + val oldVersion = "7.2" fun writeBuildGradle(build: String) { testProjectRoot.writeBuildDotGradle(build) @@ -32,11 +32,11 @@ class FlankGradlePluginIntegrationTest { .withPluginClasspath() .withGradleVersion(oldVersion) .buildAndFail() - assertThat(result.output).contains("Fladle requires at minimum version Gradle 6.5. Detected version Gradle 6.4") + assertThat(result.output).contains("Fladle requires at minimum version Gradle 7.3. Detected version Gradle 7.2") } @Test - fun testGradleSevenOh() { + fun testGradleEightOh() { writeBuildGradle( """plugins { | id "com.osacky.fladle" @@ -47,7 +47,7 @@ class FlankGradlePluginIntegrationTest { GradleRunner.create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() - .withGradleVersion("7.0") + .withGradleVersion("8.0") .build() assertThat(result.output).contains("SUCCESS") @@ -273,7 +273,7 @@ class FlankGradlePluginIntegrationTest { } @Test - fun testGradleSevenCompat() { + fun testGradleEightCompat() { writeBuildGradle( """plugins { id "com.osacky.fladle" @@ -292,7 +292,7 @@ class FlankGradlePluginIntegrationTest { testProjectRoot.writeEmptyServiceCredential() val result = testProjectRoot.gradleRunner() - .withGradleVersion("7.0-rc-1") + .withGradleVersion("8.0") .withArguments("printYmlFooConfig") .build() assertThat(result.task(":printYmlFooConfig")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) diff --git a/sample-android-library/build.gradle.kts b/sample-android-library/build.gradle.kts index 751c6fca..8cf64b3f 100644 --- a/sample-android-library/build.gradle.kts +++ b/sample-android-library/build.gradle.kts @@ -25,14 +25,14 @@ android { } testOptions.execution = "ANDROIDX_TEST_ORCHESTRATOR" compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } diff --git a/sample-flavors-kotlin/build.gradle.kts b/sample-flavors-kotlin/build.gradle.kts index 551677fc..ff6a537a 100644 --- a/sample-flavors-kotlin/build.gradle.kts +++ b/sample-flavors-kotlin/build.gradle.kts @@ -15,8 +15,8 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } testOptions.execution = "ANDROIDX_TEST_ORCHESTRATOR" @@ -34,7 +34,7 @@ android { java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/build.gradle.kts index 1e08d49e..4c8a977d 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/build.gradle.kts @@ -15,15 +15,15 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } testOptions.execution = "ANDROIDX_TEST_ORCHESTRATOR" } java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } diff --git a/sample/build.gradle b/sample/build.gradle index c2fc7529..f39d1a7c 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -17,14 +17,14 @@ android { execution 'ANDROIDX_TEST_ORCHESTRATOR' } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } From 4888b5228be3421351e09602503b84a54169cc0e Mon Sep 17 00:00:00 2001 From: Veyndan Stuart Date: Wed, 4 Mar 2026 22:59:16 +0100 Subject: [PATCH 23/35] Bump Android Gradle Plugin from 7.4.2 to 8.2.2 (#480) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6ccba2c1..1a9c062a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,7 +30,7 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" kotlin = "2.2.21" -agp-version = "7.4.2" +agp-version = "8.2.2" flank-version = "23.10.1" [libraries] From e2ea01b0cb15b31f0a22f316701c9f5016c4da2a Mon Sep 17 00:00:00 2001 From: Matthew Runo <74583+inktomi@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:36:59 -0800 Subject: [PATCH 24/35] Code formatting & cleanup - broken out from AGP 9 update PR (#482) * Code cleanup: formatting and expression body conversions Apply ktlint/kotlinter formatting fixes: - Multi-line chain formatting for readability - Convert block body functions to expression body syntax - Add trailing commas to constructor parameters - Reformat when expressions with braces - Reformat block comments to inline comments * Lint fixes - converting runAndFail() functions from block body to expression body syntax --- .../com/osacky/flank/gradle/FladleConfig.kt | 7 ++- .../flank/gradle/FladlePluginDelegate.kt | 54 ++++++++++++++++--- .../osacky/flank/gradle/FlankExecutionTask.kt | 7 ++- .../flank/gradle/FlankGradleExtension.kt | 4 +- .../com/osacky/flank/gradle/FlankJavaExec.kt | 4 +- .../flank/gradle/FulladleModuleExtension.kt | 4 +- .../com/osacky/flank/gradle/FulladlePlugin.kt | 18 +++---- .../RequiredDeviceKeyMissingException.kt | 4 +- .../flank/gradle/SanityConfigValidation.kt | 12 +++-- .../flank/gradle/YamlConfigWriterTask.kt | 11 ++-- .../com/osacky/flank/gradle/YamlExtensions.kt | 3 +- .../com/osacky/flank/gradle/YamlWriter.kt | 3 +- .../flank/gradle/validation/SinceFlank.kt | 5 +- .../gradle/validation/ValidateOptions.kt | 16 ++++-- .../flank/gradle/validation/VersionNumber.kt | 47 +++++++--------- .../gradle/sample/ExampleInstrumentedTest.kt | 4 +- .../gradle/sample/ExampleInstrumentedTest.kt | 4 +- .../gradle/sample/ExampleInstrumentedTest.kt | 4 +- .../gradle/sample/ExampleInstrumentedTest.kt | 4 +- 19 files changed, 130 insertions(+), 85 deletions(-) diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladleConfig.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladleConfig.kt index 869a9938..d6721998 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladleConfig.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladleConfig.kt @@ -51,13 +51,11 @@ interface FladleConfig { @get:Input val testTargets: ListProperty + // The maximum number of shards. Value will be overwritten by [maxTestShards] if both used in configuration @Deprecated( message = "testShards is deprecated. Use maxTestShards instead", replaceWith = ReplaceWith("maxTestShards"), ) - /** - * The maximum number of shards. Value will be overwritten by [maxTestShards] if both used in configuration - */ @get:Input @get:Optional val testShards: Property @@ -473,7 +471,8 @@ interface FladleConfig { @Internal fun getPresentProperties() = - this::class.memberProperties + this::class + .memberProperties .filter { when (val prop = it.call(this)) { is Property<*> -> prop.isPresent diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt index 6d3c1f92..61a9732f 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt @@ -24,7 +24,10 @@ class FladlePluginDelegate { target.tasks.register("flankAuth", FlankJavaExec::class.java) { doFirst { - target.layout.fladleDir.get().asFile.mkdirs() + target.layout.fladleDir + .get() + .asFile + .mkdirs() } classpath = project.fladleConfig args = listOf("auth", "login") @@ -34,7 +37,6 @@ class FladlePluginDelegate { } private fun checkMinimumGradleVersion() { - // Gradle 4.9 is required because we use the lazy task configuration API. if (GRADLE_MIN_VERSION > GradleVersion.current()) { throw GradleException("Fladle requires at minimum version $GRADLE_MIN_VERSION. Detected version ${GradleVersion.current()}.") } @@ -102,7 +104,14 @@ class FladlePluginDelegate { group = TASK_GROUP dependsOn(writeConfigProps) doLast { - println(writeConfigProps.get().fladleConfigFile.get().asFile.readText()) + println( + writeConfigProps + .get() + .fladleConfigFile + .get() + .asFile + .readText(), + ) } } @@ -110,7 +119,19 @@ class FladlePluginDelegate { if (useDefaultDir) setUpWorkingDir(configName) description = "Finds problems with the current configuration." classpath = project.fladleConfig - args = listOf("firebase", "test", "android", "doctor", "-c", writeConfigProps.get().fladleConfigFile.get().asFile.absolutePath) + args = + listOf( + "firebase", + "test", + "android", + "doctor", + "-c", + writeConfigProps + .get() + .fladleConfigFile + .get() + .asFile.absolutePath, + ) dependsOn(writeConfigProps) } @@ -122,13 +143,30 @@ class FladlePluginDelegate { args = if (project.hasProperty("dumpShards")) { listOf( - "firebase", "test", "android", "run", "-c", - writeConfigProps.get().fladleConfigFile.get().asFile.absolutePath, "--dump-shards", + "firebase", + "test", + "android", + "run", + "-c", + writeConfigProps + .get() + .fladleConfigFile + .get() + .asFile.absolutePath, + "--dump-shards", ) } else { listOf( - "firebase", "test", "android", "run", "-c", - writeConfigProps.get().fladleConfigFile.get().asFile.absolutePath, + "firebase", + "test", + "android", + "run", + "-c", + writeConfigProps + .get() + .fladleConfigFile + .get() + .asFile.absolutePath, ) } if (config.serviceAccountCredentials.isPresent) { diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt index 168c5712..c4605747 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt @@ -22,7 +22,12 @@ open class FlankExecutionTask private fun checkFilesExist(base: FladleConfig) { if (base.serviceAccountCredentials.isPresent) { - check(base.serviceAccountCredentials.get().asFile.exists()) { + check( + base.serviceAccountCredentials + .get() + .asFile + .exists(), + ) { "serviceAccountCredential file doesn't exist ${base.serviceAccountCredentials.get()}" } } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt index 19c0f938..25b496d1 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt @@ -16,7 +16,9 @@ import javax.inject.Inject open class FlankGradleExtension @Inject - constructor(objects: ObjectFactory) : FladleConfig { + constructor( + objects: ObjectFactory, + ) : FladleConfig { companion object { const val FLANK_VERSION = "23.10.1" } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt index f10ef850..e515f15d 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt @@ -10,7 +10,9 @@ import javax.inject.Inject ) open class FlankJavaExec @Inject - constructor(projectLayout: ProjectLayout) : JavaExec() { + constructor( + projectLayout: ProjectLayout, + ) : JavaExec() { init { group = FladlePluginDelegate.TASK_GROUP mainClass.set("ftl.Main") diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt index 510f5f54..a9c23b99 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt @@ -9,7 +9,9 @@ import javax.inject.Inject open class FulladleModuleExtension @Inject - constructor(objects: ObjectFactory) { + constructor( + objects: ObjectFactory, + ) { /** * When set to false, Fulladle will not automatically add this module to additionalTestApks. * diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt index 568feebb..c3901046 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt @@ -23,18 +23,12 @@ class FulladlePlugin : Plugin { val fulladleConfigureTask = root.tasks.register("configureFulladle") { var modulesEnabled = false - /** - * we will first configure all app modules - * then configure all library modules - * we force this order of configuration because - * app modules are better candidates to become - * root level test/app APKs, since they produce - * app APKs - * if no app module had tests or was enabled - * we will choose a library module to become - * a root level module, in which case we will - * have to check if it has its debugApk set - */ + // We first configure all app modules, then configure all library modules. + // We force this order because app modules are better candidates to become + // root level test/app APKs, since they produce app APKs. + // If no app module had tests or was enabled, we will choose a library module + // to become a root level module, in which case we will have to check if it + // has its debugApk set. doLast { // first configure all app modules root.subprojects { diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/RequiredDeviceKeyMissingException.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/RequiredDeviceKeyMissingException.kt index 31427c11..7682930f 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/RequiredDeviceKeyMissingException.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/RequiredDeviceKeyMissingException.kt @@ -1,3 +1,5 @@ package com.osacky.flank.gradle -data class RequiredDeviceKeyMissingException(val key: String) : Exception("Device should have '$key' key set to a value.") +data class RequiredDeviceKeyMissingException( + val key: String, +) : Exception("Device should have '$key' key set to a value.") diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt index 26d91f4a..10b51018 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt @@ -6,16 +6,22 @@ import java.lang.IllegalArgumentException fun checkIfSanityAndValidateConfigs(config: FladleConfig) = when (config) { - is FlankGradleExtension -> + is FlankGradleExtension -> { config.checkAndValidateConfig { option, name -> "Incorrect [$name] configuration. [$option] can't be used together with sanityRobo." } - is FladleConfigImpl -> + } + + is FladleConfigImpl -> { config.checkAndValidateConfig(config.name) { option, name -> "Incorrect [$name] configuration. [$option] can't be used together with sanityRobo. " + "To configure sanityRobo, add clearPropertiesForSanityRobo() to the [$name] configuration" } - else -> throw IllegalArgumentException("Unexpected configuration when validating parameters. Did not expect: $config.") + } + + else -> { + throw IllegalArgumentException("Unexpected configuration when validating parameters. Did not expect: $config.") + } } private fun FladleConfig.checkAndValidateConfig( diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlConfigWriterTask.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlConfigWriterTask.kt index 12373cbb..1d3b09e6 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlConfigWriterTask.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlConfigWriterTask.kt @@ -38,21 +38,18 @@ open class YamlConfigWriterTask @get:Input val additionalTestApks: ListProperty = - objects.listProperty(String::class.java) + objects + .listProperty(String::class.java) .convention(config.additionalTestApks) @OutputFile val fladleConfigFile: Provider = fladleDir.map { it.file("flank.yml") } @Internal - override fun getDescription(): String { - return "Writes a flank.yml file based on the current FlankGradleExtension configuration." - } + override fun getDescription(): String = "Writes a flank.yml file based on the current FlankGradleExtension configuration." @Internal - override fun getGroup(): String { - return FladlePluginDelegate.TASK_GROUP - } + override fun getGroup(): String = FladlePluginDelegate.TASK_GROUP @TaskAction fun writeFile() { diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt index 75d41a73..d0fc43af 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt @@ -35,7 +35,8 @@ fun StringBuilder.appendListProperty( fun StringBuilder.appendAdditionalProperty(property: Property) { if (property.isPresent) { - property.get() + property + .get() .split("\n") .map { " $it" } .forEach { appendLine(it) } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlWriter.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlWriter.kt index 2262148f..d2083f64 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlWriter.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlWriter.kt @@ -126,7 +126,8 @@ internal class YamlWriter { } else { appendListProperty(config.roboDirectives, name = "robo-directives") { val value = - it.getOrElse(2) { "" } + it + .getOrElse(2) { "" } .let { stringValue -> if (stringValue.isBlank()) "\"\"" else stringValue } appendLine(" ${it[0]}:${it[1]}: $value") } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/SinceFlank.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/SinceFlank.kt index 142b9713..f35e6222 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/SinceFlank.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/SinceFlank.kt @@ -1,3 +1,6 @@ package com.osacky.flank.gradle.validation -annotation class SinceFlank(val version: String, val hasDefaultValue: Boolean = false) +annotation class SinceFlank( + val version: String, + val hasDefaultValue: Boolean = false, +) diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/ValidateOptions.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/ValidateOptions.kt index 9fead49d..0a48b133 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/ValidateOptions.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/ValidateOptions.kt @@ -11,7 +11,8 @@ fun validateOptionsUsed( // if using snapshot version default to the latest known version of flank for validation checks val configFlankVersion = if (flank.toLowerCase().endsWith("snapshot")) FLANK_VERSION.toVersion() else flank.toVersion() - config.getPresentProperties() + config + .getPresentProperties() .mapNotNull { property -> properties[property.name]?.let { property to it } } .forEach { (property, version) -> if (version > configFlankVersion) { @@ -25,11 +26,18 @@ fun validateOptionsUsed( private fun String.toVersion() = VersionNumber.parse(this) private val properties = - FladleConfig::class.memberProperties + FladleConfig::class + .memberProperties .asSequence() .map { it to it.getter.annotations } // we also need to exclude properties with default values to preserve backward compatibility // to be fixed .filter { it.second.any { annotation -> annotation is SinceFlank && !annotation.hasDefaultValue } } - .map { it.first.name to it.second.filterIsInstance().first().version.toVersion() } - .toMap() + .map { + it.first.name to + it.second + .filterIsInstance() + .first() + .version + .toVersion() + }.toMap() diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/VersionNumber.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/VersionNumber.kt index d17b4b3e..90d5d9cb 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/VersionNumber.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/validation/VersionNumber.kt @@ -40,13 +40,13 @@ class VersionNumber private constructor( if (patch != other.patch) { return patch - other.patch } - return qualifier.orEmpty().lowercase() + return qualifier + .orEmpty() + .lowercase() .compareTo(other.qualifier.orEmpty().lowercase()) } - override fun equals(other: Any?): Boolean { - return other is VersionNumber && compareTo(other) == 0 - } + override fun equals(other: Any?): Boolean = other is VersionNumber && compareTo(other) == 0 override fun hashCode(): Int { var result = major @@ -57,9 +57,7 @@ class VersionNumber private constructor( return result } - override fun toString(): String { - return scheme.format(this) - } + override fun toString(): String = scheme.format(this) /** * Returns the version number scheme. @@ -70,7 +68,9 @@ class VersionNumber private constructor( fun format(versionNumber: VersionNumber): String } - private abstract class AbstractScheme protected constructor(val depth: Int) : Scheme { + private abstract class AbstractScheme protected constructor( + val depth: Int, + ) : Scheme { override fun parse(versionString: String): VersionNumber { if (versionString.isEmpty()) { return UNKNOWN @@ -109,16 +109,15 @@ class VersionNumber private constructor( return UNKNOWN } - private class Scanner(val str: String) { + private class Scanner( + val str: String, + ) { var pos: Int = 0 - fun hasDigit(): Boolean { - return pos < str.length && Character.isDigit(str.get(pos)) - } + fun hasDigit(): Boolean = pos < str.length && Character.isDigit(str.get(pos)) - fun isSeparatorAndDigit(vararg separators: Char): Boolean { - return pos < str.length - 1 && oneOf(*separators) && Character.isDigit(str.get(pos + 1)) - } + fun isSeparatorAndDigit(vararg separators: Char): Boolean = + pos < str.length - 1 && oneOf(*separators) && Character.isDigit(str.get(pos + 1)) fun oneOf(vararg separators: Char): Boolean { val current = str.get(pos) @@ -148,22 +147,19 @@ class VersionNumber private constructor( pos++ } - fun remainder(): String? { - return if (pos == str.length) null else str.substring(pos) - } + fun remainder(): String? = if (pos == str.length) null else str.substring(pos) } } private class DefaultScheme : AbstractScheme(3) { - override fun format(versionNumber: VersionNumber): String { - return String.format( + override fun format(versionNumber: VersionNumber): String = + String.format( VERSION_TEMPLATE, versionNumber.major, versionNumber.minor, versionNumber.micro, if (versionNumber.qualifier == null) "" else "-" + versionNumber.qualifier, ) - } companion object { private const val VERSION_TEMPLATE = "%d.%d.%d%s" @@ -178,8 +174,8 @@ class VersionNumber private constructor( fun version( major: Int, minor: Int = 0, - ): VersionNumber { - return VersionNumber( + ): VersionNumber = + VersionNumber( major = major, minor = minor, micro = 0, @@ -187,10 +183,7 @@ class VersionNumber private constructor( qualifier = null, scheme = DEFAULT_SCHEME, ) - } - fun parse(versionString: String): VersionNumber { - return DEFAULT_SCHEME.parse(versionString) - } + fun parse(versionString: String): VersionNumber = DEFAULT_SCHEME.parse(versionString) } } diff --git a/sample-android-library/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt b/sample-android-library/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt index ab896993..0b6fe002 100644 --- a/sample-android-library/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt +++ b/sample-android-library/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt @@ -12,7 +12,5 @@ class ExampleInstrumentedTest { } @Test - fun runAndFail() { - throw RuntimeException("Test failed") - } + fun runAndFail(): Unit = throw RuntimeException("Test failed") } diff --git a/sample-flavors-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt b/sample-flavors-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt index 5d25f62c..efa6aae8 100644 --- a/sample-flavors-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt +++ b/sample-flavors-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt @@ -23,7 +23,5 @@ class ExampleInstrumentedTest { } @Test - fun runAndFail() { - throw RuntimeException("Test failed") - } + fun runAndFail(): Unit = throw RuntimeException("Test failed") } diff --git a/sample-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt b/sample-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt index 57d1a72f..cec17543 100644 --- a/sample-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt +++ b/sample-kotlin/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt @@ -22,7 +22,5 @@ class ExampleInstrumentedTest { } @Test - fun runAndFail() { - throw RuntimeException("Test failed") - } + fun runAndFail(): Unit = throw RuntimeException("Test failed") } diff --git a/sample/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt b/sample/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt index 2587b288..f71566f5 100644 --- a/sample/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt +++ b/sample/src/androidTest/java/com/osacky/flank/gradle/sample/ExampleInstrumentedTest.kt @@ -22,7 +22,5 @@ class ExampleInstrumentedTest { } @Test - fun runAndFail() { - throw RuntimeException("Test failed") - } + fun runAndFail(): Unit = throw RuntimeException("Test failed") } From dcc20d112a186a2bc2a4aa6370e6d00e18e719a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:37:16 +0100 Subject: [PATCH 25/35] Update kotlin monorepo to v2.3.10 (#476) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a9c062a..cfe2c313 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" -kotlin = "2.2.21" +kotlin = "2.3.10" agp-version = "8.2.2" flank-version = "23.10.1" From 60790aee42ec7e78f3ce2baaf0ed99b5fa4796cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:50:53 +0100 Subject: [PATCH 26/35] Update Gradle to v8.14.4 (#483) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index a3cabd9d..b62a872a 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ fladle { } tasks.wrapper.configure { - gradleVersion = '8.14.3' + gradleVersion = '8.14.4' } def isNonStable = { String version -> diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d4081da4..aaaabb3c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From f90d15d6a2be425ec6f2241708e3e061e17cd498 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 12:37:22 +0100 Subject: [PATCH 27/35] Update plugin com.gradle.develocity to v4.3.2 (#484) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index bac20682..a5da6364 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,7 +7,7 @@ pluginManagement { } plugins { - id "com.gradle.develocity" version "4.3" + id "com.gradle.develocity" version "4.3.2" } include ':android-library-no-tests' From 25f60a54be92b0ddf783c2c7f12348da6397856c Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Mar 2026 12:42:27 +0100 Subject: [PATCH 28/35] Add 0.19.0 changelog entry Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index af64fd40..d76b820c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,8 +1,11 @@ # Changelog ## Unreleased + +## 0.19.0 * Minimum required JVM version is now 17. * Minimum supported Gradle version is now 7.3. +* Fix support for Gradle 9.0.0. [PR](https://github.com/runningcode/fladle/pull/452) Thanks [kevinguitar](https://github.com/kevinguitar) ## 0.18.0 * Use non-deprecated device models and versions in default config. [PR](https://github.com/runningcode/fladle/pull/446) Thanks [Kaibolay](https://github.com/kaibolay) From 0614f1f59ce78294c694920a97ae8848c17be12d Mon Sep 17 00:00:00 2001 From: Matthew Runo <74583+inktomi@users.noreply.github.com> Date: Fri, 6 Mar 2026 00:13:28 -0800 Subject: [PATCH 29/35] Update to Android Gradle Plugin 9.0.1 (#481) * Applied Android Studio JVM migration * Update to Android Gradle Plugin 9.0.1 - Migrate from legacy variant API (AppExtension, TestedExtension, BaseVariant) to new variant API (ApplicationExtension, ApplicationAndroidComponentsExtension, Variant) - Replace testVariants.configureEach with onVariants callbacks for APK path detection - Add VariantApkInfo data class to capture variant info during configuration - Update Gradle wrapper from 8.14.3 to 9.1.0 (minimum required by AGP 9.0) - Update Kotlin language/API version from 1.7 to 2.0 - Remove kotlin-android plugin from sample projects (built-in in AGP 9.0) - Add type bounds for Kotlin 2.0 compatibility - Change task classes from open to abstract (AGP 9 requirement) - Update minimum Gradle version from 7.3 to 9.1 Fixes #478 * Updated changelog with blurbs about changes for AGP 9.0.1 support * Added changelog info to unreleased section * Updated gradle wrapper binary, and fixes for chain-method-continuation lint issue * Fix formatting with lint --------- Co-authored-by: Nelson Osacky --- android-library-no-tests/build.gradle.kts | 1 - build.gradle | 3 +- docs/changelog.md | 2 + fladle-plugin/build.gradle.kts | 18 +- fladle-plugin/settings.gradle.kts | 4 + .../flank/gradle/FladlePluginDelegate.kt | 155 +++++++---- .../osacky/flank/gradle/FlankExecutionTask.kt | 2 +- .../com/osacky/flank/gradle/FlankJavaExec.kt | 2 +- .../flank/gradle/FulladleModuleExtension.kt | 6 + .../com/osacky/flank/gradle/FulladlePlugin.kt | 243 ++++++++++++------ .../flank/gradle/SanityConfigValidation.kt | 2 +- .../com/osacky/flank/gradle/VariantApkInfo.kt | 11 + .../java/com/osacky/flank/gradle/Variants.kt | 25 +- .../com/osacky/flank/gradle/YamlExtensions.kt | 10 +- .../flank/gradle/MultipleConfigsTest.kt | 6 +- .../integration/AutoConfigureFladleTest.kt | 3 +- .../integration/ConfigurationCacheTest.kt | 8 +- .../FlankGradlePluginIntegrationTest.kt | 48 ++-- .../FulladlePluginIntegrationTest.kt | 49 ++-- .../flank/gradle/integration/TestFixtures.kt | 9 +- .../flank/gradle/integration/VariantTests.kt | 21 +- .../validation/ValidateExclusionsTest.kt | 3 +- .../gradle/validation/ValidateOptionsTest.kt | 7 +- gradle.properties | 2 - gradle/gradle-daemon-jvm.properties | 13 + gradle/libs.versions.toml | 10 +- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 45457 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 13 +- gradlew.bat | 5 +- sample-android-library/build.gradle.kts | 1 - sample-flavors-kotlin/build.gradle.kts | 1 - sample-kotlin/build.gradle.kts | 1 - sample/build.gradle | 1 - settings.gradle | 1 + 35 files changed, 444 insertions(+), 244 deletions(-) create mode 100644 fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt create mode 100644 gradle/gradle-daemon-jvm.properties diff --git a/android-library-no-tests/build.gradle.kts b/android-library-no-tests/build.gradle.kts index b71a13a8..76dda11f 100644 --- a/android-library-no-tests/build.gradle.kts +++ b/android-library-no-tests/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("com.android.library") - kotlin("android") } android { diff --git a/build.gradle b/build.gradle index b62a872a..165b5226 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,6 @@ buildscript { plugins { alias(libs.plugins.agp) apply false - alias(libs.plugins.kgp) apply false alias(libs.plugins.ben.manes.versions) id "com.osacky.fulladle" alias(libs.plugins.kotlinter) @@ -22,7 +21,7 @@ fladle { } tasks.wrapper.configure { - gradleVersion = '8.14.4' + gradleVersion = '9.1.0' } def isNonStable = { String version -> diff --git a/docs/changelog.md b/docs/changelog.md index d76b820c..08f2d165 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,6 +1,8 @@ # Changelog ## Unreleased +* Minimum required Gradle version is now 9.1 +* Fixed support for Android Gradle Plugin version 9.0.1 ## 0.19.0 * Minimum required JVM version is now 17. diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index b0fe4eb1..29d4e847 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -18,18 +18,18 @@ plugins { alias(libs.plugins.vanniktech.publish) } -// See https://github.com/slackhq/keeper/pull/11#issuecomment-579544375 for context -val isReleaseMode : Boolean = hasProperty("fladle.releaseMode") - dependencies { compileOnly(gradleApi()) - if (isReleaseMode) { - compileOnly(libs.agp) - } else { - implementation(libs.agp) + compileOnly(libs.agp) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-embeddable") + exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-runner") } compileOnly(libs.gradle.enterprise) + // AGP must be on the runtime classpath so GradleTestKit's withPluginClasspath() + // can resolve the com.android.application and com.android.library plugins. + runtimeOnly(libs.agp) + testImplementation(gradleTestKit()) testImplementation(libs.junit) testImplementation(libs.truth) @@ -106,8 +106,8 @@ tasks.withType(ValidatePlugins::class.java).configureEach { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).configureEach { compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) - languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) + languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) } } diff --git a/fladle-plugin/settings.gradle.kts b/fladle-plugin/settings.gradle.kts index 528a0fa6..09608f5d 100644 --- a/fladle-plugin/settings.gradle.kts +++ b/fladle-plugin/settings.gradle.kts @@ -1,5 +1,9 @@ rootProject.name = "fladle" +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" +} + dependencyResolutionManagement { versionCatalogs { create("libs") { diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt index 61a9732f..44873cd9 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt @@ -1,14 +1,15 @@ package com.osacky.flank.gradle -import com.android.build.gradle.AppExtension -import com.android.build.gradle.TestedExtension -import com.android.build.gradle.internal.tasks.factory.dependsOn -import com.android.builder.model.TestOptions +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.api.variant.FilterConfiguration +import com.android.build.api.variant.HasAndroidTest import com.osacky.flank.gradle.validation.checkForExclusionUsage import com.osacky.flank.gradle.validation.validateOptionsUsed import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.artifacts.Configuration +import org.gradle.api.plugins.BasePluginExtension import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.create import org.gradle.util.GradleVersion @@ -46,24 +47,22 @@ class FladlePluginDelegate { project: Project, base: FlankGradleExtension, ) { - if (GradleVersion.current() > GradleVersion.version("6.1")) { - base.flankVersion.finalizeValueOnRead() - base.flankCoordinates.finalizeValueOnRead() - base.serviceAccountCredentials.finalizeValueOnRead() + base.flankVersion.finalizeValueOnRead() + base.flankCoordinates.finalizeValueOnRead() + base.serviceAccountCredentials.finalizeValueOnRead() + + // Register onVariants callbacks before afterEvaluate for APK path detection + project.pluginManager.withPlugin("com.android.application") { + if (!base.debugApk.isPresent || !base.instrumentationApk.isPresent) { + findDebugAndInstrumentationApk(project, base) + } } + project.afterEvaluate { // Add Flank dependency to Fladle Configuration // Must be done afterEvaluate otherwise extension values will not be set. project.dependencies.add(FLADLE_CONFIG, "${base.flankCoordinates.get()}:${base.flankVersion.get()}") - // Only use automatic apk path detection for 'com.android.application' projects. - project.pluginManager.withPlugin("com.android.application") { - // This doesn't work properly for multiple configs since they likely are inheriting the config from root already. See #60 https://github.com/runningcode/fladle/issues/60 - if (!base.debugApk.isPresent || !base.instrumentationApk.isPresent) { - findDebugAndInstrumentationApk(project, base) - } - } - tasks.apply { createTasksForConfig(base, base, project, "") @@ -97,7 +96,7 @@ class FladlePluginDelegate { val writeConfigProps = register("writeConfigProps$name", YamlConfigWriterTask::class.java, base, config, name) - writeConfigProps.dependsOn(validateFladle) + writeConfigProps.configure { dependsOn(validateFladle) } register("printYml$name") { description = "Print the flank.yml file to the console." @@ -174,17 +173,15 @@ class FladlePluginDelegate { } dependsOn(writeConfigProps) if (config.dependOnAssemble.isPresent && config.dependOnAssemble.get()) { - val testedExtension = - requireNotNull(project.extensions.findByType(TestedExtension::class.java)) { "Could not find TestedExtension in ${project.name}" } - testedExtension.testVariants.configureEach { - if (testedVariant.isExpectedVariant(config)) { - if (testedVariant.assembleProvider.isPresent) { - dependsOn(testedVariant.assembleProvider) - } - if (assembleProvider.isPresent) { - dependsOn(assembleProvider) - } - } + // Find assemble tasks by convention name pattern + val variantName = config.variant.orNull + if (variantName != null) { + val capitalizedVariant = variantName.capitalize() + dependsOn("assemble$capitalizedVariant") + dependsOn("assemble${capitalizedVariant}AndroidTest") + } else { + dependsOn("assembleDebug") + dependsOn("assembleDebugAndroidTest") } } if (config.localResultsDir.hasValue) { @@ -210,16 +207,17 @@ class FladlePluginDelegate { private fun automaticallyConfigureTestOrchestrator( project: Project, config: FladleConfig, - androidExtension: AppExtension, + androidExtension: ApplicationExtension, ) { project.afterEvaluate { + val execution = androidExtension.testOptions.execution.uppercase() val useOrchestrator = - androidExtension.testOptions.getExecutionEnum() == TestOptions.Execution.ANDROIDX_TEST_ORCHESTRATOR || - androidExtension.testOptions.getExecutionEnum() == TestOptions.Execution.ANDROID_TEST_ORCHESTRATOR + execution == "ANDROIDX_TEST_ORCHESTRATOR" || + execution == "ANDROID_TEST_ORCHESTRATOR" if (useOrchestrator) { log("Automatically detected the use of Android Test Orchestrator") + config.useOrchestrator.set(true) } - config.useOrchestrator.set(useOrchestrator) } } @@ -227,28 +225,77 @@ class FladlePluginDelegate { project: Project, config: FladleConfig, ) { - val baseExtension = - requireNotNull(project.extensions.findByType(AppExtension::class.java)) { "Could not find AppExtension in ${project.name}" } - automaticallyConfigureTestOrchestrator(project, config, baseExtension) - baseExtension.testVariants.configureEach { - val appVariant = testedVariant - outputs.configureEach test@{ - appVariant.outputs - .matching { it.isExpectedAbiOutput(config) } - .configureEach app@{ - if (appVariant.isExpectedVariant(config)) { - if (!config.debugApk.isPresent) { - // Don't set debug apk if not already set. #172 - project.log("Configuring fladle.debugApk from variant ${this@app.name}") - config.debugApk.set(this@app.outputFile.absolutePath) - } - if (!config.roboScript.isPresent && !config.instrumentationApk.isPresent && !config.sanityRobo.get()) { - // Don't set instrumentation apk if not already set. #172 - project.log("Configuring fladle.instrumentationApk from variant ${this@test.name}") - config.instrumentationApk.set(this@test.outputFile.absolutePath) - } - } + val androidExtension = + requireNotNull( + project.extensions.findByType(ApplicationExtension::class.java), + ) { "Could not find ApplicationExtension in ${project.name}" } + automaticallyConfigureTestOrchestrator(project, config, androidExtension) + + val androidComponents = + requireNotNull(project.extensions.findByType(ApplicationAndroidComponentsExtension::class.java)) { + "Could not find ApplicationAndroidComponentsExtension in ${project.name}" + } + + androidComponents.onVariants { variant -> + if (!variant.isExpectedVariant(config)) return@onVariants + val androidTest = (variant as? HasAndroidTest)?.androidTest ?: return@onVariants + + val buildType = variant.buildType ?: return@onVariants + val flavorName = variant.productFlavors.joinToString("") { it.second } + val flavorPath = variant.productFlavors.joinToString("/") { it.second } + val archivesName = + project.extensions + .getByType(BasePluginExtension::class.java) + .archivesName + .get() + val buildDir = project.layout.buildDirectory + + // Test APK path + val testApkDirPath = if (flavorPath.isNotEmpty()) "androidTest/$flavorPath/$buildType" else "androidTest/$buildType" + val testApkFileName = + if (flavorName.isNotEmpty()) { + "$archivesName-$flavorName-$buildType-androidTest.apk" + } else { + "$archivesName-$buildType-androidTest.apk" + } + val testApkPath = + buildDir + .file("outputs/apk/$testApkDirPath/$testApkFileName") + .get() + .asFile + .absolutePath + + variant.outputs.forEach { output -> + if (!output.isExpectedAbiOutput(config)) return@forEach + + val abiFilter = output.filters.firstOrNull { it.filterType == FilterConfiguration.FilterType.ABI } + val abiName = abiFilter?.identifier + + val appApkDirPath = if (flavorPath.isNotEmpty()) "$flavorPath/$buildType" else buildType + val appApkFileName = + buildString { + append(archivesName) + if (flavorName.isNotEmpty()) append("-$flavorName") + if (abiName != null) append("-$abiName") + append("-$buildType.apk") } + val appApkPath = + buildDir + .file("outputs/apk/$appApkDirPath/$appApkFileName") + .get() + .asFile + .absolutePath + + if (!config.debugApk.isPresent) { + // Don't set debug apk if not already set. #172 + project.log("Configuring fladle.debugApk from variant ${variant.name}") + config.debugApk.set(appApkPath) + } + if (!config.roboScript.isPresent && !config.instrumentationApk.isPresent && !config.sanityRobo.get()) { + // Don't set instrumentation apk if not already set. #172 + project.log("Configuring fladle.instrumentationApk from variant ${variant.name}") + config.instrumentationApk.set(testApkPath) + } } } } @@ -257,7 +304,7 @@ class FladlePluginDelegate { get() = configurations.getByName(FLADLE_CONFIG) companion object { - val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("7.3") + val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("9.1") const val TASK_GROUP = "fladle" const val FLADLE_CONFIG = "fladle" diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt index c4605747..2518ff9d 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt @@ -8,7 +8,7 @@ import javax.inject.Inject @DisableCachingByDefault( because = "Flank executions are dependent on resources such as network connection and server and therefore cannot be cached.", ) -open class FlankExecutionTask +abstract class FlankExecutionTask @Inject constructor( projectLayout: ProjectLayout, diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt index e515f15d..21bb73aa 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt @@ -8,7 +8,7 @@ import javax.inject.Inject @DisableCachingByDefault( because = "Flank executions are dependent on resources such as network connection and server and therefore cannot be cached.", ) -open class FlankJavaExec +abstract class FlankJavaExec @Inject constructor( projectLayout: ProjectLayout, diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt index a9c23b99..e6637bd1 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt @@ -48,4 +48,10 @@ open class FulladleModuleExtension * can be a match. */ val variant: Property = objects.property().convention(null as String?) + + /** + * Variant APK info collected during configuration via onVariants callbacks. + * Used by FulladlePlugin at execution time to build YAML entries. + */ + internal val variantApks: MutableList = mutableListOf() } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt index c3901046..59be14be 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt @@ -1,8 +1,12 @@ package com.osacky.flank.gradle -import com.android.build.gradle.TestedExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.api.variant.FilterConfiguration +import com.android.build.api.variant.HasAndroidTest +import com.android.build.api.variant.LibraryAndroidComponentsExtension import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.plugins.BasePluginExtension import org.gradle.kotlin.dsl.getByType /** @@ -18,6 +22,96 @@ class FulladlePlugin : Plugin { root.subprojects { // Yuck, cross project configuration extensions.create("fulladleModuleConfig", FulladleModuleExtension::class.java) + + // Register onVariants callbacks to capture APK info during configuration + pluginManager.withPlugin("com.android.application") { + val androidComponents = extensions.getByType(ApplicationAndroidComponentsExtension::class.java) + val ext = extensions.findByType(FulladleModuleExtension::class.java) ?: return@withPlugin + androidComponents.onVariants { variant -> + val androidTest = (variant as? HasAndroidTest)?.androidTest ?: return@onVariants + val buildType = variant.buildType ?: return@onVariants + val flavorName = variant.productFlavors.joinToString("") { it.second } + val flavorPath = variant.productFlavors.joinToString("/") { it.second } + val archivesName = extensions.getByType(BasePluginExtension::class.java).archivesName.get() + + variant.outputs.forEach { output -> + val abiFilter = output.filters.firstOrNull { it.filterType == FilterConfiguration.FilterType.ABI } + val abiName = abiFilter?.identifier + + val appApkDirPath = if (flavorPath.isNotEmpty()) "$flavorPath/$buildType" else buildType + val appApkFileName = + buildString { + append(archivesName) + if (flavorName.isNotEmpty()) append("-$flavorName") + if (abiName != null) append("-$abiName") + append("-$buildType.apk") + } + val appApkPath = + layout.buildDirectory + .file("outputs/apk/$appApkDirPath/$appApkFileName") + .get() + .asFile.absolutePath + + val testApkDirPath = + if (flavorPath.isNotEmpty()) "androidTest/$flavorPath/$buildType" else "androidTest/$buildType" + val testApkFileName = + if (flavorName.isNotEmpty()) { + "$archivesName-$flavorName-$buildType-androidTest.apk" + } else { + "$archivesName-$buildType-androidTest.apk" + } + val testApkPath = + layout.buildDirectory + .file("outputs/apk/$testApkDirPath/$testApkFileName") + .get() + .asFile.absolutePath + + ext.variantApks.add( + VariantApkInfo( + variantName = variant.name, + appApkPath = appApkPath, + testApkPath = testApkPath, + abiName = abiName, + ), + ) + } + } + } + + pluginManager.withPlugin("com.android.library") { + val androidComponents = extensions.getByType(LibraryAndroidComponentsExtension::class.java) + val ext = extensions.findByType(FulladleModuleExtension::class.java) ?: return@withPlugin + androidComponents.onVariants { variant -> + val androidTest = (variant as? HasAndroidTest)?.androidTest ?: return@onVariants + val buildType = variant.buildType ?: return@onVariants + val flavorName = variant.productFlavors.joinToString("") { it.second } + val flavorPath = variant.productFlavors.joinToString("/") { it.second } + val archivesName = extensions.getByType(BasePluginExtension::class.java).archivesName.get() + + val testApkDirPath = + if (flavorPath.isNotEmpty()) "androidTest/$flavorPath/$buildType" else "androidTest/$buildType" + val testApkFileName = + if (flavorName.isNotEmpty()) { + "$archivesName-$flavorName-$buildType-androidTest.apk" + } else { + "$archivesName-$buildType-androidTest.apk" + } + val testApkPath = + layout.buildDirectory + .file("outputs/apk/$testApkDirPath/$testApkFileName") + .get() + .asFile.absolutePath + + ext.variantApks.add( + VariantApkInfo( + variantName = variant.name, + appApkPath = null, + testApkPath = testApkPath, + abiName = null, + ), + ) + } + } } val fulladleConfigureTask = @@ -80,82 +174,80 @@ fun configureModule( return } - val testedExtension = extensions.findByType(TestedExtension::class.java) ?: return // Only configure the first test variant per module. // Does anyone test more than one variant per module? var addedTestsForModule = false - testedExtension.testVariants.configureEach testVariant@{ - if (this.isExpectedVariantInModule(fulladleModuleExtension)) { - testedVariant.outputs - .matching { it.isExpectedAbiOutput(flankGradleExtension) } - .configureEach app@{ - if (addedTestsForModule) { - return@app - } - this@testVariant.outputs.configureEach test@{ - val yml = StringBuilder() - // If the debugApk isn't yet set, let's use this one. - if (!flankGradleExtension.debugApk.isPresent) { - if (project.isAndroidAppModule) { - // app modules produce app apks that we can consume - flankGradleExtension.debugApk.set(rootProject.provider { this@app.outputFile.absolutePath }) - } else if (project.isAndroidLibraryModule) { - // library modules do not produce an app apk and we'll use the one specified in fulladleModuleConfig block - // we need library modules to specify the app apk to test against, even if it's a dummy one - check(fulladleModuleExtension.debugApk.isPresent && fulladleModuleExtension.debugApk.orNull != null) { - "Library module ${project.path} did not specify a debug apk. Library modules do not " + - "generate a debug apk and one needs to be specified in the fulladleModuleConfig block\n" + - "This is a required parameter in FTL which remains unused for library modules under test, " + - "and you can use a dummy apk here" - } - flankGradleExtension.debugApk.set(rootProject.provider { fulladleModuleExtension.debugApk.get() }) - } - } else { - // Otherwise, let's just add it to the list. - if (project.isAndroidAppModule) { - yml.appendLine("- app: ${this@app.outputFile}") - } else if (project.isAndroidLibraryModule) { - // app apk is not required for library modules so only use if it's explicitly specified - if (fulladleModuleExtension.debugApk.orNull != null) { - yml.appendLine("- app: ${fulladleModuleExtension.debugApk.get()}") - } - } - } + for (variantInfo in fulladleModuleExtension.variantApks) { + if (addedTestsForModule) break - // If the instrumentation apk isn't yet set, let's use this one. - if (!flankGradleExtension.instrumentationApk.isPresent) { - flankGradleExtension.instrumentationApk.set(rootProject.provider { this@test.outputFile.absolutePath }) - } else { - // Otherwise, let's just add it to the list. - if (yml.isBlank()) { - // The first item in the list needs to start with a ` - `. - yml.appendLine("- test: ${this@test.outputFile}") - } else { - yml.appendLine(" test: ${this@test.outputFile}") - } - } + if (!variantInfo.isExpectedVariantInModule(fulladleModuleExtension)) continue - if (yml.isEmpty()) { - // this is the root module - // should not be added as additional test apk - overrideRootLevelConfigs(flankGradleExtension, fulladleModuleExtension) - } else { - yml.appendProperty(fulladleModuleExtension.maxTestShards, " max-test-shards") - yml.appendMapProperty( - fulladleModuleExtension.clientDetails, - " client-details", - ) { appendLine(" ${it.key}: ${it.value}") } - yml.appendMapProperty( - fulladleModuleExtension.environmentVariables, - " environment-variables", - ) { appendLine(" ${it.key}: ${it.value}") } - flankGradleExtension.additionalTestApks.add(yml.toString()) - } - addedTestsForModule = true - } + // Check ABI filter against the extension + if (flankGradleExtension.abi.isPresent && variantInfo.abiName != null && variantInfo.abiName != flankGradleExtension.abi.get()) continue + if (flankGradleExtension.abi.isPresent && variantInfo.abiName == null) { + // No ABI filter on this output - it's a match (universal) + } + + val yml = StringBuilder() + // If the debugApk isn't yet set, let's use this one. + if (!flankGradleExtension.debugApk.isPresent) { + if (project.isAndroidAppModule && variantInfo.appApkPath != null) { + // app modules produce app apks that we can consume + flankGradleExtension.debugApk.set(rootProject.provider { variantInfo.appApkPath }) + } else if (project.isAndroidLibraryModule) { + // library modules do not produce an app apk and we'll use the one specified in fulladleModuleConfig block + // we need library modules to specify the app apk to test against, even if it's a dummy one + check(fulladleModuleExtension.debugApk.isPresent && fulladleModuleExtension.debugApk.orNull != null) { + "Library module ${project.path} did not specify a debug apk. Library modules do not " + + "generate a debug apk and one needs to be specified in the fulladleModuleConfig block\n" + + "This is a required parameter in FTL which remains unused for library modules under test, " + + "and you can use a dummy apk here" } + flankGradleExtension.debugApk.set(rootProject.provider { fulladleModuleExtension.debugApk.get() }) + } + } else { + // Otherwise, let's just add it to the list. + if (project.isAndroidAppModule && variantInfo.appApkPath != null) { + yml.appendLine("- app: ${variantInfo.appApkPath}") + } else if (project.isAndroidLibraryModule) { + // app apk is not required for library modules so only use if it's explicitly specified + if (fulladleModuleExtension.debugApk.orNull != null) { + yml.appendLine("- app: ${fulladleModuleExtension.debugApk.get()}") + } + } + } + + // If the instrumentation apk isn't yet set, let's use this one. + if (!flankGradleExtension.instrumentationApk.isPresent) { + flankGradleExtension.instrumentationApk.set(rootProject.provider { variantInfo.testApkPath }) + } else { + // Otherwise, let's just add it to the list. + if (yml.isBlank()) { + // The first item in the list needs to start with a ` - `. + yml.appendLine("- test: ${variantInfo.testApkPath}") + } else { + yml.appendLine(" test: ${variantInfo.testApkPath}") + } + } + + if (yml.isEmpty()) { + // this is the root module + // should not be added as additional test apk + overrideRootLevelConfigs(flankGradleExtension, fulladleModuleExtension) + } else { + yml.appendProperty(fulladleModuleExtension.maxTestShards, " max-test-shards") + yml.appendMapProperty( + fulladleModuleExtension.clientDetails, + " client-details", + ) { appendLine(" ${it.key}: ${it.value}") } + yml.appendMapProperty( + fulladleModuleExtension.environmentVariables, + " environment-variables", + ) { appendLine(" ${it.key}: ${it.value}") } + flankGradleExtension.additionalTestApks.add(yml.toString()) } + addedTestsForModule = true } } @@ -174,16 +266,11 @@ val Project.hasAndroidTest: Boolean if (!fulladleModuleExtension.enabled.get()) { return false } - val testedExtension = extensions.findByType(TestedExtension::class.java) ?: return false - var testsFound = true - testedExtension.testVariants.configureEach testVariant@{ - if (!file("$projectDir/src/androidTest").exists()) { - println("Ignoring $name test variant in $path: No tests in $projectDir/src/androidTest") - testsFound = false - } - return@testVariant + if (!file("$projectDir/src/androidTest").exists()) { + println("Ignoring test variants in $path: No tests in $projectDir/src/androidTest") + return false } - return testsFound + return true } fun overrideRootLevelConfigs( diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt index 10b51018..b26bcd5f 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt @@ -41,5 +41,5 @@ private fun FladleConfig.checkAndValidateConfig( val Property.hasValue get() = orNull.isNullOrBlank().not() -private val ListProperty.hasValue +private val ListProperty.hasValue get() = getOrElse(emptyList()).isNotEmpty() diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt new file mode 100644 index 00000000..b69db0fa --- /dev/null +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt @@ -0,0 +1,11 @@ +package com.osacky.flank.gradle + +data class VariantApkInfo( + val variantName: String, + val appApkPath: String?, + val testApkPath: String, + val abiName: String?, +) { + fun isExpectedVariantInModule(config: FulladleModuleExtension): Boolean = + !config.variant.isPresent || (config.variant.isPresent && variantName.contains(config.variant.get())) +} diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt index 630ed2ab..df732443 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt @@ -1,33 +1,34 @@ package com.osacky.flank.gradle -import com.android.build.VariantOutput -import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.api.BaseVariantOutput +import com.android.build.api.variant.FilterConfiguration +import com.android.build.api.variant.Variant +import com.android.build.api.variant.VariantOutput /** - * Returns true if this [BaseVariant] matches the variant specified in the [config]. + * Returns true if this [Variant] matches the variant specified in the [config]. * * If no variant is specified, all variants are considered a match. */ -fun BaseVariant.isExpectedVariant(config: FladleConfig) = +fun Variant.isExpectedVariant(config: FladleConfig) = !config.variant.isPresent || (config.variant.isPresent && config.variant.get() == this.name) /** - * Returns true if this [BaseVariantOutput] matches the ABI specified in the [config]. + * Returns true if this [VariantOutput] matches the ABI specified in the [config]. * - * If the config does not specify an ABI, or if the config specifies an ABI but the [BaseVariantOutput] + * If the config does not specify an ABI, or if the config specifies an ABI but the [VariantOutput] * is not filtered by ABI, it is considered a match. */ -fun BaseVariantOutput.isExpectedAbiOutput(config: FladleConfig): Boolean { +fun VariantOutput.isExpectedAbiOutput(config: FladleConfig): Boolean { + val abiFilters = filters.filter { it.filterType == FilterConfiguration.FilterType.ABI } return !config.abi.isPresent || - !filterTypes.contains(VariantOutput.FilterType.ABI.name) || - filters.single { it.filterType == VariantOutput.FilterType.ABI.name }.identifier == config.abi.get() + abiFilters.isEmpty() || + abiFilters.any { it.identifier == config.abi.get() } } /** - * Returns true if this [BaseVariant] matches the variant specified in the [config]. + * Returns true if this [Variant] matches the variant specified in the [config]. * * If no variant is specified, all variants are considered a match. */ -fun BaseVariant.isExpectedVariantInModule(config: FulladleModuleExtension) = +fun Variant.isExpectedVariantInModule(config: FulladleModuleExtension) = !config.variant.isPresent || (config.variant.isPresent && this.name.contains(config.variant.get())) diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt index d0fc43af..a80543bc 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt @@ -4,14 +4,14 @@ import org.gradle.api.provider.ListProperty import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property -fun StringBuilder.appendProperty( +fun StringBuilder.appendProperty( prop: Property, name: String, ) { if (prop.isPresent) appendLine(" $name: ${prop.get()}") } -fun StringBuilder.appendMapProperty( +fun StringBuilder.appendMapProperty( prop: MapProperty, name: String, custom: StringBuilder.(Map.Entry) -> Unit, @@ -22,7 +22,7 @@ fun StringBuilder.appendMapProperty( } } -fun StringBuilder.appendListProperty( +fun StringBuilder.appendListProperty( prop: ListProperty, name: String, custom: StringBuilder.(T) -> Unit, @@ -43,8 +43,8 @@ fun StringBuilder.appendAdditionalProperty(property: Property) { } } -val ListProperty.isPresentAndNotEmpty +val ListProperty.isPresentAndNotEmpty get() = isPresent && get().isNotEmpty() -val MapProperty.isPresentAndNotEmpty +val MapProperty.isPresentAndNotEmpty get() = isPresent && get().isNotEmpty() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt index 8b7a732f..dcb28cd3 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt @@ -38,7 +38,8 @@ class MultipleConfigsTest { testProjectRoot.newFile("flank-gradle-service.json").writeText("{}") val result = - GradleRunner.create() + GradleRunner + .create() .withPluginClasspath() .withArguments("writeConfigPropsOrange", "--stacktrace") .forwardOutput() @@ -76,7 +77,8 @@ class MultipleConfigsTest { ) val regularConfig = - GradleRunner.create() + GradleRunner + .create() .withPluginClasspath() .withArguments("writeConfigProps") .forwardOutput() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt index a4c870ae..848eb540 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt @@ -39,7 +39,8 @@ class AutoConfigureFladleTest { testProjectRoot.setupFixture(fixtureName) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withArguments("assembleDebug", "assembleDebugAndroidTest", "printYml", "--stacktrace") diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt index 2f9b5582..83cbf547 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt @@ -115,7 +115,7 @@ class ConfigurationCacheTest { settings.writeText( """ plugins { - id 'com.gradle.enterprise' version '3.7' + id 'com.gradle.develocity' version '4.3' } """.trimIndent(), ) @@ -131,11 +131,11 @@ class ConfigurationCacheTest { assertThat(secondResult.output).contains("Reusing configuration cache.") } - private fun configCachingRunner(arg: String): GradleRunner { - return GradleRunner.create() + private fun configCachingRunner(arg: String): GradleRunner = + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .forwardOutput() .withArguments(arg, "--configuration-cache") - } } diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt index 1a1ff22d..d95df33f 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt @@ -11,8 +11,8 @@ class FlankGradlePluginIntegrationTest { @get:Rule var testProjectRoot = TemporaryFolder() - val minSupportGradleVersion = "7.3" - val oldVersion = "7.2" + val minSupportGradleVersion = "9.1.0" + val oldVersion = "9.0.0" fun writeBuildGradle(build: String) { testProjectRoot.writeBuildDotGradle(build) @@ -27,16 +27,17 @@ class FlankGradlePluginIntegrationTest { """.trimMargin(), ) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(oldVersion) .buildAndFail() - assertThat(result.output).contains("Fladle requires at minimum version Gradle 7.3. Detected version Gradle 7.2") + assertThat(result.output).contains("Fladle requires at minimum version Gradle 9.1. Detected version Gradle 9.0.0") } @Test - fun testGradleEightOh() { + fun testGradleNineOne() { writeBuildGradle( """plugins { | id "com.osacky.fladle" @@ -44,10 +45,11 @@ class FlankGradlePluginIntegrationTest { """.trimMargin(), ) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() - .withGradleVersion("8.0") + .withGradleVersion("9.1.0") .build() assertThat(result.output).contains("SUCCESS") @@ -61,7 +63,8 @@ class FlankGradlePluginIntegrationTest { |} """.trimMargin(), ) - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -82,7 +85,8 @@ class FlankGradlePluginIntegrationTest { |} """.trimMargin(), ) - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -103,7 +107,8 @@ class FlankGradlePluginIntegrationTest { """.trimMargin(), ) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -131,7 +136,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.newFile("foo").writeText("{}") val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -155,7 +161,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.newFile("foo").writeText("{}") val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -182,7 +189,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -209,7 +217,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -236,7 +245,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -264,7 +274,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -291,8 +302,9 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() - .withGradleVersion("8.0") + testProjectRoot + .gradleRunner() + .withGradleVersion("9.1.0") .withArguments("printYmlFooConfig") .build() assertThat(result.task(":printYmlFooConfig")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt index 6706b2e2..7d2a3ecf 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt @@ -10,7 +10,7 @@ class FulladlePluginIntegrationTest { @get:Rule var testProjectRoot = TemporaryFolder() - val agpDependency: String = "com.android.tools.build:gradle:4.2.1" + val agpDependency: String = "com.android.tools.build:gradle:9.0.1" fun writeBuildGradle(build: String) { val file = testProjectRoot.newFile("build.gradle") @@ -26,7 +26,8 @@ class FulladlePluginIntegrationTest { """.trimMargin(), ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments("help") .build() assertThat(result.output).contains("SUCCESS") @@ -88,7 +89,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -189,7 +191,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -271,7 +274,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -395,7 +399,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -446,10 +451,9 @@ class FulladlePluginIntegrationTest { testProjectRoot.newFile("settings.gradle").writeText( """ include '$appFixture' - include '$libraryFixture' include '$flavourProject' include '$flavourLibrary' - + dependencyResolutionManagement { repositories { mavenCentral() @@ -468,17 +472,17 @@ class FulladlePluginIntegrationTest { repositories { google() } - + dependencies { classpath '$agpDependency' } } - + plugins { id "com.osacky.fulladle" } - - + + fladle { serviceAccountCredentials = project.layout.projectDirectory.file("android-project/flank-gradle-5cf02dc90531.json") } @@ -486,7 +490,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -576,7 +581,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() assertThat(result.output).doesNotContain("max-test-shards: 4") @@ -632,7 +638,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .buildAndFail() @@ -708,7 +715,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .buildAndFail() @@ -797,7 +805,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -881,7 +890,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -967,7 +977,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt index e9f83355..6ad7a89c 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt @@ -5,7 +5,11 @@ import org.junit.rules.TemporaryFolder import java.io.File fun TemporaryFolder.setupFixture(fixtureName: String) { - File(this::class.java.classLoader.getResource(fixtureName)!!.file).copyRecursively(newFile(fixtureName), true) + File( + this::class.java.classLoader + .getResource(fixtureName)!! + .file, + ).copyRecursively(newFile(fixtureName), true) } internal fun TemporaryFolder.writeBuildDotGradle(buildScript: String) = @@ -13,7 +17,8 @@ internal fun TemporaryFolder.writeBuildDotGradle(buildScript: String) = .writeText(buildScript) fun TemporaryFolder.gradleRunner() = - GradleRunner.create() + GradleRunner + .create() .withPluginClasspath() .forwardOutput() .withProjectDir(root) diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt index c0f9a0c5..29f40468 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt @@ -67,15 +67,13 @@ class VariantTests { assertThat(result.output).doesNotContain(":assembleVanillaRelease") assertThat(result.output).doesNotContain(":assembleChocolate") - /** - * See #60 https://github.com/runningcode/fladle/issues/60 - testProjectRoot.writeEmptyServiceCredential() - val resultPrint = testProjectRoot.gradleRunner() - .withArguments("printYmlVanilla") - .build() - assertThat(resultPrint.output).contains("build/outputs/apk/vanilla/debug/chocovanilla-vanilla-debug.apk") - assertThat(resultPrint.output).contains("build/outputs/apk/androidTest/vanilla/debug/chocovanilla-vanilla-debug-androidTest.apk") - **/ + // See #60 https://github.com/runningcode/fladle/issues/60 + // testProjectRoot.writeEmptyServiceCredential() + // val resultPrint = testProjectRoot.gradleRunner() + // .withArguments("printYmlVanilla") + // .build() + // assertThat(resultPrint.output).contains("build/outputs/apk/vanilla/debug/chocovanilla-vanilla-debug.apk") + // assertThat(resultPrint.output).contains("build/outputs/apk/androidTest/vanilla/debug/chocovanilla-vanilla-debug-androidTest.apk") } @Test @@ -106,6 +104,8 @@ class VariantTests { |include ':android-project' """.trimMargin(), ) + testProjectRoot.newFile("local.properties").writeText("sdk.dir=${androidHome()}\n") + testProjectRoot.newFile("gradle.properties").writeText("android.useAndroidX=true") testProjectRoot.setupFixture("android-project") val flavors = if (withFlavors) { @@ -191,7 +191,8 @@ class VariantTests { if (dryRun) { arguments.add("--dry-run") } - return testProjectRoot.gradleRunner() + return testProjectRoot + .gradleRunner() .withArguments(arguments) .build() } diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt index 0b5d05b4..4ffb9517 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt @@ -32,7 +32,8 @@ class ValidateExclusionsTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments("printYml") .buildAndFail() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt index 8ef828cd..0800d233 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt @@ -16,7 +16,12 @@ class ValidateOptionsTest { @get:Rule var testProjectRoot = TemporaryFolder() - private val objects = ProjectBuilder.builder().withName("project").build().objects + private val objects = + ProjectBuilder + .builder() + .withName("project") + .build() + .objects private lateinit var config: FladleConfig @Before diff --git a/gradle.properties b/gradle.properties index b2732dd2..b9267d76 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,8 +15,6 @@ org.gradle.jvmargs=-Xmx1536m # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=false kotlin.code.style=official diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties new file mode 100644 index 00000000..5b343e54 --- /dev/null +++ b/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,13 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/67a0fee3c4236b6397dcbe8575ca2011/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/ecd23fd7707c683afbcd6052998cb6a9/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/0b98aec810298c2c1d7fdac5dac37910/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/658299a896470fbb3103ba3a430ee227/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/67a0fee3c4236b6397dcbe8575ca2011/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/23adb857f3cb3cbe28750bc7faa7abc0/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/932015f6361ccaead0c6d9b8717ed96e/redirect +toolchainVendor=JETBRAINS +toolchainVersion=21 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cfe2c313..d30bc1c5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,16 +1,16 @@ ## Generated by $ ./gradlew refreshVersionsCatalog [plugins] +foojay = { id = "org.gradle.toolchains.foojay-resolver-convention", version = "1.0.0"} ben-manes-versions = { id = "com.github.ben-manes.versions", version = "0.51.0" } -kotlinter = { id = "org.jmailen.kotlinter", version = "4.0.0" } +kotlinter = { id = "org.jmailen.kotlinter", version = "5.4.2" } gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.0.0" } vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.35.0" } -kgp = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin"} agp = { id = "com.android.application", version.ref = "agp-version"} [versions] @@ -29,8 +29,8 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" -kotlin = "2.3.10" -agp-version = "8.2.2" +agp-version = "9.0.1" + flank-version = "23.10.1" [libraries] @@ -53,8 +53,6 @@ flank = { module = "com.github.flank:flank", version.ref = "flank-version" } junit = { group = "junit", name = "junit", version.ref = "junit-version" } -kotlin-stdlib-jdk7 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk7", version.ref = "kotlin" } - gradle-enterprise = { module = "com.gradle:develocity-gradle-plugin", version = "3.19.2" } truth = "com.google.truth:truth:1.4.5" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..8bdaf60c75ab801e22807dde59e12a8735a34077 100644 GIT binary patch delta 37308 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%0DA1#UlY+id@u~pzZ$yh2Cpi4=VliLfAZ8Fp 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 /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 7101f8e4..e509b2dd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/sample-android-library/build.gradle.kts b/sample-android-library/build.gradle.kts index 8cf64b3f..63a998cb 100644 --- a/sample-android-library/build.gradle.kts +++ b/sample-android-library/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("com.android.library") - kotlin("android") } fulladleModuleConfig { diff --git a/sample-flavors-kotlin/build.gradle.kts b/sample-flavors-kotlin/build.gradle.kts index ff6a537a..2b131a90 100644 --- a/sample-flavors-kotlin/build.gradle.kts +++ b/sample-flavors-kotlin/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id ("com.android.application") - kotlin("android") id ("com.osacky.fladle") } diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/build.gradle.kts index 4c8a977d..5d729cec 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id ("com.android.application") - kotlin("android") id ("com.osacky.fladle") } diff --git a/sample/build.gradle b/sample/build.gradle index f39d1a7c..71b98804 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' apply plugin: 'com.osacky.fladle' android { diff --git a/settings.gradle b/settings.gradle index a5da6364..e6b4450a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ pluginManagement { } plugins { + id "org.gradle.toolchains.foojay-resolver-convention" version "1.0.0" id "com.gradle.develocity" version "4.3.2" } From e9a7d9c734c7564e0b6cd1a909bc33a01c686a2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 09:32:15 +0100 Subject: [PATCH 30/35] Update plugin vanniktech-publish to v0.36.0 (#490) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d30bc1c5..658d1518 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,7 +9,7 @@ kotlinter = { id = "org.jmailen.kotlinter", version = "5.4.2" } gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.0.0" } -vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.35.0" } +vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.36.0" } agp = { id = "com.android.application", version.ref = "agp-version"} From e608e3b4708ec8295e9157962cca6e032d753b50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 09:32:26 +0100 Subject: [PATCH 31/35] Update plugin gradle-plugin-publish to v2.1.0 (#489) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 658d1518..8dff5966 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ ben-manes-versions = { id = "com.github.ben-manes.versions", version = "0.51.0" kotlinter = { id = "org.jmailen.kotlinter", version = "5.4.2" } -gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.0.0" } +gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.1.0" } vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.36.0" } From 1a09e25741659b4e4c7ec25cf689b82bb4fa2a99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 09:55:22 +0100 Subject: [PATCH 32/35] Update Gradle to v9.4.0 (#463) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 45457 -> 48966 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 165b5226..710a2a98 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ fladle { } tasks.wrapper.configure { - gradleVersion = '9.1.0' + gradleVersion = '9.4.0' } def isNonStable = { String version -> diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8bdaf60c75ab801e22807dde59e12a8735a34077..d997cfc60f4cff0e7451d19d49a82fa986695d07 100644 GIT binary patch delta 39724 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ⅆA{k6{Sa_dPB>TF4Im=mf;z@rf2j7Tr#P>Bp9qL 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 delta 36423 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e111328..dbc3ce4a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index adff685a..0262dcbd 100755 --- a/gradlew +++ b/gradlew @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. From cde11c89a04b61a2af6a357c34b4569ab52d1a6e Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 14 Mar 2026 09:31:24 +0100 Subject: [PATCH 33/35] Automate release publishing via GitHub Actions (#493) * Automate release publishing via GitHub Actions Add a release workflow triggered on tag push that publishes to Maven Central, Gradle Plugin Portal, and creates a GitHub Release. Simplify CI snapshot publishing to use a single vanniktech publishToMavenCentral task and pass secrets via env vars instead of -P flags. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Matthew Runo <74583+inktomi@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) --- .github/workflows/gradle-build.yml | 13 +++++---- .github/workflows/gradle-release.yml | 40 ++++++++++++++++++++++++++++ docs/changelog.md | 4 +++ docs/releasing.md | 16 +++++------ fladle-plugin/build.gradle.kts | 2 +- mkdocs.yml | 4 +-- 6 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/gradle-release.yml diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index e65aed0d..bbbab046 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -16,9 +16,12 @@ jobs: name: Setup Gradle - name: Check Fladle run: ./gradlew assembleDebug assembleDebugAndroidTest printYml check :fladle-plugin:check - - name: Publish Marker Snapshot + - name: Publish Snapshot if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - run: ./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository :fladle-plugin:publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralPassword=${{ secrets.SONATYPE_PASSWORD }} - - name: Publish Plugin Snapshot - if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - run: ./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.releaseMode -PmavenCentralUsername=${{ secrets.SONATYPE_USERNAME }} -PmavenCentralPassword=${{ secrets.SONATYPE_PASSWORD }} + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.GPG_SIGNING_KEY_ID }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }} + run: ./gradlew :fladle-plugin:publishToMavenCentral --no-configuration-cache diff --git a/.github/workflows/gradle-release.yml b/.github/workflows/gradle-release.yml new file mode 100644 index 00000000..6565d5bb --- /dev/null +++ b/.github/workflows/gradle-release.yml @@ -0,0 +1,40 @@ +name: "Release" +on: + push: + tags: + - 'v*' + workflow_dispatch: + +jobs: + release: + name: "Publish Release" + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-java@v5 + with: + java-version: "17" + distribution: "temurin" + - uses: gradle/actions/setup-gradle@v5 + - name: Publish to Maven Central + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.GPG_SIGNING_KEY_ID }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }} + run: ./gradlew :fladle-plugin:publishToMavenCentral --no-configuration-cache + - name: Publish to Gradle Plugin Portal + env: + GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} + GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.GPG_SIGNING_KEY_ID }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }} + run: ./gradlew :fladle-plugin:publishPlugins + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: gh release create "${{ github.ref_name }}" --generate-notes diff --git a/docs/changelog.md b/docs/changelog.md index 08f2d165..ca08b04b 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,6 +4,10 @@ * Minimum required Gradle version is now 9.1 * Fixed support for Android Gradle Plugin version 9.0.1 +## 0.20.0 +* Minimum required Gradle version is now 9.1 +* Fixed support for Android Gradle Plugin version 9.0.1 + ## 0.19.0 * Minimum required JVM version is now 17. * Minimum supported Gradle version is now 7.3. diff --git a/docs/releasing.md b/docs/releasing.md index d718d59a..10ec8351 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -36,18 +36,14 @@ git tag v{{ fladle.next_release }} git push origin v{{ fladle.next_release }} ``` -* Upload to Maven Central (this must run in two separate commands since they are from two different namespaces) -``` bash -./gradlew :fladle-plugin:publishFladlePluginMarkerMavenPublicationToMavenCentralRepository :fladle-plugin:publishFulladlePluginMarkerMavenPublicationToMavenCentralRepository -Pfladle.release -./gradlew :fladle-plugin:publishPluginMavenPublicationToMavenCentralRepository -Pfladle.release -``` -* Upload to Gradle Plugin Portal -```bash -./gradlew :fladle-plugin:publishPlugins -Pfladle.releaseMode -Dorg.gradle.internal.publish.checksums.insecure=true -``` +Pushing the tag automatically triggers the [release workflow](https://github.com/runningcode/fladle/actions/workflows/gradle-release.yml) which: + +1. Publishes to Maven Central +2. Publishes to Gradle Plugin Portal +3. Creates a GitHub Release with auto-generated notes * Release to Maven Central - * Login to Maven Central Repository: [https://central.sonatype.com/](https://oss.sonatype.com/) + * Login to Maven Central Repository: [https://central.sonatype.com/](https://central.sonatype.com/) * Click on **Publish** * Merge the release branch to master diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index 29d4e847..895526fb 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -1,7 +1,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent group = "com.osacky.flank.gradle" -version = "0.19.1-SNAPSHOT" +version = "0.20.0" description = "Easily Scale your Android Instrumentation Tests with Firebase Test Lab with Flank" repositories { diff --git a/mkdocs.yml b/mkdocs.yml index e20000ff..be9b1e1d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -4,8 +4,8 @@ extra: fladle: - current_release: '0.19.0' - next_release: '0.19.1' + current_release: '0.20.0' + next_release: '0.20.1' flank_version: '23.10.1' site_name: Fladle From 47f3de54c4e254001b1bcaa00e670c50f8f1dc9b Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Sat, 14 Mar 2026 09:37:12 +0100 Subject: [PATCH 34/35] Bump to version 0.21.0 --- docs/changelog.md | 5 +++-- fladle-plugin/build.gradle.kts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index ca08b04b..a97f61a9 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,12 +1,13 @@ # Changelog ## Unreleased + +## 0.21.0 * Minimum required Gradle version is now 9.1 * Fixed support for Android Gradle Plugin version 9.0.1 ## 0.20.0 -* Minimum required Gradle version is now 9.1 -* Fixed support for Android Gradle Plugin version 9.0.1 +* Botched release. Do not use. ## 0.19.0 * Minimum required JVM version is now 17. diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index 895526fb..0f045edf 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -1,7 +1,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent group = "com.osacky.flank.gradle" -version = "0.20.0" +version = "0.21.0" description = "Easily Scale your Android Instrumentation Tests with Firebase Test Lab with Flank" repositories { From 15a584507ec016daa5d16ffab5999175de01b4a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 15:42:50 +0100 Subject: [PATCH 35/35] Update plugin gradle-plugin-publish to v2.1.1 (#497) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8dff5966..9c952c41 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ ben-manes-versions = { id = "com.github.ben-manes.versions", version = "0.51.0" kotlinter = { id = "org.jmailen.kotlinter", version = "5.4.2" } -gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.1.0" } +gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.1.1" } vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.36.0" }