From cb2a47dd2b13e864c93d212b4ef6a121cf1276ba Mon Sep 17 00:00:00 2001 From: Ryan Brooks Date: Thu, 19 Sep 2024 10:47:33 -0700 Subject: [PATCH 1/2] Support Reaper for APKs --- .../android/gradle/tasks/reaper/Register.kt | 19 ++++++- ...InitializeReaper.kt => UploadReaperAab.kt} | 22 ++------ .../gradle/tasks/reaper/UploadReaperApk.kt | 51 +++++++++++++++++++ .../android/gradle/tasks/size/UploadAAB.kt | 2 +- .../android/gradle/tasks/size/UploadAPK.kt | 4 +- 5 files changed, 74 insertions(+), 24 deletions(-) rename gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/{InitializeReaper.kt => UploadReaperAab.kt} (74%) create mode 100644 gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperApk.kt diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/Register.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/Register.kt index 0b415f21..60321087 100644 --- a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/Register.kt +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/Register.kt @@ -59,15 +59,30 @@ private fun registerReaperUploadTask( ) { val uploadReaperAabTaskName = "${EMERGE_TASK_PREFIX}UploadReaperAab${variant.name.capitalize()}" val uploadReaperAabTask = - appProject.tasks.register(uploadReaperAabTaskName, InitializeReaper::class.java) { + appProject.tasks.register(uploadReaperAabTaskName, UploadReaperAab::class.java) { it.artifact.set(variant.artifacts.get(SingleArtifact.BUNDLE)) it.publishableApiKey.set(extension.reaperOptions.publishableApiKey) it.setUploadTaskInputs(extension, appProject, variant) it.setTagFromProductOptions(extension.reaperOptions, variant) } - // Hook the bundle tasks to run the reaper upload task after they complete. + + + val uploadReaperApkTaskName = "${EMERGE_TASK_PREFIX}UploadReaperApk${variant.name.capitalize()}" + val uploadReaperApkTask = + appProject.tasks.register(uploadReaperApkTaskName, UploadReaperApk::class.java) { + it.artifactDir.set(variant.artifacts.get(SingleArtifact.APK)) + it.proguardMapping.set(variant.artifacts.get(SingleArtifact.OBFUSCATION_MAPPING_FILE)) + it.publishableApiKey.set(extension.reaperOptions.publishableApiKey) + it.setUploadTaskInputs(extension, appProject, variant) + it.setTagFromProductOptions(extension.reaperOptions, variant) + } + + // Hook the bundle & assemble tasks to run the reaper upload task after they complete. appProject.afterEvaluate { project -> val bundleTask = project.tasks.named("bundle${variant.name.capitalize()}") bundleTask.configure { it.finalizedBy(uploadReaperAabTask) } + + val assembleTask = project.tasks.named("assemble${variant.name.capitalize()}") + assembleTask.configure { it.finalizedBy(uploadReaperApkTask) } } } diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/InitializeReaper.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperAab.kt similarity index 74% rename from gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/InitializeReaper.kt rename to gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperAab.kt index 63c28a95..7b765015 100644 --- a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/InitializeReaper.kt +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperAab.kt @@ -3,6 +3,7 @@ package com.emergetools.android.gradle.tasks.reaper import com.emergetools.android.gradle.BuildConfig import com.emergetools.android.gradle.tasks.base.ArtifactMetadata import com.emergetools.android.gradle.tasks.base.BaseUploadTask +import com.emergetools.android.gradle.tasks.size.UploadAAB import kotlinx.datetime.Clock import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property @@ -15,25 +16,13 @@ import org.gradle.api.tasks.TaskAction import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream -abstract class InitializeReaper : BaseUploadTask() { - - @get:InputFile - @get:PathSensitive(PathSensitivity.NAME_ONLY) - abstract val artifact: RegularFileProperty +abstract class UploadReaperAab : UploadAAB() { @get:Input abstract val publishableApiKey: Property - override fun includeFilesInUpload(zos: ZipOutputStream) { - artifact.get().asFile.inputStream().use { inputStream -> - zos.putNextEntry(ZipEntry(artifact.get().asFile.name)) - inputStream.copyTo(zos) - zos.closeEntry() - } - } - @TaskAction - fun execute() { + override fun execute() { if (publishableApiKey.orNull == null) { throw StopExecutionException("publishableApiKey must be set for Reaper to work properly. See https://docs.emergetools.com/docs/reaper-setup-android#configure-the-sdk.") } @@ -53,9 +42,4 @@ abstract class InitializeReaper : BaseUploadTask() { logger.lifecycle("Note: Initial Reaper processing can take up to 10 minutes.") } } - - companion object { - const val AAB_PROGUARD_PATH = - "BUNDLE-METADATA/com.android.tools.build.obfuscation/proguard.map" - } } diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperApk.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperApk.kt new file mode 100644 index 00000000..9f4b64d7 --- /dev/null +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/reaper/UploadReaperApk.kt @@ -0,0 +1,51 @@ +package com.emergetools.android.gradle.tasks.reaper + +import com.emergetools.android.gradle.BuildConfig +import com.emergetools.android.gradle.tasks.base.ArtifactMetadata +import com.emergetools.android.gradle.tasks.base.BaseUploadTask +import com.emergetools.android.gradle.tasks.size.UploadAPK +import com.emergetools.android.gradle.tasks.size.UploadAPK.Companion.APK_EXTENSION +import kotlinx.datetime.Clock +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.StopExecutionException +import org.gradle.api.tasks.TaskAction +import java.io.File +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream + +abstract class UploadReaperApk : UploadAPK() { + + @get:Input + abstract val publishableApiKey: Property + + @TaskAction + override fun execute() { + if (publishableApiKey.orNull == null) { + throw StopExecutionException("publishableApiKey must be set for Reaper to work properly. See https://docs.emergetools.com/docs/reaper-setup-android#configure-the-sdk.") + } + + val artifactName = primaryArtifact.name + val proguardMappingName = proguardMapping.asFile.orNull?.name + val artifactMetadata = ArtifactMetadata( + created = Clock.System.now(), + emergeGradlePluginVersion = BuildConfig.VERSION, + androidGradlePluginVersion = agpVersion.get(), + targetArtifactZipPath = artifactName, + proguardMappingsZipPath = proguardMappingName, + ) + + upload(artifactMetadata) { response -> + logger.lifecycle("Reaper initialized! View Reaper reports for this version at the following url:") + logger.lifecycle("https://emergetools.com/reaper/${response.uploadId}") + logger.lifecycle("Note: Initial Reaper processing can take up to 10 minutes.") + } + } +} diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAAB.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAAB.kt index 6e051d2c..f0b8a434 100644 --- a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAAB.kt +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAAB.kt @@ -27,7 +27,7 @@ abstract class UploadAAB : BaseUploadTask() { } @TaskAction - fun execute() { + open fun execute() { val artifactName = artifact.get().asFile.name val artifactMetadata = ArtifactMetadata( created = Clock.System.now(), diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt index 39fd7b9a..bf8db001 100644 --- a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt @@ -27,7 +27,7 @@ abstract class UploadAPK : BaseUploadTask() { @get:PathSensitive(PathSensitivity.NAME_ONLY) abstract val proguardMapping: RegularFileProperty - private val primaryArtifact: File + protected val primaryArtifact: File get() { val apks = artifactDir.get().asFileTree.filter { it.extension == APK_EXTENSION } check(apks.files.size < 2) { @@ -54,7 +54,7 @@ abstract class UploadAPK : BaseUploadTask() { } @TaskAction - fun doExecute() { + open fun execute() { val artifactName = primaryArtifact.name val proguardMappingName = proguardMapping.asFile.orNull?.name val artifactMetadata = ArtifactMetadata( From f5eb469d1dc52ec4e64837e3b6df9229d9bbcf5a Mon Sep 17 00:00:00 2001 From: Ryan Brooks Date: Thu, 19 Sep 2024 16:19:36 -0700 Subject: [PATCH 2/2] Fix for property to be internal --- .../com/emergetools/android/gradle/tasks/size/UploadAPK.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt index bf8db001..05cf14ac 100644 --- a/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt +++ b/gradle-plugin/plugin/src/main/kotlin/com/emergetools/android/gradle/tasks/size/UploadAPK.kt @@ -8,6 +8,7 @@ import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Optional import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity @@ -27,6 +28,7 @@ abstract class UploadAPK : BaseUploadTask() { @get:PathSensitive(PathSensitivity.NAME_ONLY) abstract val proguardMapping: RegularFileProperty + @get:Internal protected val primaryArtifact: File get() { val apks = artifactDir.get().asFileTree.filter { it.extension == APK_EXTENSION }