diff --git a/gradle-plugin/plugin/performance-project-template/build.gradle.kts b/gradle-plugin/plugin/performance-project-template/build.gradle.kts index 02070c37..49390343 100644 --- a/gradle-plugin/plugin/performance-project-template/build.gradle.kts +++ b/gradle-plugin/plugin/performance-project-template/build.gradle.kts @@ -19,13 +19,3 @@ dependencies { // Add additional dependencies here as needed. // Note Espresso is not supported as it degrades performance. } - -/* - * Example code to disable build types other than "release" - -androidComponents { - beforeVariants(selector().all()) { - it.enable = it.buildType == "release" - } -} -*/ diff --git a/gradle-plugin/plugin/src/functionalTest/kotlin/com/emergetools/android/gradle/MultiProjectFlavorsBuildTypesEmergePluginTest.kt b/gradle-plugin/plugin/src/functionalTest/kotlin/com/emergetools/android/gradle/MultiProjectFlavorsBuildTypesEmergePluginTest.kt new file mode 100644 index 00000000..6b6620a8 --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/kotlin/com/emergetools/android/gradle/MultiProjectFlavorsBuildTypesEmergePluginTest.kt @@ -0,0 +1,48 @@ +package com.emergetools.android.gradle + +import com.emergetools.android.gradle.base.EmergeGradleRunner +import com.emergetools.android.gradle.mocks.assertSuccessfulUploadRequests +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +class MultiProjectFlavorsBuildTypesEmergePluginTest : EmergePluginTest() { + + @Test + fun multiProjectUpload() { + EmergeGradleRunner.create("multi-project-with-flavors-buildtypes") + .withArguments("emergeUploadMinApi24DemoStagingAab") + .withDefaultServer() + .assert { result, server -> + assertSuccessfulUploadRequests(server) + result.assertSuccessfulTask(":app:emergeUploadMinApi24DemoStagingAab") + } + .build() + } + + @Test + fun multiProjectUploadPerfBundle() { + EmergeGradleRunner.create("multi-project-with-flavors-buildtypes") + .withArguments("emergeUploadMinApi21FullReleasePerfBundle") + .withDefaultServer() + .assert { result, server -> + assertSuccessfulUploadRequests(server) + result.assertSuccessfulTask(":app:emergeUploadMinApi21FullReleasePerfBundle") + } + .build() + } + + @Test + fun multiProjectGeneratePerformanceProjectMissing() { + EmergeGradleRunner.create("multi-project-with-flavors-buildtypes") + .withArguments(":app:emergeGeneratePerformanceProject") + .withDefaultServer() + .assert { result, _ -> + assertTrue( + result.output.contains( + "task 'emergeGeneratePerformanceProject' not found in project ':app'" + ) + ) + } + .buildAndFail() + } +} diff --git a/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/app/build.gradle b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/app/build.gradle new file mode 100644 index 00000000..5c900db6 --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/app/build.gradle @@ -0,0 +1,72 @@ +plugins { + id 'com.android.application' + id 'com.emergetools.android' +} + +android { + namespace 'com.example.myapplication' + compileSdk 31 + + defaultConfig { + applicationId 'com.example.myapplication' + minSdk 23 + targetSdk 31 + versionCode 1 + versionName "1.0" + } + + buildTypes { + staging { + initWith debug + applicationIdSuffix ".debugStaging" + } + release { + initWith release + applicationIdSuffix ".release" + } + } + + flavorDimensions "api", "mode" + + productFlavors { + demo { + dimension "mode" + applicationIdSuffix ".demo" + versionNameSuffix "-demo" + } + + full { + dimension "mode" + applicationIdSuffix ".full" + versionNameSuffix "-full" + } + + minApi24 { + dimension "api" + minSdkVersion 24 + } + + minApi21 { + dimension "api" + minSdkVersion 21 + } + } +} + +emerge { + apiToken = 'abcdef123' + + performance { + projectPath = ':performance' + } + + vcs { + sha = 'testSha' + baseSha = 'testBaseSha' + branchName = 'testBranchName' + gitHub { + repoOwner = 'repoOwner' + repoName = 'repoName' + } + } +} diff --git a/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/app/src/main/AndroidManifest.xml b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..e6ed9e9b --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/app/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/build.gradle b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/build.gradle new file mode 100644 index 00000000..d87492ba --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'com.android.test' apply false +} diff --git a/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/performance/build.gradle b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/performance/build.gradle new file mode 100644 index 00000000..0178b13f --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/performance/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'org.jetbrains.kotlin.android' +} \ No newline at end of file diff --git a/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/performance/src/main/AndroidManifest.xml b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/performance/src/main/AndroidManifest.xml new file mode 100644 index 00000000..4682dee2 --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/performance/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/settings.gradle b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/settings.gradle new file mode 100644 index 00000000..c05a1648 --- /dev/null +++ b/gradle-plugin/plugin/src/functionalTest/resources/gradle-project-dirs/multi-project-with-flavors-buildtypes/settings.gradle @@ -0,0 +1,17 @@ +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + google() + } +} + +include(":app") +include(":performance") + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } +} diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/EmergePlugin.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/EmergePlugin.kt index 2343df2d..c386b934 100644 --- a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/EmergePlugin.kt +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/EmergePlugin.kt @@ -6,6 +6,7 @@ import com.android.build.api.variant.AndroidTest import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.api.variant.ApplicationVariant import com.android.build.api.variant.TestAndroidComponentsExtension +import com.android.build.api.variant.TestVariant import com.android.build.api.variant.Variant import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import com.android.build.gradle.internal.tasks.factory.dependsOn @@ -138,6 +139,7 @@ class EmergePlugin : Plugin { TestAndroidComponentsExtension::class.java ) + // In practice, we configure only one variant (debug) for the perf project, so this should only run for that single variant androidTestComponents.onVariants { perfVariant -> appProject.logger.debug( "Registering performance project tasks for ${performanceProject.path} from appProject ${appProject.path} with android test plugin for variant ${perfVariant.name}" @@ -198,24 +200,26 @@ class EmergePlugin : Plugin { appProject: Project, performanceProject: Project, extension: EmergePluginExtension, - perfVariant: Variant, + perfVariant: TestVariant, ) { - registerEmergeLocalTestTask(appProject, performanceProject, perfVariant) - registerUploadPerfBundleTask(appProject, performanceProject, perfVariant, extension) + // We're not concerned with the variants of the performance project, rather the app variants, + // generate a perf task for each app variant for the single debug variant of the perf project. + appVariants.forEach { appVariant -> + registerEmergeLocalTestTask(appProject, performanceProject, appVariant, perfVariant) + registerUploadPerfBundleTask( + appProject, performanceProject, appVariant, perfVariant, extension + ) + } } private fun registerUploadPerfBundleTask( appProject: Project, performanceProject: Project, - performanceVariant: Variant, + appVariant: Variant, + performanceVariant: TestVariant, extension: EmergePluginExtension, ) { - val taskName = "${EMERGE_TASK_PREFIX}Upload${performanceVariant.name.capitalize()}PerfBundle" - val appVariant = appVariants.find { it.name == performanceVariant.name } - checkNotNull(appVariant) { - "Could not find app variant matching performance variant ${performanceVariant.name}" - } - + val taskName = "${EMERGE_TASK_PREFIX}Upload${appVariant.name.capitalize()}PerfBundle" appProject.tasks.register(taskName, UploadPerfBundle::class.java) { it.group = EMERGE_TASK_GROUP it.description = "Builds & uploads an AAB for variant ${appVariant.name} to " + @@ -249,23 +253,23 @@ class EmergePlugin : Plugin { private fun registerEmergeLocalTestTask( appProject: Project, performanceProject: Project, - performanceVariant: Variant, + appVariant: ApplicationVariant, + performanceVariant: TestVariant, ) { - val appVariant = appVariants.find { it.name == performanceVariant.name } + val appVariantName = appVariant.name.capitalize() val perfVariantName = performanceVariant.name.capitalize() - val taskName = "emergeLocal${perfVariantName}Test" + val taskName = "emergeLocal${appVariantName}Test" val task = appProject.tasks.register(taskName, LocalPerfTest::class.java) { it.group = EMERGE_TASK_GROUP it.description = "Installs and runs tests for ${performanceVariant.name} on" + " connected devices. For testing and debugging." - // If possible get the application ID from the variant of the same name - appVariant?.let { appVariant -> it.appPackageName.set(appVariant.applicationId) } + it.appPackageName.set(appVariant.applicationId) it.testPackageName.set(performanceVariant.namespace) } - val uninstallAppTaskPath = "${appProject.path}:uninstall$perfVariantName" - val installAppTaskPath = "${appProject.path}:install$perfVariantName" + val uninstallAppTaskPath = "${appProject.path}:uninstall$appVariantName" + val installAppTaskPath = "${appProject.path}:install$appVariantName" // We need the uninstall task to run first but don't want to enforce that // order unless the local test task is actually being run @@ -447,13 +451,9 @@ class EmergePlugin : Plugin { } buildTypes { - val debugSigningConfig = getByName("debug").signingConfig - appExtension.buildTypes.forEach { appBuildType -> - appProject.logger.debug("Configuring build type ${appBuildType.name} for performance project") - maybeCreate(appBuildType.name).apply { - isDebuggable = false - signingConfig = debugSigningConfig - } + debug { + isDebuggable = true + signingConfig = appExtension.signingConfigs.getByName("debug") } } diff --git a/performance/sample/app/build.gradle.kts b/performance/sample/app/build.gradle.kts index 7299c9cf..644dd2bf 100644 --- a/performance/sample/app/build.gradle.kts +++ b/performance/sample/app/build.gradle.kts @@ -36,10 +36,53 @@ android { signingConfig = signingConfigs.getByName("debug") } debug { + isDefault = true applicationIdSuffix = ".debug" } } + flavorDimensions.add("api") + flavorDimensions.add("mode") + + productFlavors { + create("demo") { + dimension = "mode" + applicationIdSuffix = ".demo" + versionNameSuffix = "-demo" + } + + create("full") { + dimension = "mode" + applicationIdSuffix = ".full" + versionNameSuffix = "-full" + } + + create("minApi24") { + dimension = "api" + minSdk = 24 + } + + create("minApi21") { + dimension = "api" + minSdk = 21 + } + } + + flavorDimensions.add("store") + flavorDimensions.add("distribution") + + productFlavors { + create("play") { + dimension = "store" + signingConfig = signingConfigs.getByName("debug") + isDefault = true + } + create("playstore") { + dimension = "distribution" + signingConfig = signingConfigs.getByName("debug") + } + } + compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 diff --git a/performance/sample/perfTesting/build.gradle.kts b/performance/sample/perfTesting/build.gradle.kts index 799e65fa..094faf46 100644 --- a/performance/sample/perfTesting/build.gradle.kts +++ b/performance/sample/perfTesting/build.gradle.kts @@ -17,12 +17,3 @@ dependencies { // Emerge's UIAutomator helper library (Optional): https://github.com/EmergeTools/relax implementation("com.emergetools.test:relax:0.1.0") } - -/** - * Example code to disable build types other than "release" - */ -androidComponents { - beforeVariants(selector().all()) { - it.enable = it.buildType == "release" - } -}