From 384c54c2377242b6ef5418764b0426a9291811ad Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Tue, 17 Dec 2019 18:38:10 +0900 Subject: [PATCH 01/10] Split UploadApkTask into UploadArtifactTask --- .../gradle/plugins/tasks/UploadApkTask.groovy | 166 +--------------- .../plugins/tasks/UploadArtifactTask.groovy | 185 ++++++++++++++++++ .../UploadApkTaskConfigurationSpec.groovy | 40 +--- .../plugins/tasks/UploadApkTaskSpec.groovy | 143 +------------- .../tasks/UploadArtifactTaskSpec.groovy | 184 +++++++++++++++++ .../UploadArtifactTaskUploadParamsSpec.groovy | 35 ++++ 6 files changed, 421 insertions(+), 332 deletions(-) create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy create mode 100644 src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy create mode 100644 src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskUploadParamsSpec.groovy diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTask.groovy index 4200f2e2..06e7f893 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTask.groovy @@ -1,98 +1,28 @@ package com.deploygate.gradle.plugins.tasks -import com.deploygate.gradle.plugins.Config import com.deploygate.gradle.plugins.artifacts.ApkInfo import com.deploygate.gradle.plugins.dsl.NamedDeployment import com.deploygate.gradle.plugins.tasks.factory.DeployGateTaskFactory -import com.deploygate.gradle.plugins.utils.BrowserUtils -import com.deploygate.gradle.plugins.utils.HTTPBuilderFactory -import com.google.common.annotations.VisibleForTesting -import groovyx.net.http.ContentType -import groovyx.net.http.HttpResponseDecorator -import groovyx.net.http.Method -import org.apache.http.entity.mime.MultipartEntity -import org.apache.http.entity.mime.content.FileBody -import org.apache.http.entity.mime.content.StringBody -import org.gradle.api.DefaultTask -import org.gradle.api.GradleException import org.gradle.api.tasks.TaskAction import javax.annotation.Nonnull -import javax.annotation.Nullable -import java.nio.charset.Charset - -class UploadApkTask extends DefaultTask { - static class Configuration { - boolean isSigningReady - boolean isUniversalApk - - File apkFile - String message - String distributionKey - String releaseNote - String visibility - - HashMap toUploadParams() { - HashMap params = new HashMap() - if (message != null) { - params.put("message", message) - } - if (distributionKey != null) { - params.put("distribution_key", distributionKey) - } - if (releaseNote != null) { - params.put("release_note", releaseNote) - } - if (visibility != null) { - params.put("visibility", visibility) - } - return params - } - } +class UploadApkTask extends UploadArtifactTask { static Configuration createConfiguration(@Nonnull NamedDeployment deployment, @Nonnull ApkInfo apkInfo) { return new Configuration( + artifactFile: deployment.sourceFile ?: apkInfo.apkFile, isSigningReady: apkInfo.isSigningReady(), isUniversalApk: apkInfo.isUniversalApk(), - apkFile: deployment.sourceFile ?: apkInfo.apkFile, - message: deployment.message, - distributionKey: deployment.distribution?.key, - releaseNote: deployment.distribution?.releaseNote, - visibility: deployment.visibility + uploadParams: createUploadParams(deployment) ) } - @Nullable - private String variantName - - private Configuration configuration - - void setVariantName(@Nonnull String variantName) { - if (this.variantName && this.variantName != variantName) { - throw new IllegalStateException("different variant name cannot be assigned") - } - - this.variantName = variantName - } - - @VisibleForTesting - @Nullable - String getVariantName() { - return variantName - } - - void setConfiguration(@Nonnull Configuration configuration) { - if (!this.variantName) { - throw new IllegalStateException("variant name must be set first") - } - - if (this.configuration) { - logger.debug("$variantName upload apk task configuration has been overwritten") - } - - this.configuration = configuration + @TaskAction + void doUpload() { + super.doUpload() } + @Override void applyTaskProfile() { setDescription("Deploy assembled $variantName to DeployGate") @@ -106,88 +36,10 @@ class UploadApkTask extends DefaultTask { } } - @TaskAction - def uploadApkToServer() { + @Override + void runArtifactSpecificVerification() { if (!configuration.isSigningReady) { throw new IllegalStateException('Cannot upload a build without code signature to DeployGate') } - - if (!configuration.apkFile) { - throw new IllegalStateException("An apk file to be upload not specified.") - } - - if (!configuration.apkFile.exists()) { - throw new IllegalStateException("APK file ${configuration.apkFile} was not found. If you are using Android Build Tools >= 3.0.0, you need to set `sourceFile` in your build.gradle. See https://docs.deploygate.com/docs/gradle-plugin") - } - - def appOwnerName = getAppOwnerName() - def apiToken = getApiToken() - - onBeforeUpload() - - def response = postRequestToUpload(appOwnerName, apiToken, configuration.apkFile, configuration.toUploadParams()) - - handleResponse(response, response.data) - } - - void onBeforeUpload() { - project.deploygate.notifyServer 'start_upload', ['length': Long.toString(configuration.apkFile.length())] - } - - def handleResponse(HttpResponseDecorator response, data) { - if (!(200 <= response.status && response.status < 300) || data.error) { - throw new GradleException("${variantName} failed due to ${data.message}") - } - - if (data.error) - project.deploygate.notifyServer 'upload_finished', ['error': true, message: data.message] - else { - def sent = project.deploygate.notifyServer 'upload_finished', ['path': data.results.path] - - if (!sent && (Config.shouldOpenAppDetailAfterUpload() || data.results.revision == 1)) { - BrowserUtils.openBrowser "${project.deploygate.endpoint}${data.results.path}" - } - } - } - - @VisibleForTesting - @Nonnull - String getApiToken() { - def apiToken = project.deploygate.apiToken - - if (!apiToken?.trim()) { - throw new GradleException('apiToken is missing. Please enter the token.') - } - - apiToken.trim() - } - - @VisibleForTesting - @Nonnull - String getAppOwnerName() { - def appOwnerName = project.deploygate.appOwnerName - - if (!appOwnerName?.trim()) { - throw new GradleException('appOwnerName is missing. Please enter the token.') - } - - appOwnerName.trim() - } - - private HttpResponseDecorator postRequestToUpload(String appOwnerName, String apiToken, File apkFile, Map params) { - MultipartEntity entity = new MultipartEntity() - Charset charset = Charset.forName('UTF-8') - - entity.addPart("file", new FileBody(apkFile.getAbsoluteFile())) - entity.addPart("token", new StringBody(apiToken, charset)) - - for (String key : params.keySet()) { - entity.addPart(key, new StringBody(params.get(key), charset)) - } - - HTTPBuilderFactory.restClient(project.deploygate.endpoint).request(Method.POST, ContentType.JSON) { req -> - uri.path = "/api/users/${appOwnerName}/apps" - req.entity = entity - } as HttpResponseDecorator } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy new file mode 100644 index 00000000..23cab807 --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy @@ -0,0 +1,185 @@ +package com.deploygate.gradle.plugins.tasks + +import com.deploygate.gradle.plugins.Config +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import com.deploygate.gradle.plugins.utils.BrowserUtils +import com.deploygate.gradle.plugins.utils.HTTPBuilderFactory +import com.google.common.annotations.VisibleForTesting +import groovyx.net.http.ContentType +import groovyx.net.http.HttpResponseDecorator +import groovyx.net.http.Method +import org.apache.http.entity.mime.MultipartEntity +import org.apache.http.entity.mime.content.FileBody +import org.apache.http.entity.mime.content.StringBody +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException + +import javax.annotation.Nonnull +import javax.annotation.Nullable +import java.nio.charset.Charset + +abstract class UploadArtifactTask extends DefaultTask { + static class Configuration { + boolean isSigningReady + boolean isUniversalApk + + File artifactFile + + UploadParams uploadParams + } + + static class UploadParams { + String message + String distributionKey + String releaseNote + String visibility + + HashMap toMap() { + HashMap params = new HashMap() + if (message != null) { + params.put("message", message) + } + if (distributionKey != null) { + params.put("distribution_key", distributionKey) + } + if (releaseNote != null) { + params.put("release_note", releaseNote) + } + if (visibility != null) { + params.put("visibility", visibility) + } + return params + } + } + + static UploadParams createUploadParams(@Nonnull NamedDeployment deployment) { + return new UploadParams( + message: deployment.message, + distributionKey: deployment.distribution?.key, + releaseNote: deployment.distribution?.releaseNote, + visibility: deployment.visibility + ) + } + + @Nullable + private String variantName + + Configuration configuration + + void setVariantName(@Nonnull String variantName) { + if (this.variantName && this.variantName != variantName) { + throw new IllegalStateException("different variant name cannot be assigned") + } + + this.variantName = variantName + } + + @Nullable + String getVariantName() { + return variantName + } + + void setConfiguration(@Nonnull Configuration configuration) { + if (!this.variantName) { + throw new IllegalStateException("variant name must be set first") + } + + if (this.configuration) { + logger.debug("$variantName upload artifact (${this.getClass().simpleName}) task configuration has been overwritten") + } + + this.configuration = configuration + } + + // Add TaskAction annotation in overrider classes + void doUpload() { + runArtifactSpecificVerification() + uploadArtifactToServer() + } + + abstract void applyTaskProfile() + + abstract void runArtifactSpecificVerification() + + private void uploadArtifactToServer() { + if (!configuration.artifactFile) { + throw new IllegalStateException("An artifact file to be upload not specified.") + } + + if (!configuration.artifactFile.exists()) { + throw new IllegalStateException("An artifact file (${configuration.artifactFile}) was not found. If you are using Android Build Tools >= 3.0.0, you need to set `sourceFile` in your build.gradle. See https://docs.deploygate.com/docs/gradle-plugin") + } + + def appOwnerName = getAppOwnerName() + def apiToken = getApiToken() + + onBeforeUpload() + + def response = postRequestToUpload(appOwnerName, apiToken, configuration.artifactFile, configuration.uploadParams) + + handleResponse(response, response.data) + } + + private void onBeforeUpload() { + project.deploygate.notifyServer 'start_upload', ['length': Long.toString(configuration.artifactFile.length())] + } + + private void handleResponse(HttpResponseDecorator response, data) { + if (!(200 <= response.status && response.status < 300) || data.error) { + throw new GradleException("${variantName} failed due to ${data.message}") + } + + if (data.error) + project.deploygate.notifyServer 'upload_finished', ['error': true, message: data.message] + else { + def sent = project.deploygate.notifyServer 'upload_finished', ['path': data.results.path] + + if (!sent && (Config.shouldOpenAppDetailAfterUpload() || data.results.revision == 1)) { + BrowserUtils.openBrowser "${project.deploygate.endpoint}${data.results.path}" + } + } + } + + @Nonnull + @VisibleForTesting + String getApiToken() { + def apiToken = project.deploygate.apiToken + + if (!apiToken?.trim()) { + throw new GradleException('apiToken is missing. Please enter the token.') + } + + apiToken.trim() + } + + @Nonnull + @VisibleForTesting + String getAppOwnerName() { + def appOwnerName = project.deploygate.appOwnerName + + if (!appOwnerName?.trim()) { + throw new GradleException('appOwnerName is missing. Please enter the token.') + } + + appOwnerName.trim() + } + + private HttpResponseDecorator postRequestToUpload(String appOwnerName, String apiToken, File artifactFile, UploadParams uploadParams) { + MultipartEntity entity = new MultipartEntity() + Charset charset = Charset.forName('UTF-8') + + entity.addPart("file", new FileBody(artifactFile.getAbsoluteFile())) + entity.addPart("token", new StringBody(apiToken, charset)) + + def params = uploadParams.toMap() + + for (String key : params.keySet()) { + entity.addPart(key, new StringBody(params.get(key), charset)) + } + + HTTPBuilderFactory.restClient(project.deploygate.endpoint).request(Method.POST, ContentType.JSON) { req -> + uri.path = "/api/users/${appOwnerName}/apps" + req.entity = entity + } as HttpResponseDecorator + } +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskConfigurationSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskConfigurationSpec.groovy index 8b83c009..611a39bb 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskConfigurationSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskConfigurationSpec.groovy @@ -27,10 +27,10 @@ class UploadApkTaskConfigurationSpec extends Specification { def configuration = UploadApkTask.createConfiguration(deployment, apkInfo) expect: - configuration.message == message - configuration.distributionKey == distributionKey - configuration.releaseNote == distributionReleaseNote - configuration.visibility == visibility + configuration.uploadParams.message == message + configuration.uploadParams.distributionKey == distributionKey + configuration.uploadParams.releaseNote == distributionReleaseNote + configuration.uploadParams.visibility == visibility configuration.isSigningReady == signingReady configuration.isUniversalApk == universalApk @@ -53,7 +53,7 @@ class UploadApkTaskConfigurationSpec extends Specification { def configuration = UploadApkTask.createConfiguration(deployment, apkInfo) expect: - configuration.apkFile == sourceFile ?: apkFile + configuration.artifactFile == sourceFile ?: apkFile where: sourceFile | apkFile @@ -63,34 +63,4 @@ class UploadApkTaskConfigurationSpec extends Specification { new File("build.gradle") | new File("build.gradle") } - @Unroll - def "toUploadParams should not contain null values"() { - setup: - def configuration = new UploadApkTask.Configuration() - configuration.apkFile = apkFile - configuration.message = message - configuration.distributionKey = distributionKey - configuration.releaseNote = releaseNote - configuration.visibility = visibility - configuration.isSigningReady = isSigningReady - configuration.isUniversalApk = isUniversalApk - - and: - def params = configuration.toUploadParams() - - expect: - params["message"] == message - params["distribution_key"] == distributionKey - params["release_note"] == releaseNote - params["visibility"] == visibility - message != null || !params.containsKey("message") - distributionKey != null || !params.containsKey("distribution_key") - releaseNote != null || !params.containsKey("release_note") - visibility != null || !params.containsKey("visibility") - - where: - message | distributionKey | releaseNote | visibility | isSigningReady | isUniversalApk | apkFile - null | null | null | null | false | false | null - "message" | "distributionKey" | "releaseNote" | "public" | true | true | new File("build.gradle") - } } diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy index 2090e86c..eabdfd7e 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy @@ -23,126 +23,7 @@ class UploadApkTaskSpec extends Specification { project = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build() } - def "getApiToken should get from an extension"() { - setup: - def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) - project.extensions.add("deploygate", deploygate) - - and: - def task = project.tasks.create("UploadApkTask", UploadApkTask) - - and: - deploygate.apiToken = null - - when: - task.apiToken - - then: - thrown(GradleException) - - when: - deploygate.apiToken = " " - - and: - task.apiToken - - then: - thrown(GradleException) - - when: - deploygate.apiToken = "token" - - and: - def token = task.apiToken - - then: - token == "token" - - when: - deploygate.apiToken = " token2 " - - and: - def token2 = task.apiToken - - then: - token2 == "token2" - } - - def "getAppOwnerName should get from an extension"() { - setup: - def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) - project.extensions.add("deploygate", deploygate) - - and: - def task = project.tasks.create("UploadApkTask", UploadApkTask) - - and: - deploygate.appOwnerName = null - - when: - task.appOwnerName - - then: - thrown(GradleException) - - when: - deploygate.appOwnerName = " " - - and: - task.appOwnerName - - then: - thrown(GradleException) - - when: - deploygate.appOwnerName = "appOwnerName" - - and: - def token = task.appOwnerName - - then: - token == "appOwnerName" - - when: - deploygate.appOwnerName = " appOwnerName2 " - - and: - def token2 = task.appOwnerName - - then: - token2 == "appOwnerName2" - } - - def "setVariantName cannot be called with different names"() { - setup: - def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) - project.extensions.add("deploygate", deploygate) - - and: - def task = project.tasks.create("UploadApkTask", UploadApkTask) - - when: - task.variantName = "dep1" - - then: - task.variantName == "dep1" - - when: "try to change the variant name" - task.variantName = "dep2" - - then: "but the change was ignored" - thrown(IllegalStateException) - task.variantName == "dep1" - - when: - task.variantName = "dep1" - - then: "no exception was thrown" - noExceptionThrown() - task.variantName == "dep1" - } - - def "uploadApkToServer should reject illegal states before processing"() { + def "doUpload should reject illegal states before processing"() { setup: def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) project.extensions.add("deploygate", deploygate) @@ -152,28 +33,10 @@ class UploadApkTaskSpec extends Specification { task.variantName = "dep1" when: "signing is required" - task.configuration = new UploadApkTask.Configuration(isSigningReady: false) - - and: - task.uploadApkToServer() - - then: - thrown(IllegalStateException) - - when: "apkFile is required" - task.configuration = new UploadApkTask.Configuration(apkFile: null, isSigningReady: true) - - and: - task.uploadApkToServer() - - then: - thrown(IllegalStateException) - - when: "apkFile must exist" - task.configuration = new UploadApkTask.Configuration(apkFile: new File("not found"), isSigningReady: true) + task.configuration = new UploadArtifactTask.Configuration(isSigningReady: false) and: - task.uploadApkToServer() + task.doUpload() then: thrown(IllegalStateException) diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy new file mode 100644 index 00000000..823ebd4f --- /dev/null +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy @@ -0,0 +1,184 @@ +package com.deploygate.gradle.plugins.tasks + +import com.deploygate.gradle.plugins.dsl.DeployGateExtension +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +import javax.annotation.Nonnull + +class UploadArtifactTaskSpec extends Specification { + static class UploadArtifactTaskStub extends UploadArtifactTask { + + @Override + void applyTaskProfile() { + + } + + @Override + void runArtifactSpecificVerification() { + + } + } + + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + + @Nonnull + private Project project + + def setup() { + project = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build() + } + + def "getApiToken should get from an extension"() { + setup: + def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) + project.extensions.add("deploygate", deploygate) + + and: + def task = project.tasks.create("UploadArtifactTaskStub", UploadArtifactTaskStub) + + and: + deploygate.apiToken = null + + when: + task.apiToken + + then: + thrown(GradleException) + + when: + deploygate.apiToken = " " + + and: + task.apiToken + + then: + thrown(GradleException) + + when: + deploygate.apiToken = "token" + + and: + def token = task.apiToken + + then: + token == "token" + + when: + deploygate.apiToken = " token2 " + + and: + def token2 = task.apiToken + + then: + token2 == "token2" + } + + def "getAppOwnerName should get from an extension"() { + setup: + def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) + project.extensions.add("deploygate", deploygate) + + and: + def task = project.tasks.create("UploadArtifactTaskStub", UploadArtifactTaskStub) + + and: + deploygate.appOwnerName = null + + when: + task.appOwnerName + + then: + thrown(GradleException) + + when: + deploygate.appOwnerName = " " + + and: + task.appOwnerName + + then: + thrown(GradleException) + + when: + deploygate.appOwnerName = "appOwnerName" + + and: + def token = task.appOwnerName + + then: + token == "appOwnerName" + + when: + deploygate.appOwnerName = " appOwnerName2 " + + and: + def token2 = task.appOwnerName + + then: + token2 == "appOwnerName2" + } + + def "setVariantName cannot be called with different names"() { + setup: + def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) + project.extensions.add("deploygate", deploygate) + + and: + def task = project.tasks.create("UploadArtifactTaskStub", UploadArtifactTaskStub) + + when: + task.variantName = "dep1" + + then: + task.variantName == "dep1" + + when: "try to change the variant name" + task.variantName = "dep2" + + then: "but the change was ignored" + thrown(IllegalStateException) + task.variantName == "dep1" + + when: + task.variantName = "dep1" + + then: "no exception was thrown" + noExceptionThrown() + task.variantName == "dep1" + } + + def "doUpload should reject illegal states before processing"() { + setup: + def deploygate = new DeployGateExtension(project, project.container(NamedDeployment)) + project.extensions.add("deploygate", deploygate) + + and: + def task = project.tasks.create("UploadArtifactTaskStub", UploadArtifactTaskStub) + task.variantName = "dep1" + + when: "apkFile is required" + task.configuration = new UploadArtifactTask.Configuration(artifactFile: null, isSigningReady: true) + + and: + task.doUpload() + + then: + thrown(IllegalStateException) + + when: "apkFile must exist" + task.configuration = new UploadArtifactTask.Configuration(artifactFile: new File("not found"), isSigningReady: true) + + and: + task.doUpload() + + then: + thrown(IllegalStateException) + } +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskUploadParamsSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskUploadParamsSpec.groovy new file mode 100644 index 00000000..fb00502d --- /dev/null +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskUploadParamsSpec.groovy @@ -0,0 +1,35 @@ +package com.deploygate.gradle.plugins.tasks + +import spock.lang.Specification +import spock.lang.Unroll + +class UploadArtifactTaskUploadParamsSpec extends Specification { + + @Unroll + def "toMap should not contain null values"() { + setup: + def uploadParams = new UploadArtifactTask.UploadParams() + uploadParams.message = message + uploadParams.distributionKey = distributionKey + uploadParams.releaseNote = releaseNote + uploadParams.visibility = visibility + + and: + def params = uploadParams.toMap() + + expect: + params["message"] == message + params["distribution_key"] == distributionKey + params["release_note"] == releaseNote + params["visibility"] == visibility + message != null || !params.containsKey("message") + distributionKey != null || !params.containsKey("distribution_key") + releaseNote != null || !params.containsKey("release_note") + visibility != null || !params.containsKey("visibility") + + where: + message | distributionKey | releaseNote | visibility | isSigningReady | isUniversalApk | apkFile + null | null | null | null | false | false | null + "message" | "distributionKey" | "releaseNote" | "public" | true | true | new File("build.gradle") + } +} From 283cab9ea6711fa47a7fd2722bad2d66c6bcd362 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 02:40:09 +0900 Subject: [PATCH 02/10] Renamed apk to artifact --- .../gradle/plugins/Processor.groovy | 14 +++--- .../gradle/plugins/artifacts/AabInfo.groovy | 12 +++++ .../artifacts/DefaultPresetAabInfo.groovy | 9 ++++ .../plugins/artifacts/DirectAabInfo.groovy | 35 ++++++++++++++ .../artifacts/PackageAppTaskCompat.groovy | 1 + .../internal/agp/AndroidGradlePlugin.groovy | 5 ++ .../internal/gradle/TaskFactory.groovy | 30 +++++++++--- .../gradle/plugins/tasks/UploadAabTask.groovy | 46 +++++++++++++++++++ .../AGPBasedUploadApkTaskFactory.groovy | 6 +-- .../DSLBasedUploadApkTaskFactory.groovy | 8 ++-- .../factory/DeployGateTaskFactory.groovy | 5 ++ .../tasks/factory/UploadApkTaskFactory.groovy | 9 ---- .../factory/UploadArtifactTaskFactory.groovy | 9 ++++ .../gradle/plugins/ProcessorSpec.groovy | 12 ++--- .../AGPBasedUploadApkTaskFactorySpec.groovy | 8 ++-- .../DSLBasedUploadApkTaskFactorySpec.groovy | 16 +++---- 16 files changed, 177 insertions(+), 48 deletions(-) create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/artifacts/AabInfo.groovy create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/artifacts/DefaultPresetAabInfo.groovy create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/artifacts/DirectAabInfo.groovy create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy delete mode 100644 src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadApkTaskFactory.groovy create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadArtifactTaskFactory.groovy diff --git a/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy b/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy index 2496edc2..dc17b862 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy @@ -25,10 +25,10 @@ class Processor { private final LogoutTaskFactory logoutTaskFactory @Nonnull - private final UploadApkTaskFactory applicationVariantBasedUploadApkTaskFactory + private final UploadArtifactTaskFactory applicationVariantBasedUploadApkTaskFactory @Nonnull - private final UploadApkTaskFactory stringBasedUploadApkTaskFactory + private final UploadArtifactTaskFactory stringBasedUploadApkTaskFactory def declaredNames = new HashSet() @@ -47,8 +47,8 @@ class Processor { @Nonnull Project project, @Nonnull LoginTaskFactory loginTaskFactory, @Nonnull LogoutTaskFactory logoutTaskFactory, - @Nonnull UploadApkTaskFactory applicationVariantBasedUploadApkTaskFactory, - @Nonnull UploadApkTaskFactory stringBasedUploadApkTaskFactory + @Nonnull UploadArtifactTaskFactory applicationVariantBasedUploadApkTaskFactory, + @Nonnull UploadArtifactTaskFactory stringBasedUploadApkTaskFactory ) { this.project = project this.loginTaskFactory = loginTaskFactory @@ -79,11 +79,11 @@ class Processor { } def registerDeclarationAwareUploadApkTask(String variantOrCustomName) { - stringBasedUploadApkTaskFactory.registerUploadApkTask(variantOrCustomName, *dependencyAncestorOfUploadTaskNames) + stringBasedUploadApkTaskFactory.registerUploadArtifactTask(variantOrCustomName, *dependencyAncestorOfUploadTaskNames) } def registerAggregatedDeclarationAwareUploadApkTask(Collection variantOrCustomNames) { - stringBasedUploadApkTaskFactory.registerAggregatedUploadApkTask(variantOrCustomNames.collect { + stringBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask(variantOrCustomNames.collect { DeployGateTaskFactory.uploadApkTaskName(it) }) } @@ -94,7 +94,7 @@ class Processor { return } - applicationVariantBasedUploadApkTaskFactory.registerUploadApkTask(variant, *dependencyAncestorOfUploadTaskNames) + applicationVariantBasedUploadApkTaskFactory.registerUploadArtifactTask(variant, *dependencyAncestorOfUploadTaskNames) } @VisibleForTesting diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/AabInfo.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/AabInfo.groovy new file mode 100644 index 00000000..2ce74839 --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/AabInfo.groovy @@ -0,0 +1,12 @@ +package com.deploygate.gradle.plugins.artifacts + +import javax.annotation.Nonnull +import javax.annotation.Nullable + +interface AabInfo { + @Nonnull + String getVariantName() + + @Nullable + File getAabFile() +} \ No newline at end of file diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/DefaultPresetAabInfo.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/DefaultPresetAabInfo.groovy new file mode 100644 index 00000000..35dcb640 --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/DefaultPresetAabInfo.groovy @@ -0,0 +1,9 @@ +package com.deploygate.gradle.plugins.artifacts + +import javax.annotation.Nonnull + +class DefaultPresetAabInfo extends DirectAabInfo { + DefaultPresetAabInfo(@Nonnull String variantName) { + super(variantName, null) + } +} diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/DirectAabInfo.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/DirectAabInfo.groovy new file mode 100644 index 00000000..488992e2 --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/DirectAabInfo.groovy @@ -0,0 +1,35 @@ +package com.deploygate.gradle.plugins.artifacts + +import com.google.common.annotations.VisibleForTesting + +import javax.annotation.Nonnull +import javax.annotation.Nullable + +@VisibleForTesting +class DirectAabInfo implements AabInfo { + @Nonnull + private final String variantName + @Nullable + private final File aabFile + + DirectAabInfo(@Nonnull String variantName, @Nullable File aabFile) { + this.variantName = variantName + this.aabFile = aabFile + + if (!variantName) { + throw new IllegalArgumentException("variantName must not be null or empty") + } + } + + @Override + @Nonnull + String getVariantName() { + return variantName + } + + @Override + @Nullable + File getAabFile() { + return aabFile + } +} diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy index a6c8ce2c..d0326906 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy @@ -1,5 +1,6 @@ package com.deploygate.gradle.plugins.artifacts + import com.deploygate.gradle.plugins.internal.agp.AndroidGradlePlugin import groovy.transform.PackageScope diff --git a/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy b/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy index 3b82c5da..24ceaf32 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy @@ -61,6 +61,11 @@ class AndroidGradlePlugin { return "assemble${variantName.capitalize()}" } + @Nonnull + static String androidBundleTaskName(@Nonnull String variantName) { + return "bundle${variantName.capitalize()}" + } + /** * Get the AGP version from a classloader because `plugins` block will separate class loaders * diff --git a/src/main/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactory.groovy index 2b369dae..f806e079 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactory.groovy @@ -15,17 +15,33 @@ class TaskFactory { } @Nullable - final LazyConfigurableTask register(@Nonnull String taskName, @Nonnull Class klass, boolean allowExisting = true) { - def existingTask = project.tasks.findByName(taskName) + final LazyConfigurableTask register(@Nonnull String taskName, @Nonnull Class klass) { + def existingTask = findByName(taskName) if (existingTask) { - if (allowExisting) { - return new SingleTask(existingTask as T) - } else { - return null - } + return null } return GradleCompat.newLazyConfigurableTask(project, taskName, klass) } + + @Nullable + final LazyConfigurableTask registerOrFindBy(@Nonnull String taskName, @Nonnull Class klass) { + def existingTask = findByName(taskName) + + if (existingTask) { + return new SingleTask(existingTask as T) + } + + return GradleCompat.newLazyConfigurableTask(project, taskName, klass) + } + + final boolean exists(@Nonnull String taskName) { + return findByName(taskName) + } + + @Nullable + private Task findByName(@Nonnull String taskName) { + return project.tasks.findByName(taskName) + } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy new file mode 100644 index 00000000..5adbe57b --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy @@ -0,0 +1,46 @@ +package com.deploygate.gradle.plugins.tasks + +import com.deploygate.gradle.plugins.artifacts.AabInfo +import com.deploygate.gradle.plugins.artifacts.ApkInfo +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import com.deploygate.gradle.plugins.tasks.factory.DeployGateTaskFactory +import org.gradle.api.tasks.TaskAction + +import javax.annotation.Nonnull + +class UploadAabTask extends UploadArtifactTask { + static Configuration createConfiguration(@Nonnull NamedDeployment deployment, @Nonnull AabInfo aabInfo) { + return new Configuration( + artifactFile: deployment.sourceFile ?: aabInfo.aabFile, + isSigningReady: false, + isUniversalApk: false, + uploadParams: createUploadParams(deployment) + ) + } + + @TaskAction + void doUpload() { + super.doUpload() + } + + @Override + void applyTaskProfile() { + setDescription("Deploy assembled $variantName to DeployGate") + + if (!configuration.isSigningReady) { + // require signing config to build a signed APKs + setDescription(description + " (requires valid signingConfig setting)") + } + + if (configuration.isUniversalApk) { + group = DeployGateTaskFactory.GROUP_NAME + } + } + + @Override + void runArtifactSpecificVerification() { + if (!configuration.isSigningReady) { + throw new IllegalStateException('Cannot upload a build without code signature to DeployGate') + } + } +} diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy index 476f2d64..d664d212 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy @@ -10,13 +10,13 @@ import javax.annotation.Nonnull import static com.deploygate.gradle.plugins.internal.agp.AndroidGradlePlugin.androidAssembleTaskName -class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements UploadApkTaskFactory { +class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements UploadArtifactTaskFactory { AGPBasedUploadApkTaskFactory(@Nonnull Project project) { super(project) } @Override - void registerUploadApkTask(@Nonnull IApplicationVariant applicationVariant, Object... dependsOn) { + void registerUploadArtifactTask(@Nonnull IApplicationVariant applicationVariant, Object... dependsOn) { String variantName = applicationVariant.name // depends on other task provider, so we need to get a task right now. @@ -48,7 +48,7 @@ class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo } @Override - void registerAggregatedUploadApkTask(Object... dependsOn) { + void registerAggregatedUploadArtifactTask(Object... dependsOn) { throw new IllegalAccessException("this method is not allowed to be called") } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy index d375f320..5443f0d8 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy @@ -9,14 +9,14 @@ import org.gradle.api.Project import javax.annotation.Nonnull -class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements UploadApkTaskFactory { +class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements UploadArtifactTaskFactory { DSLBasedUploadApkTaskFactory(@Nonnull Project project) { super(project) } @Override - void registerUploadApkTask(@Nonnull String variantNameOrCustomName, Object... dependsOn) { - def lazyUploadApkTask = taskFactory.register(uploadApkTaskName(variantNameOrCustomName), UploadApkTask, false) + void registerUploadArtifactTask(@Nonnull String variantNameOrCustomName, Object... dependsOn) { + def lazyUploadApkTask = taskFactory.registerOrFindBy(uploadApkTaskName(variantNameOrCustomName), UploadApkTask) if (!lazyUploadApkTask) { project.logger.debug("It sounds $variantNameOrCustomName's upload apk task has been already registered by me or other factories") @@ -51,7 +51,7 @@ class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo } @Override - void registerAggregatedUploadApkTask(Object... dependsOn) { + void registerAggregatedUploadArtifactTask(Object... dependsOn) { if (!dependsOn?.flatten()) { project.logger.debug("skipped register aggregation tasks") return diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy index cf9b23d6..57b60f8d 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy @@ -15,6 +15,11 @@ abstract class DeployGateTaskFactory { return "$AGGREGATION_TASK_NAME${variantName.capitalize()}" } + @Nonnull + static String uploadAabTaskName(@Nonnull String variantName) { + return "$AGGREGATION_TASK_NAME${variantName.capitalize()}Aab" + } + @Nonnull final Project project @Nonnull diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadApkTaskFactory.groovy deleted file mode 100644 index ed63f4e3..00000000 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadApkTaskFactory.groovy +++ /dev/null @@ -1,9 +0,0 @@ -package com.deploygate.gradle.plugins.tasks.factory - -import javax.annotation.Nonnull - -interface UploadApkTaskFactory { - void registerUploadApkTask(@Nonnull T variantOrVariantNameOrCustomName, Object... dependsOn) - - void registerAggregatedUploadApkTask(Object... dependsOn) -} diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadArtifactTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadArtifactTaskFactory.groovy new file mode 100644 index 00000000..8da99948 --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/UploadArtifactTaskFactory.groovy @@ -0,0 +1,9 @@ +package com.deploygate.gradle.plugins.tasks.factory + +import javax.annotation.Nonnull + +interface UploadArtifactTaskFactory { + void registerUploadArtifactTask(@Nonnull T variantOrVariantNameOrCustomName, Object... dependsOn) + + void registerAggregatedUploadArtifactTask(Object... dependsOn) +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy index 3fe346ba..33013b25 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy @@ -4,7 +4,7 @@ import com.deploygate.gradle.plugins.internal.agp.AndroidGradlePlugin import com.deploygate.gradle.plugins.internal.agp.IApplicationVariant import com.deploygate.gradle.plugins.tasks.factory.LoginTaskFactory import com.deploygate.gradle.plugins.tasks.factory.LogoutTaskFactory -import com.deploygate.gradle.plugins.tasks.factory.UploadApkTaskFactory +import com.deploygate.gradle.plugins.tasks.factory.UploadArtifactTaskFactory import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder import spock.lang.Specification @@ -24,10 +24,10 @@ class ProcessorSpec extends Specification { private LogoutTaskFactory logoutTaskFactory @Nonnull - private UploadApkTaskFactory applicationVariantBasedUploadApkTaskFactory + private UploadArtifactTaskFactory applicationVariantBasedUploadApkTaskFactory @Nonnull - private UploadApkTaskFactory stringBasedUploadApkTaskFactory + private UploadArtifactTaskFactory stringBasedUploadApkTaskFactory @Nonnull private Processor processor @@ -112,7 +112,7 @@ class ProcessorSpec extends Specification { processor.registerDeclarationAwareUploadApkTask("dep1") then: - 1 * stringBasedUploadApkTaskFactory.registerUploadApkTask("dep1", LoginTaskFactory.TASK_NAME) + 1 * stringBasedUploadApkTaskFactory.registerUploadArtifactTask("dep1", LoginTaskFactory.TASK_NAME) and: 0 * loginTaskFactory._ @@ -129,7 +129,7 @@ class ProcessorSpec extends Specification { processor.registerAggregatedDeclarationAwareUploadApkTask(["dep1", "dep2", "dep3"]) then: - 1 * stringBasedUploadApkTaskFactory.registerAggregatedUploadApkTask(["uploadDeployGateDep1", "uploadDeployGateDep2", "uploadDeployGateDep3"]) + 1 * stringBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask(["uploadDeployGateDep1", "uploadDeployGateDep2", "uploadDeployGateDep3"]) and: 0 * loginTaskFactory._ @@ -174,7 +174,7 @@ class ProcessorSpec extends Specification { processor.registerVariantAwareUploadApkTask(applicationVariant) then: - 1 * applicationVariantBasedUploadApkTaskFactory.registerUploadApkTask(applicationVariant, LoginTaskFactory.TASK_NAME) + 1 * applicationVariantBasedUploadApkTaskFactory.registerUploadArtifactTask(applicationVariant, LoginTaskFactory.TASK_NAME) and: 0 * loginTaskFactory._ diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy index b8c64fd7..d46cb61a 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy @@ -39,7 +39,7 @@ class AGPBasedUploadApkTaskFactorySpec extends Specification { agpBasedUploadApkTaskFactory = new AGPBasedUploadApkTaskFactory(project) when: - agpBasedUploadApkTaskFactory.registerAggregatedUploadApkTask() + agpBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask() then: thrown(IllegalAccessException) @@ -62,7 +62,7 @@ class AGPBasedUploadApkTaskFactorySpec extends Specification { } when: - agpBasedUploadApkTaskFactory.registerUploadApkTask(variant) + agpBasedUploadApkTaskFactory.registerUploadArtifactTask(variant) and: def task = project.tasks.findByName("uploadDeployGateDep1") @@ -89,7 +89,7 @@ class AGPBasedUploadApkTaskFactorySpec extends Specification { } when: - agpBasedUploadApkTaskFactory.registerUploadApkTask(variant) + agpBasedUploadApkTaskFactory.registerUploadArtifactTask(variant) and: def firstTask = project.tasks.findByName("uploadDeployGateDep1") @@ -98,7 +98,7 @@ class AGPBasedUploadApkTaskFactorySpec extends Specification { firstTask when: - agpBasedUploadApkTaskFactory.registerUploadApkTask(variant) + agpBasedUploadApkTaskFactory.registerUploadArtifactTask(variant) and: def secondTask = project.tasks.findByName("uploadDeployGateDep1") diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy index 8827d9af..176dba43 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy @@ -36,13 +36,13 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { def taskNames = project.tasks.toList().collect { it.name } when: - dslBasedUploadApkTaskFactory.registerAggregatedUploadApkTask() + dslBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask() then: taskNames == project.tasks.toList().collect { it.name } when: - dslBasedUploadApkTaskFactory.registerAggregatedUploadApkTask([]) + dslBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask([]) then: taskNames == project.tasks.toList().collect { it.name } @@ -53,7 +53,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) when: - dslBasedUploadApkTaskFactory.registerAggregatedUploadApkTask("task1", "task2") + dslBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask("task1", "task2") and: def task = project.tasks.findByName("uploadDeployGate") @@ -75,8 +75,8 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) when: - dslBasedUploadApkTaskFactory.registerAggregatedUploadApkTask("task1", "task2") - dslBasedUploadApkTaskFactory.registerAggregatedUploadApkTask("task3", "task4") + dslBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask("task1", "task2") + dslBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask("task3", "task4") and: def task = project.tasks.findByName("uploadDeployGate") @@ -103,7 +103,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) when: - dslBasedUploadApkTaskFactory.registerUploadApkTask("dep1") + dslBasedUploadApkTaskFactory.registerUploadArtifactTask("dep1") and: def task = project.tasks.findByName("uploadDeployGateDep1") @@ -127,7 +127,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { project.tasks.create("uploadDeployGateDep1") when: - dslBasedUploadApkTaskFactory.registerUploadApkTask("dep1") + dslBasedUploadApkTaskFactory.registerUploadArtifactTask("dep1") and: def task = project.tasks.findByName("uploadDeployGateDep1") @@ -147,7 +147,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) when: - dslBasedUploadApkTaskFactory.registerUploadApkTask("dep2") + dslBasedUploadApkTaskFactory.registerUploadArtifactTask("dep2") then: thrown(GradleException) From 085ac71db85a8c003dbe75912761e7c693a55311 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 03:22:24 +0900 Subject: [PATCH 03/10] Support aab roughly --- .../gradle/plugins/DeployGatePlugin.groovy | 5 +- .../gradle/plugins/Processor.groovy | 35 +++++++++- .../artifacts/PackageAppTaskCompat.groovy | 17 +++++ .../gradle/plugins/tasks/UploadAabTask.groovy | 24 +++---- .../plugins/tasks/UploadArtifactTask.groovy | 13 ++-- .../AGPBasedUploadAabTaskFactory.groovy | 50 ++++++++++++++ .../AGPBasedUploadApkTaskFactory.groovy | 2 +- .../DSLBasedUploadAabTaskFactory.groovy | 67 +++++++++++++++++++ .../factory/DeployGateTaskFactory.groovy | 1 + 9 files changed, 192 insertions(+), 22 deletions(-) create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy create mode 100644 src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy diff --git a/src/main/groovy/com/deploygate/gradle/plugins/DeployGatePlugin.groovy b/src/main/groovy/com/deploygate/gradle/plugins/DeployGatePlugin.groovy index 72497e62..2dbb03e4 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/DeployGatePlugin.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/DeployGatePlugin.groovy @@ -68,11 +68,12 @@ class DeployGatePlugin implements Plugin { processor.registerDeclarationAwareUploadApkTask(variantOrCustomName) if (AndroidGradlePlugin.isAppBundleSupported()) { - // TODO create tasks for app bundle + processor.registerDeclarationAwareUploadAabTask(variantOrCustomName) } } processor.registerAggregatedDeclarationAwareUploadApkTask(processor.declaredNames) + processor.registerAggregatedDeclarationAwareUploadAabTask(processor.declaredNames) if (!processor.canProcessVariantAware()) { project.logger.warn("DeployGate Gradle Plugin is stopped because Android Gradle Plugin must be applied before.") @@ -85,7 +86,7 @@ class DeployGatePlugin implements Plugin { processor.registerVariantAwareUploadApkTask(variantProxy) if (AndroidGradlePlugin.isAppBundleSupported()) { - // TODO create tasks for app bundle + processor.registerVariantAwareUploadAabTask(variantProxy) } } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy b/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy index dc17b862..d544dcc0 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/Processor.groovy @@ -27,9 +27,15 @@ class Processor { @Nonnull private final UploadArtifactTaskFactory applicationVariantBasedUploadApkTaskFactory + @Nonnull + private final UploadArtifactTaskFactory applicationVariantBasedUploadAabTaskFactory + @Nonnull private final UploadArtifactTaskFactory stringBasedUploadApkTaskFactory + @Nonnull + private final UploadArtifactTaskFactory stringBasedUploadAabTaskFactory + def declaredNames = new HashSet() Processor(@Nonnull Project project) { @@ -38,7 +44,9 @@ class Processor { new LoginTaskFactoryImpl(project), new LogoutTaskFactoryImpl(project), new AGPBasedUploadApkTaskFactory(project), - new DSLBasedUploadApkTaskFactory(project) + new AGPBasedUploadAabTaskFactory(project), + new DSLBasedUploadApkTaskFactory(project), + new DSLBasedUploadAabTaskFactory(project) ) } @@ -48,13 +56,17 @@ class Processor { @Nonnull LoginTaskFactory loginTaskFactory, @Nonnull LogoutTaskFactory logoutTaskFactory, @Nonnull UploadArtifactTaskFactory applicationVariantBasedUploadApkTaskFactory, - @Nonnull UploadArtifactTaskFactory stringBasedUploadApkTaskFactory + @Nonnull UploadArtifactTaskFactory applicationVariantBasedUploadAabTaskFactory, + @Nonnull UploadArtifactTaskFactory stringBasedUploadApkTaskFactory, + @Nonnull UploadArtifactTaskFactory stringBasedUploadAabTaskFactory ) { this.project = project this.loginTaskFactory = loginTaskFactory this.logoutTaskFactory = logoutTaskFactory this.applicationVariantBasedUploadApkTaskFactory = applicationVariantBasedUploadApkTaskFactory + this.applicationVariantBasedUploadAabTaskFactory = applicationVariantBasedUploadAabTaskFactory this.stringBasedUploadApkTaskFactory = stringBasedUploadApkTaskFactory + this.stringBasedUploadAabTaskFactory = stringBasedUploadAabTaskFactory } boolean canProcessVariantAware() { @@ -82,12 +94,22 @@ class Processor { stringBasedUploadApkTaskFactory.registerUploadArtifactTask(variantOrCustomName, *dependencyAncestorOfUploadTaskNames) } + def registerDeclarationAwareUploadAabTask(String variantOrCustomName) { + stringBasedUploadAabTaskFactory.registerUploadArtifactTask(variantOrCustomName, *dependencyAncestorOfUploadTaskNames) + } + def registerAggregatedDeclarationAwareUploadApkTask(Collection variantOrCustomNames) { stringBasedUploadApkTaskFactory.registerAggregatedUploadArtifactTask(variantOrCustomNames.collect { DeployGateTaskFactory.uploadApkTaskName(it) }) } + def registerAggregatedDeclarationAwareUploadAabTask(Collection variantOrCustomNames) { + stringBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask(variantOrCustomNames.collect { + DeployGateTaskFactory.uploadApkTaskName(it) + }) + } + def registerVariantAwareUploadApkTask(@Nonnull IApplicationVariant variant) { if (!canProcessVariantAware()) { project.logger.error("android gradle plugin not found but tried to create android-specific tasks. Ignored...") @@ -97,6 +119,15 @@ class Processor { applicationVariantBasedUploadApkTaskFactory.registerUploadArtifactTask(variant, *dependencyAncestorOfUploadTaskNames) } + def registerVariantAwareUploadAabTask(@Nonnull IApplicationVariant variant) { + if (!canProcessVariantAware()) { + project.logger.error("android gradle plugin not found but tried to create android-specific tasks. Ignored...") + return + } + + applicationVariantBasedUploadAabTaskFactory.registerUploadArtifactTask(variant, *dependencyAncestorOfUploadTaskNames) + } + @VisibleForTesting static String[] getDependencyAncestorOfUploadTaskNames() { return [LoginTaskFactory.TASK_NAME] diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy index d0326906..f709184d 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy @@ -27,6 +27,23 @@ class PackageAppTaskCompat { ) } + @Nonnull + static AabInfo getAabInfo(@Nonnull /* PackageApplication */ packageAppTask) { + String variantName = packageAppTask.name + // outputScope is retrieved by the reflection + Collection apkNames = packageAppTask.outputScope.apkDatas*.outputFileName + File outputDir = packageAppTask.outputDirectory + File apkFile = new File(outputDir, (String) apkNames[0]) + + // FIXME toooooooooooo dirty hack! + def aabFile = new File(apkFile.getPath().replaceAll("\\.apk\$", ".aab").reverse().replaceAll("/apk/".reverse(), "/bundle/".reverse()).reverse()) + + return new DirectAabInfo( + variantName, + aabFile, + ) + } + @PackageScope static boolean hasSigningConfig(packageAppTask) { if (!AndroidGradlePlugin.isSigningConfigCollectionSupported()) { diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy index 5adbe57b..f1d4a4ab 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy @@ -1,7 +1,6 @@ package com.deploygate.gradle.plugins.tasks import com.deploygate.gradle.plugins.artifacts.AabInfo -import com.deploygate.gradle.plugins.artifacts.ApkInfo import com.deploygate.gradle.plugins.dsl.NamedDeployment import com.deploygate.gradle.plugins.tasks.factory.DeployGateTaskFactory import org.gradle.api.tasks.TaskAction @@ -18,29 +17,28 @@ class UploadAabTask extends UploadArtifactTask { ) } + private def lazyPackageApplication + + void setLazyPackageApplication(lazyPackageApplication) { + this.lazyPackageApplication = lazyPackageApplication + } + @TaskAction void doUpload() { + // evaluate immediately + lazyPackageApplication.get() + super.doUpload() } @Override void applyTaskProfile() { - setDescription("Deploy assembled $variantName to DeployGate") - - if (!configuration.isSigningReady) { - // require signing config to build a signed APKs - setDescription(description + " (requires valid signingConfig setting)") - } + setDescription("Deploy bundled $variantName to DeployGate") - if (configuration.isUniversalApk) { - group = DeployGateTaskFactory.GROUP_NAME - } + group = DeployGateTaskFactory.GROUP_NAME } @Override void runArtifactSpecificVerification() { - if (!configuration.isSigningReady) { - throw new IllegalStateException('Cannot upload a build without code signature to DeployGate') - } } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy index 23cab807..72cb53ce 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy @@ -7,6 +7,7 @@ import com.deploygate.gradle.plugins.utils.HTTPBuilderFactory import com.google.common.annotations.VisibleForTesting import groovyx.net.http.ContentType import groovyx.net.http.HttpResponseDecorator +import groovyx.net.http.HttpResponseException import groovyx.net.http.Method import org.apache.http.entity.mime.MultipartEntity import org.apache.http.entity.mime.content.FileBody @@ -177,9 +178,13 @@ abstract class UploadArtifactTask extends DefaultTask { entity.addPart(key, new StringBody(params.get(key), charset)) } - HTTPBuilderFactory.restClient(project.deploygate.endpoint).request(Method.POST, ContentType.JSON) { req -> - uri.path = "/api/users/${appOwnerName}/apps" - req.entity = entity - } as HttpResponseDecorator + try { + HTTPBuilderFactory.restClient(project.deploygate.endpoint).request(Method.POST, ContentType.JSON) { req -> + uri.path = "/api/users/${appOwnerName}/apps" + req.entity = entity + } as HttpResponseDecorator + } catch (HttpResponseException e) { + e.response + } } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy new file mode 100644 index 00000000..d92ba2ff --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy @@ -0,0 +1,50 @@ +package com.deploygate.gradle.plugins.tasks.factory + +import com.deploygate.gradle.plugins.artifacts.PackageAppTaskCompat +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import com.deploygate.gradle.plugins.internal.agp.IApplicationVariant +import com.deploygate.gradle.plugins.tasks.UploadAabTask +import org.gradle.api.Project + +import javax.annotation.Nonnull + +import static com.deploygate.gradle.plugins.internal.agp.AndroidGradlePlugin.androidBundleTaskName + +class AGPBasedUploadAabTaskFactory extends DeployGateTaskFactory implements UploadArtifactTaskFactory { + AGPBasedUploadAabTaskFactory(@Nonnull Project project) { + super(project) + } + + @Override + void registerUploadArtifactTask(@Nonnull IApplicationVariant applicationVariant, Object... dependsOn) { + String variantName = applicationVariant.name + + // depends on other task provider, so we need to get a task right now. + def dgTask = taskFactory.registerOrFindBy(uploadAabTaskName(variantName), UploadAabTask).get() + + final NamedDeployment deployment = deployGateExtension.findDeploymentByName(variantName) + + dgTask.variantName = variantName + + if (deployment?.skipAssemble) { + dgTask.dependsOn(dependsOn) + } else { + dgTask.dependsOn([androidBundleTaskName(variantName), *dependsOn].flatten()) + } + + dgTask.lazyPackageApplication = applicationVariant.lazyPackageApplication() + + applicationVariant.lazyPackageApplication().configure { packageAppTask -> + def aabInfo = PackageAppTaskCompat.getAabInfo(packageAppTask) + def configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + + dgTask.configuration = configuration + dgTask.applyTaskProfile() + } + } + + @Override + void registerAggregatedUploadArtifactTask(Object... dependsOn) { + throw new IllegalAccessException("this method is not allowed to be called") + } +} diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy index d664d212..a7f7d7fe 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy @@ -20,7 +20,7 @@ class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo String variantName = applicationVariant.name // depends on other task provider, so we need to get a task right now. - def dgTask = taskFactory.register(uploadApkTaskName(variantName), UploadApkTask).get() + def dgTask = taskFactory.registerOrFindBy(uploadApkTaskName(variantName), UploadApkTask).get() final NamedDeployment deployment = deployGateExtension.findDeploymentByName(variantName) diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy new file mode 100644 index 00000000..4e5c3044 --- /dev/null +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy @@ -0,0 +1,67 @@ +package com.deploygate.gradle.plugins.tasks.factory + +import com.deploygate.gradle.plugins.artifacts.DefaultPresetAabInfo +import com.deploygate.gradle.plugins.artifacts.DefaultPresetApkInfo +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import com.deploygate.gradle.plugins.tasks.UploadAabTask +import com.deploygate.gradle.plugins.tasks.UploadApkTask +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.Project + +import javax.annotation.Nonnull + +class DSLBasedUploadAabTaskFactory extends DeployGateTaskFactory implements UploadArtifactTaskFactory { + DSLBasedUploadAabTaskFactory(@Nonnull Project project) { + super(project) + } + + @Override + void registerUploadArtifactTask(@Nonnull String variantNameOrCustomName, Object... dependsOn) { + def lazyUploadAabTask = taskFactory.registerOrFindBy(uploadAabTaskName(variantNameOrCustomName), UploadAabTask) + + if (!lazyUploadAabTask) { + project.logger.debug("It sounds $variantNameOrCustomName's upload aab task has been already registered by me or other factories") + return + } + + if (!deployGateExtension.hasDeployment(variantNameOrCustomName)) { + project.logger.error("No associated deployment to $variantNameOrCustomName has been detected") + project.logger.error("Please report this problem from https://github.com/DeployGate/gradle-deploygate-plugin/issues") + + throw new GradleException("$variantNameOrCustomName could not be handled by DeployGate plugin") + } + + final NamedDeployment deployment = deployGateExtension.findDeploymentByName(variantNameOrCustomName) + + if (!deployment.skipAssemble) { + project.logger.debug("$variantNameOrCustomName required assmble but ignored") + } + + lazyUploadAabTask.configure { dgTask -> + dgTask.variantName = variantNameOrCustomName + dgTask.dependsOn(dependsOn) + } + + def aabInfo = new DefaultPresetAabInfo(variantNameOrCustomName) + def configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + + lazyUploadAabTask.configure { dgTask -> + dgTask.configuration = configuration + dgTask.applyTaskProfile() + } + } + + @Override + void registerAggregatedUploadArtifactTask(Object... dependsOn) { + if (!dependsOn?.flatten()) { + project.logger.debug("skipped register aggregation tasks") + return + } + + taskFactory.register(AGGREGATION_AAB_TASK_NAME, DefaultTask).configure { dgTask -> + dgTask.group = GROUP_NAME + dgTask.dependsOn(dependsOn.flatten()) + } + } +} diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy index 57b60f8d..704ee302 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy @@ -9,6 +9,7 @@ import javax.annotation.Nonnull abstract class DeployGateTaskFactory { public static final String GROUP_NAME = 'DeployGate' public static String AGGREGATION_TASK_NAME = "uploadDeployGate" + public static String AGGREGATION_AAB_TASK_NAME = "uploadDeployGateAab" @Nonnull static String uploadApkTaskName(@Nonnull String variantName) { From c5aa8240246e4f317a7c04ea8ab3dfe479366172 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 03:23:07 +0900 Subject: [PATCH 04/10] Renamed fields --- .../tasks/factory/DSLBasedUploadApkTaskFactory.groovy | 2 +- .../plugins/tasks/factory/DeployGateTaskFactory.groovy | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy index 5443f0d8..2eaf5946 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy @@ -57,7 +57,7 @@ class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo return } - taskFactory.register(AGGREGATION_TASK_NAME, DefaultTask).configure { dgTask -> + taskFactory.register(AGGREGATION_APK_TASK_NAME, DefaultTask).configure { dgTask -> dgTask.group = GROUP_NAME dgTask.dependsOn(dependsOn.flatten()) } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy index 704ee302..9728d17c 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy @@ -8,17 +8,18 @@ import javax.annotation.Nonnull abstract class DeployGateTaskFactory { public static final String GROUP_NAME = 'DeployGate' - public static String AGGREGATION_TASK_NAME = "uploadDeployGate" + public static String PREFIX_TASK_NAME = "uploadDeployGate" + public static String AGGREGATION_APK_TASK_NAME = "uploadDeployGate" public static String AGGREGATION_AAB_TASK_NAME = "uploadDeployGateAab" @Nonnull static String uploadApkTaskName(@Nonnull String variantName) { - return "$AGGREGATION_TASK_NAME${variantName.capitalize()}" + return "$PREFIX_TASK_NAME${variantName.capitalize()}" } @Nonnull static String uploadAabTaskName(@Nonnull String variantName) { - return "$AGGREGATION_TASK_NAME${variantName.capitalize()}Aab" + return "$PREFIX_TASK_NAME${variantName.capitalize()}Aab" } @Nonnull From 665fc22fd71245b916f7f585e791a723acfc5934 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 03:42:25 +0900 Subject: [PATCH 05/10] Fixed Groovy specs --- .../gradle/plugins/tasks/UploadAabTask.groovy | 1 + .../DSLBasedUploadAabTaskFactory.groovy | 4 +- .../DSLBasedUploadApkTaskFactory.groovy | 4 +- .../tasks/factory/LoginTaskFactoryImpl.groovy | 2 +- .../factory/LogoutTaskFactoryImpl.groovy | 2 +- .../gradle/plugins/ProcessorSpec.groovy | 38 ++++- .../internal/gradle/TaskFactorySpec.groovy | 46 ++++-- .../UploadAabTaskConfigurationSpec.groovy | 64 ++++++++ .../plugins/tasks/UploadAabTaskSpec.groovy | 25 +++ .../AGPBasedUploadAabTaskFactorySpec.groovy | 111 +++++++++++++ .../AGPBasedUploadApkTaskFactorySpec.groovy | 4 +- .../DSLBasedUploadAabTaskFactorySpec.groovy | 155 ++++++++++++++++++ .../DSLBasedUploadApkTaskFactorySpec.groovy | 12 +- 13 files changed, 435 insertions(+), 33 deletions(-) create mode 100644 src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskConfigurationSpec.groovy create mode 100644 src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskSpec.groovy create mode 100644 src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy create mode 100644 src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy index f1d4a4ab..4351c48b 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy @@ -26,6 +26,7 @@ class UploadAabTask extends UploadArtifactTask { @TaskAction void doUpload() { // evaluate immediately + assert lazyPackageApplication != null lazyPackageApplication.get() super.doUpload() diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy index 4e5c3044..9b385aef 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy @@ -18,7 +18,7 @@ class DSLBasedUploadAabTaskFactory extends DeployGateTaskFactory implements Uplo @Override void registerUploadArtifactTask(@Nonnull String variantNameOrCustomName, Object... dependsOn) { - def lazyUploadAabTask = taskFactory.registerOrFindBy(uploadAabTaskName(variantNameOrCustomName), UploadAabTask) + def lazyUploadAabTask = taskFactory.register(uploadAabTaskName(variantNameOrCustomName), UploadAabTask) if (!lazyUploadAabTask) { project.logger.debug("It sounds $variantNameOrCustomName's upload aab task has been already registered by me or other factories") @@ -59,7 +59,7 @@ class DSLBasedUploadAabTaskFactory extends DeployGateTaskFactory implements Uplo return } - taskFactory.register(AGGREGATION_AAB_TASK_NAME, DefaultTask).configure { dgTask -> + taskFactory.registerOrFindBy(AGGREGATION_AAB_TASK_NAME, DefaultTask).configure { dgTask -> dgTask.group = GROUP_NAME dgTask.dependsOn(dependsOn.flatten()) } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy index 2eaf5946..1bc960ca 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy @@ -16,7 +16,7 @@ class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo @Override void registerUploadArtifactTask(@Nonnull String variantNameOrCustomName, Object... dependsOn) { - def lazyUploadApkTask = taskFactory.registerOrFindBy(uploadApkTaskName(variantNameOrCustomName), UploadApkTask) + def lazyUploadApkTask = taskFactory.register(uploadApkTaskName(variantNameOrCustomName), UploadApkTask) if (!lazyUploadApkTask) { project.logger.debug("It sounds $variantNameOrCustomName's upload apk task has been already registered by me or other factories") @@ -57,7 +57,7 @@ class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo return } - taskFactory.register(AGGREGATION_APK_TASK_NAME, DefaultTask).configure { dgTask -> + taskFactory.registerOrFindBy(AGGREGATION_APK_TASK_NAME, DefaultTask).configure { dgTask -> dgTask.group = GROUP_NAME dgTask.dependsOn(dependsOn.flatten()) } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LoginTaskFactoryImpl.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LoginTaskFactoryImpl.groovy index 9f7a1d80..015ceb61 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LoginTaskFactoryImpl.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LoginTaskFactoryImpl.groovy @@ -12,7 +12,7 @@ class LoginTaskFactoryImpl extends DeployGateTaskFactory implements LoginTaskFac @Override void registerLoginTask() { - taskFactory.register(TASK_NAME, LoginTask).configure { + taskFactory.registerOrFindBy(TASK_NAME, LoginTask).configure { it.group = GROUP_NAME } } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LogoutTaskFactoryImpl.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LogoutTaskFactoryImpl.groovy index 053ee3e2..60b60e08 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LogoutTaskFactoryImpl.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/LogoutTaskFactoryImpl.groovy @@ -12,7 +12,7 @@ class LogoutTaskFactoryImpl extends DeployGateTaskFactory implements LogoutTaskF @Override void registerLogoutTask() { - taskFactory.register(TASK_NAME, LogoutTask).configure { + taskFactory.registerOrFindBy(TASK_NAME, LogoutTask).configure { it.group = GROUP_NAME } } diff --git a/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy index 33013b25..f2ef0ad1 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/ProcessorSpec.groovy @@ -26,9 +26,15 @@ class ProcessorSpec extends Specification { @Nonnull private UploadArtifactTaskFactory applicationVariantBasedUploadApkTaskFactory + @Nonnull + private UploadArtifactTaskFactory applicationVariantBasedUploadAabTaskFactory + @Nonnull private UploadArtifactTaskFactory stringBasedUploadApkTaskFactory + @Nonnull + private UploadArtifactTaskFactory stringBasedUploadAabTaskFactory + @Nonnull private Processor processor @@ -37,12 +43,14 @@ class ProcessorSpec extends Specification { loginTaskFactory = Mock() logoutTaskFactory = Mock() applicationVariantBasedUploadApkTaskFactory = Mock() + applicationVariantBasedUploadAabTaskFactory = Mock() stringBasedUploadApkTaskFactory = Mock() + stringBasedUploadAabTaskFactory = Mock() } def "addVariantOrCustomName should store given names except empty"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) when: processor.addVariantOrCustomName("") @@ -67,12 +75,14 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } def "registerLoginTask should manipulate LoginTaskFactory"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) when: processor.registerLoginTask() @@ -84,12 +94,14 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } def "registerLogoutTask should manipulate LogoutTaskFactory"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) when: processor.registerLogoutTask() @@ -101,12 +113,14 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } def "registerDeclarationAwareUploadApkTask should manipulate String-based UploadApkTaskFactory"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) when: processor.registerDeclarationAwareUploadApkTask("dep1") @@ -118,12 +132,14 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } def "registerAggregatedDeclarationAwareUploadApkTask should collect upload tasks"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) when: processor.registerAggregatedDeclarationAwareUploadApkTask(["dep1", "dep2", "dep3"]) @@ -135,13 +151,15 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } @ConfineMetaClassChanges([AndroidGradlePlugin]) def "registerVariantAwareUploadApkTask should not do nothing unless AndroidGradlePlugin is applied"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) IApplicationVariant applicationVariant = Mock() and: @@ -156,13 +174,15 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } @ConfineMetaClassChanges([AndroidGradlePlugin]) def "registerVariantAwareUploadApkTask should manipulate IApplicationVariant-based UploadApkTaskFactory if AndroidGradlePlugin is applied"() { given: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) IApplicationVariant applicationVariant = Mock() and: @@ -180,7 +200,9 @@ class ProcessorSpec extends Specification { 0 * loginTaskFactory._ 0 * logoutTaskFactory._ 0 * applicationVariantBasedUploadApkTaskFactory._ + 0 * applicationVariantBasedUploadAabTaskFactory._ 0 * stringBasedUploadApkTaskFactory._ + 0 * stringBasedUploadAabTaskFactory._ } def "just check getDependencyAncestorOfUploadTaskNames"() { @@ -195,7 +217,7 @@ class ProcessorSpec extends Specification { @Unroll def "canProcessVariantAware should depend on AndroidGradlePlugin.isApplied (#isAGPApplied)"() { setup: - processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, stringBasedUploadApkTaskFactory) + processor = new Processor(project, loginTaskFactory, logoutTaskFactory, applicationVariantBasedUploadApkTaskFactory, applicationVariantBasedUploadAabTaskFactory, stringBasedUploadApkTaskFactory, stringBasedUploadAabTaskFactory) and: AndroidGradlePlugin.metaClass.static.isApplied = { Project _ -> diff --git a/src/test/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactorySpec.groovy index 2c8b1885..595e354c 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/internal/gradle/TaskFactorySpec.groovy @@ -34,7 +34,7 @@ class TaskFactorySpec extends Specification { TaskFactory taskFactory = new TaskFactory(project) and: - def result = taskFactory.register(taskName, DefaultTask) + def result = taskFactory.registerOrFindBy(taskName, DefaultTask) expect: expectedTaskClass.isInstance(result) @@ -53,7 +53,7 @@ class TaskFactorySpec extends Specification { @ConfineMetaClassChanges([GradleCompat]) @Unroll - def "TaskFactory can handle duplicated tasks regardless of #gradleVersion"() { + def "TaskFactory#register does nothing if a task is duplicated regardless of #gradleVersion"() { given: Project project = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build() @@ -66,10 +66,41 @@ class TaskFactorySpec extends Specification { taskFactory.register(taskName, DefaultTask) and: - def result = taskFactory.register(taskName, DefaultTask, allowExisting) + def result = taskFactory.register(taskName, DefaultTask) expect: - !allowExisting && result == null || expectedTaskClass.isInstance(result) + result == null + + where: + taskName | gradleVersion | allowExisting + "agp300" | "4.1" | false + "agp310" | "4.4" | false + "agp320" | "4.6" | false + "border" | "4.7" | false + "border" | "4.8" | false + "agp330" | "4.10.1" | false + "agp340-beta04" | "5.1.1" | false + } + + @ConfineMetaClassChanges([GradleCompat]) + @Unroll + def "TaskFactory#registerOrFindBy return an existing task if duplicated regardless of #gradleVersion"() { + given: + Project project = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build() + + GradleCompat.metaClass.static.getVersion = { -> + VersionString.tryParse(gradleVersion) + } + + and: + TaskFactory taskFactory = new TaskFactory(project) + taskFactory.register(taskName, DefaultTask) + + and: + def result = taskFactory.registerOrFindBy(taskName, DefaultTask) + + expect: + expectedTaskClass.isInstance(result) where: taskName | gradleVersion | allowExisting | expectedTaskClass @@ -80,12 +111,5 @@ class TaskFactorySpec extends Specification { "border" | "4.8" | true | SingleTask "agp330" | "4.10.1" | true | SingleTask "agp340-beta04" | "5.1.1" | true | SingleTask - "agp300" | "4.1" | false | null - "agp310" | "4.4" | false | null - "agp320" | "4.6" | false | null - "border" | "4.7" | false | null - "border" | "4.8" | false | null - "agp330" | "4.10.1" | false | null - "agp340-beta04" | "5.1.1" | false | null } } diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskConfigurationSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskConfigurationSpec.groovy new file mode 100644 index 00000000..8f794799 --- /dev/null +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskConfigurationSpec.groovy @@ -0,0 +1,64 @@ +package com.deploygate.gradle.plugins.tasks + +import com.deploygate.gradle.plugins.artifacts.DirectAabInfo +import com.deploygate.gradle.plugins.dsl.Distribution +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import spock.lang.Specification +import spock.lang.Unroll + +class UploadAabTaskConfigurationSpec extends Specification { + + @Unroll + def "create a configuration"() { + setup: + def deployment = new NamedDeployment("dep1") + deployment.message = message + deployment.distribution { Distribution distribution -> + distribution.key = distributionKey + distribution.releaseNote = distributionReleaseNote + } + deployment.visibility = visibility + deployment.skipAssemble = skipAssemble + + and: + def aabInfo = new DirectAabInfo("dep1", null) + + and: + def configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + + expect: + configuration.uploadParams.message == message + configuration.uploadParams.distributionKey == distributionKey + configuration.uploadParams.releaseNote == distributionReleaseNote + configuration.uploadParams.visibility == visibility + + where: + message | distributionKey | distributionReleaseNote | visibility | skipAssemble + null | null | null | null | false + "message" | "distributionKey" | "distributionReleaseNote" | "public" | true + } + + @Unroll + def "create a configuration for aab file handling"() { + setup: + def deployment = new NamedDeployment("dep1") + deployment.sourceFile = sourceFile + + and: + def aabInfo = new DirectAabInfo("dep1", aabFile) + + and: + def configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + + expect: + configuration.artifactFile == sourceFile ?: aabFile + + where: + sourceFile | aabFile + null | null + null | new File("build.gradle") + new File("build.gradle") | null + new File("build.gradle") | new File("build.gradle") + } + +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskSpec.groovy new file mode 100644 index 00000000..7d4e9fe8 --- /dev/null +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTaskSpec.groovy @@ -0,0 +1,25 @@ +package com.deploygate.gradle.plugins.tasks + + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +import javax.annotation.Nonnull + +class UploadAabTaskSpec extends Specification { + + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + + @Nonnull + private Project project + + def setup() { + project = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build() + } + + // no specific assertions +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy new file mode 100644 index 00000000..b563aa07 --- /dev/null +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy @@ -0,0 +1,111 @@ +package com.deploygate.gradle.plugins.tasks.factory + +import com.deploygate.gradle.plugins.artifacts.DirectAabInfo +import com.deploygate.gradle.plugins.artifacts.DirectApkInfo +import com.deploygate.gradle.plugins.artifacts.PackageAppTaskCompat +import com.deploygate.gradle.plugins.dsl.DeployGateExtension +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import com.deploygate.gradle.plugins.internal.agp.IApplicationVariant +import com.deploygate.gradle.plugins.internal.gradle.GradleCompat +import com.deploygate.gradle.plugins.internal.gradle.LazyConfigurableTask +import com.deploygate.gradle.plugins.tasks.UploadAabTask +import com.deploygate.gradle.plugins.tasks.UploadApkTask +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import spock.lang.Specification +import spock.util.mop.ConfineMetaClassChanges + +import javax.annotation.Nonnull + +class AGPBasedUploadAabTaskFactorySpec extends Specification { + @Nonnull + private Project project + + @Nonnull + private NamedDomainObjectContainer deployments + + @Nonnull + private AGPBasedUploadAabTaskFactory agpBasedUploadAabTaskFactory + + def setup() { + project = ProjectBuilder.builder().build() + GradleCompat.init(project) + deployments = project.container(NamedDeployment) + + project.extensions.add("deploygate", new DeployGateExtension(project, deployments)) + } + + def "registerAggregatedUploadApkTask should not be supported"() { + given: + agpBasedUploadAabTaskFactory = new AGPBasedUploadAabTaskFactory(project) + + when: + agpBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask() + + then: + thrown(IllegalAccessException) + } + + @ConfineMetaClassChanges([PackageAppTaskCompat]) + def "registerUploadArtifactTask should add a UploadApkTask"() { + setup: + def variantName = "dep1" + def variant = Mock(IApplicationVariant) + variant.name >> variantName + variant.lazyPackageApplication() >> Stub(LazyConfigurableTask, name: variantName) + + and: + agpBasedUploadAabTaskFactory = new AGPBasedUploadAabTaskFactory(project) + + and: + PackageAppTaskCompat.metaClass.static.getAabInfo = { LazyConfigurableTask _ -> + new DirectAabInfo(variantName, null) + } + + when: + agpBasedUploadAabTaskFactory.registerUploadArtifactTask(variant) + + and: + def task = project.tasks.findByName("uploadDeployGateDep1Aab") + + then: + task + task instanceof UploadAabTask + } + + @ConfineMetaClassChanges([PackageAppTaskCompat]) + def "registerUploadArtifactTask should modify the existing instance if already exist"() { + given: + def variantName = "dep1" + def variant = Mock(IApplicationVariant) + variant.name >> variantName + variant.lazyPackageApplication() >> Stub(LazyConfigurableTask, name: variantName) + + and: + agpBasedUploadAabTaskFactory = new AGPBasedUploadAabTaskFactory(project) + + and: + PackageAppTaskCompat.metaClass.static.getAabInfo = { LazyConfigurableTask _ -> + new DirectAabInfo(variantName, null) + } + + when: + agpBasedUploadAabTaskFactory.registerUploadArtifactTask(variant) + + and: + def firstTask = project.tasks.findByName("uploadDeployGateDep1Aab") + + then: + firstTask + + when: + agpBasedUploadAabTaskFactory.registerUploadArtifactTask(variant) + + and: + def secondTask = project.tasks.findByName("uploadDeployGateDep1Aab") + + then: + firstTask == secondTask + } +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy index d46cb61a..65509050 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactorySpec.groovy @@ -46,7 +46,7 @@ class AGPBasedUploadApkTaskFactorySpec extends Specification { } @ConfineMetaClassChanges([PackageAppTaskCompat]) - def "registerUploadApkTask should add a UploadApkTask"() { + def "registerUploadArtifactTask should add a UploadApkTask"() { setup: def variantName = "dep1" def variant = Mock(IApplicationVariant) @@ -73,7 +73,7 @@ class AGPBasedUploadApkTaskFactorySpec extends Specification { } @ConfineMetaClassChanges([PackageAppTaskCompat]) - def "registerUploadApkTask should modify the existing instance if already exist"() { + def "registerUploadArtifactTask should modify the existing instance if already exist"() { given: def variantName = "dep1" def variant = Mock(IApplicationVariant) diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy new file mode 100644 index 00000000..ed26ca85 --- /dev/null +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy @@ -0,0 +1,155 @@ +package com.deploygate.gradle.plugins.tasks.factory + +import com.deploygate.gradle.plugins.dsl.DeployGateExtension +import com.deploygate.gradle.plugins.dsl.NamedDeployment +import com.deploygate.gradle.plugins.internal.gradle.GradleCompat +import com.deploygate.gradle.plugins.tasks.UploadAabTask +import org.gradle.api.GradleException +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +import javax.annotation.Nonnull + +class DSLBasedUploadAabTaskFactorySpec extends Specification { + + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + + @Nonnull + private Project project + + @Nonnull + private DSLBasedUploadAabTaskFactory dslBasedUploadAabTaskFactory + + def setup() { + project = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build() + GradleCompat.init(project) + } + + def "registerAggregatedUploadArtifactTask should not add any task if empty is given"() { + given: + dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) + def taskNames = project.tasks.toList().collect { it.name } + + when: + dslBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask() + + then: + taskNames == project.tasks.toList().collect { it.name } + + when: + dslBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask([]) + + then: + taskNames == project.tasks.toList().collect { it.name } + } + + def "registerAggregatedUploadArtifactTask should add a task which run given tasks only once"() { + given: + dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) + + when: + dslBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask("task1", "task2") + + and: + def task = project.tasks.findByName("uploadDeployGateAab") + + then: + task.dependsOn.flatten().collect { + if (it.hasProperty("taskName")) { + it.taskName + } else if (it.hasProperty("name")) { + it.name + } else { + it + } + } == ["task1", "task2"] + } + + def "registerAggregatedUploadArtifactTask should modify the existing itself if called twice"() { + given: + dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) + + when: + dslBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask("task1", "task2") + dslBasedUploadAabTaskFactory.registerAggregatedUploadArtifactTask("task3", "task4") + + and: + def task = project.tasks.findByName("uploadDeployGateAab") + + then: + task.dependsOn.flatten().collect { + if (it.hasProperty("taskName")) { + it.taskName + } else if (it.hasProperty("name")) { + it.name + } else { + it + } + } == ["task1", "task2", "task3", "task4"] + } + + def "registerAggregatedUploadArtifactTask should add a UploadAabTask"() { + given: + NamedDomainObjectContainer deployments = project.container(NamedDeployment) + deployments.create("dep1") + project.extensions.add("deploygate", new DeployGateExtension(project, deployments)) + + and: + dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) + + when: + dslBasedUploadAabTaskFactory.registerUploadArtifactTask("dep1") + + and: + def task = project.tasks.findByName("uploadDeployGateDep1Aab") + + then: + task + task instanceof UploadAabTask + task.group == DeployGateTaskFactory.GROUP_NAME + } + + def "registerAggregatedUploadArtifactTask should not override itself if already exist"() { + given: + NamedDomainObjectContainer deployments = project.container(NamedDeployment) + deployments.create("dep1") + project.extensions.add("deploygate", new DeployGateExtension(project, deployments)) + + and: + dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) + + and: + project.tasks.create("uploadDeployGateDep1Aab") + + when: + dslBasedUploadAabTaskFactory.registerUploadArtifactTask("dep1") + + and: + def task = project.tasks.findByName("uploadDeployGateDep1Aab") + + then: + task + !(task instanceof UploadAabTask) + } + + def "registerAggregatedUploadArtifactTask should not allow adding names which do not exist in build.gradle"() { + given: + NamedDomainObjectContainer deployments = project.container(NamedDeployment) + deployments.create("dep1") + project.extensions.add("deploygate", new DeployGateExtension(project, deployments)) + + and: + dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) + + when: + dslBasedUploadAabTaskFactory.registerUploadArtifactTask("dep2") + + then: + thrown(GradleException) + } +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy index 176dba43..271139b1 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactorySpec.groovy @@ -30,7 +30,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { GradleCompat.init(project) } - def "registerAggregatedUploadApkTask should not add any task if empty is given"() { + def "registerAggregatedUploadArtifactTask should not add any task if empty is given"() { given: dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) def taskNames = project.tasks.toList().collect { it.name } @@ -48,7 +48,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { taskNames == project.tasks.toList().collect { it.name } } - def "registerAggregatedUploadApkTask should add a task which run given tasks only once"() { + def "registerAggregatedUploadArtifactTask should add a task which run given tasks only once"() { given: dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) @@ -70,7 +70,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { } == ["task1", "task2"] } - def "registerAggregatedUploadApkTask should modify the existing itself if called twice"() { + def "registerAggregatedUploadArtifactTask should modify the existing itself if called twice"() { given: dslBasedUploadApkTaskFactory = new DSLBasedUploadApkTaskFactory(project) @@ -93,7 +93,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { } == ["task1", "task2", "task3", "task4"] } - def "registerUploadApkTask should add a UploadApkTask"() { + def "registerUploadArtifactTask should add a UploadApkTask"() { given: NamedDomainObjectContainer deployments = project.container(NamedDeployment) deployments.create("dep1") @@ -114,7 +114,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { task.group == DeployGateTaskFactory.GROUP_NAME } - def "registerUploadApkTask should not override itself if already exist"() { + def "registerUploadArtifactTask should not override itself if already exist"() { given: NamedDomainObjectContainer deployments = project.container(NamedDeployment) deployments.create("dep1") @@ -137,7 +137,7 @@ class DSLBasedUploadApkTaskFactorySpec extends Specification { !(task instanceof UploadApkTask) } - def "registerUploadApkTask should not allow adding names which do not exist in build.gradle"() { + def "registerUploadArtifactTask should not allow adding names which do not exist in build.gradle"() { given: NamedDomainObjectContainer deployments = project.container(NamedDeployment) deployments.create("dep1") From 55ef7b5db3599eae56fb1ed7047555e5d1fdf1cc Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 03:46:26 +0900 Subject: [PATCH 06/10] Renamed aab upload task name --- .../plugins/tasks/factory/DeployGateTaskFactory.groovy | 6 +++--- .../tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy | 8 ++++---- .../tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy index 9728d17c..b60ac625 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy @@ -8,18 +8,18 @@ import javax.annotation.Nonnull abstract class DeployGateTaskFactory { public static final String GROUP_NAME = 'DeployGate' - public static String PREFIX_TASK_NAME = "uploadDeployGate" public static String AGGREGATION_APK_TASK_NAME = "uploadDeployGate" public static String AGGREGATION_AAB_TASK_NAME = "uploadDeployGateAab" + // if product flavor is `aab`, then this does not work ;( @Nonnull static String uploadApkTaskName(@Nonnull String variantName) { - return "$PREFIX_TASK_NAME${variantName.capitalize()}" + return "$AGGREGATION_APK_TASK_NAME${variantName.capitalize()}" } @Nonnull static String uploadAabTaskName(@Nonnull String variantName) { - return "$PREFIX_TASK_NAME${variantName.capitalize()}Aab" + return "$AGGREGATION_AAB_TASK_NAME${variantName.capitalize()}" } @Nonnull diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy index b563aa07..ce3485de 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactorySpec.groovy @@ -48,7 +48,7 @@ class AGPBasedUploadAabTaskFactorySpec extends Specification { } @ConfineMetaClassChanges([PackageAppTaskCompat]) - def "registerUploadArtifactTask should add a UploadApkTask"() { + def "registerUploadArtifactTask should add a UploadAabTask"() { setup: def variantName = "dep1" def variant = Mock(IApplicationVariant) @@ -67,7 +67,7 @@ class AGPBasedUploadAabTaskFactorySpec extends Specification { agpBasedUploadAabTaskFactory.registerUploadArtifactTask(variant) and: - def task = project.tasks.findByName("uploadDeployGateDep1Aab") + def task = project.tasks.findByName("uploadDeployGateAabDep1") then: task @@ -94,7 +94,7 @@ class AGPBasedUploadAabTaskFactorySpec extends Specification { agpBasedUploadAabTaskFactory.registerUploadArtifactTask(variant) and: - def firstTask = project.tasks.findByName("uploadDeployGateDep1Aab") + def firstTask = project.tasks.findByName("uploadDeployGateAabDep1") then: firstTask @@ -103,7 +103,7 @@ class AGPBasedUploadAabTaskFactorySpec extends Specification { agpBasedUploadAabTaskFactory.registerUploadArtifactTask(variant) and: - def secondTask = project.tasks.findByName("uploadDeployGateDep1Aab") + def secondTask = project.tasks.findByName("uploadDeployGateAabDep1") then: firstTask == secondTask diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy index ed26ca85..593c8f01 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactorySpec.groovy @@ -106,7 +106,7 @@ class DSLBasedUploadAabTaskFactorySpec extends Specification { dslBasedUploadAabTaskFactory.registerUploadArtifactTask("dep1") and: - def task = project.tasks.findByName("uploadDeployGateDep1Aab") + def task = project.tasks.findByName("uploadDeployGateAabDep1") then: task @@ -124,13 +124,13 @@ class DSLBasedUploadAabTaskFactorySpec extends Specification { dslBasedUploadAabTaskFactory = new DSLBasedUploadAabTaskFactory(project) and: - project.tasks.create("uploadDeployGateDep1Aab") + project.tasks.create("uploadDeployGateAabDep1") when: dslBasedUploadAabTaskFactory.registerUploadArtifactTask("dep1") and: - def task = project.tasks.findByName("uploadDeployGateDep1Aab") + def task = project.tasks.findByName("uploadDeployGateAabDep1") then: task From 264f25a002c13d5aea7777f39f9b4a726d098c96 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 03:55:50 +0900 Subject: [PATCH 07/10] Moved lazy package app into artifact task --- .../gradle/plugins/tasks/UploadAabTask.groovy | 10 ---------- .../gradle/plugins/tasks/UploadArtifactTask.groovy | 11 +++++++++++ .../tasks/factory/AGPBasedUploadApkTaskFactory.groovy | 8 ++------ .../gradle/plugins/tasks/UploadApkTaskSpec.groovy | 1 + .../plugins/tasks/UploadArtifactTaskSpec.groovy | 1 + 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy index 4351c48b..f067f075 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadAabTask.groovy @@ -17,18 +17,8 @@ class UploadAabTask extends UploadArtifactTask { ) } - private def lazyPackageApplication - - void setLazyPackageApplication(lazyPackageApplication) { - this.lazyPackageApplication = lazyPackageApplication - } - @TaskAction void doUpload() { - // evaluate immediately - assert lazyPackageApplication != null - lazyPackageApplication.get() - super.doUpload() } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy index 72cb53ce..85d7b149 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy @@ -67,6 +67,8 @@ abstract class UploadArtifactTask extends DefaultTask { Configuration configuration + private def lazyPackageApplication + void setVariantName(@Nonnull String variantName) { if (this.variantName && this.variantName != variantName) { throw new IllegalStateException("different variant name cannot be assigned") @@ -92,8 +94,17 @@ abstract class UploadArtifactTask extends DefaultTask { this.configuration = configuration } + void setLazyPackageApplication(lazyPackageApplication) { + this.lazyPackageApplication = lazyPackageApplication + } + // Add TaskAction annotation in overrider classes void doUpload() { + assert lazyPackageApplication != null + // evaluate surely + // ref: https://github.com/DeployGate/gradle-deploygate-plugin/issues/86 + lazyPackageApplication.get() + runArtifactSpecificVerification() uploadArtifactToServer() } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy index a7f7d7fe..27979cfb 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy @@ -32,6 +32,8 @@ class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo dgTask.dependsOn([androidAssembleTaskName(variantName), *dependsOn].flatten()) } + dgTask.lazyPackageApplication = applicationVariant.lazyPackageApplication() + applicationVariant.lazyPackageApplication().configure { packageAppTask -> def apkInfo = PackageAppTaskCompat.getApkInfo(packageAppTask) def configuration = UploadApkTask.createConfiguration(deployment, apkInfo) @@ -39,12 +41,6 @@ class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo dgTask.configuration = configuration dgTask.applyTaskProfile() } - - if (deployment?.skipAssemble) { - // a package application provider may not be evaluated in some cases. - // ref: https://github.com/DeployGate/gradle-deploygate-plugin/issues/86 - applicationVariant.lazyPackageApplication().get() - } } @Override diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy index eabdfd7e..96091bb3 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy @@ -31,6 +31,7 @@ class UploadApkTaskSpec extends Specification { and: def task = project.tasks.create("UploadApkTask", UploadApkTask) task.variantName = "dep1" + task.lazyPackageApplication = Optional.of("DUMMY") when: "signing is required" task.configuration = new UploadArtifactTask.Configuration(isSigningReady: false) diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy index 823ebd4f..4922aa46 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy @@ -162,6 +162,7 @@ class UploadArtifactTaskSpec extends Specification { and: def task = project.tasks.create("UploadArtifactTaskStub", UploadArtifactTaskStub) task.variantName = "dep1" + task.lazyPackageApplication = Optional.of("DUMMY") when: "apkFile is required" task.configuration = new UploadArtifactTask.Configuration(artifactFile: null, isSigningReady: true) From 9c149ad0123e55845aa05bebd9b4fc9aa5105d44 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 04:07:48 +0900 Subject: [PATCH 08/10] Tweaked --- .../gradle/plugins/artifacts/PackageAppTaskCompat.groovy | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy index f709184d..cfb09cb8 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy @@ -33,10 +33,8 @@ class PackageAppTaskCompat { // outputScope is retrieved by the reflection Collection apkNames = packageAppTask.outputScope.apkDatas*.outputFileName File outputDir = packageAppTask.outputDirectory - File apkFile = new File(outputDir, (String) apkNames[0]) - // FIXME toooooooooooo dirty hack! - def aabFile = new File(apkFile.getPath().replaceAll("\\.apk\$", ".aab").reverse().replaceAll("/apk/".reverse(), "/bundle/".reverse()).reverse()) + File aabFile = new File(outputDir.getPath().replaceFirst("/apk/", "/bundle/"), ((String) apkNames[0]).replaceFirst("\\.apk\$", ".aab")) return new DirectAabInfo( variantName, From f08e67d9efc0e3dae7a75d410b04b2d9c5117279 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 15:07:42 +0900 Subject: [PATCH 09/10] Estimate aab path --- .../internal/agp/AndroidGradlePlugin.groovy | 1 + .../plugins/tasks/UploadArtifactTask.groovy | 12 +- .../AGPBasedUploadAabTaskFactory.groovy | 12 +- .../DSLBasedUploadAabTaskFactory.groovy | 2 +- .../DSLBasedUploadApkTaskFactory.groovy | 2 +- .../factory/DeployGateTaskFactory.groovy | 9 +- .../plugins/AcceptanceTestBaseSpec.groovy | 254 +++++++++++++++++- .../gradle/plugins/VersionString.groovy | 81 ++++++ .../plugins/tasks/UploadApkTaskSpec.groovy | 1 - .../tasks/UploadArtifactTaskSpec.groovy | 1 - 10 files changed, 350 insertions(+), 25 deletions(-) create mode 100644 src/test/acceptance/com/deploygate/gradle/plugins/VersionString.groovy diff --git a/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy b/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy index 24ceaf32..751501c4 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy @@ -1,5 +1,6 @@ package com.deploygate.gradle.plugins.internal.agp + import com.deploygate.gradle.plugins.internal.VersionString import org.gradle.api.Plugin import org.gradle.api.Project diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy index 85d7b149..6e707907 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTask.groovy @@ -100,10 +100,14 @@ abstract class UploadArtifactTask extends DefaultTask { // Add TaskAction annotation in overrider classes void doUpload() { - assert lazyPackageApplication != null - // evaluate surely - // ref: https://github.com/DeployGate/gradle-deploygate-plugin/issues/86 - lazyPackageApplication.get() + if (lazyPackageApplication) { + // evaluate surely + // ref: https://github.com/DeployGate/gradle-deploygate-plugin/issues/86 + lazyPackageApplication.get() + logger.debug("$variantName's package application task has been evaluated") + } else { + logger.debug("$variantName's package application task is not found") + } runArtifactSpecificVerification() uploadArtifactToServer() diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy index d92ba2ff..1b3be668 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy @@ -1,5 +1,6 @@ package com.deploygate.gradle.plugins.tasks.factory +import com.deploygate.gradle.plugins.artifacts.DirectAabInfo import com.deploygate.gradle.plugins.artifacts.PackageAppTaskCompat import com.deploygate.gradle.plugins.dsl.NamedDeployment import com.deploygate.gradle.plugins.internal.agp.IApplicationVariant @@ -34,13 +35,12 @@ class AGPBasedUploadAabTaskFactory extends DeployGateTaskFactory implements Uplo dgTask.lazyPackageApplication = applicationVariant.lazyPackageApplication() - applicationVariant.lazyPackageApplication().configure { packageAppTask -> - def aabInfo = PackageAppTaskCompat.getAabInfo(packageAppTask) - def configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + // cannot get an aab name from package application + def baseName = project.properties["archivesBaseName"] as String + def aabInfo = new DirectAabInfo(variantName, new File(project.buildDir, "outputs/bundle/${variantName}/${baseName}.aab")) - dgTask.configuration = configuration - dgTask.applyTaskProfile() - } + dgTask.configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + dgTask.applyTaskProfile() } @Override diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy index 9b385aef..a9fc3c8e 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadAabTaskFactory.groovy @@ -59,7 +59,7 @@ class DSLBasedUploadAabTaskFactory extends DeployGateTaskFactory implements Uplo return } - taskFactory.registerOrFindBy(AGGREGATION_AAB_TASK_NAME, DefaultTask).configure { dgTask -> + taskFactory.registerOrFindBy(SUFFIX_AAB_TASK_NAME, DefaultTask).configure { dgTask -> dgTask.group = GROUP_NAME dgTask.dependsOn(dependsOn.flatten()) } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy index 1bc960ca..e896d13b 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DSLBasedUploadApkTaskFactory.groovy @@ -57,7 +57,7 @@ class DSLBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo return } - taskFactory.registerOrFindBy(AGGREGATION_APK_TASK_NAME, DefaultTask).configure { dgTask -> + taskFactory.registerOrFindBy(SUFFIX_APK_TASK_NAME, DefaultTask).configure { dgTask -> dgTask.group = GROUP_NAME dgTask.dependsOn(dependsOn.flatten()) } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy index b60ac625..3d300ab6 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/DeployGateTaskFactory.groovy @@ -8,18 +8,17 @@ import javax.annotation.Nonnull abstract class DeployGateTaskFactory { public static final String GROUP_NAME = 'DeployGate' - public static String AGGREGATION_APK_TASK_NAME = "uploadDeployGate" - public static String AGGREGATION_AAB_TASK_NAME = "uploadDeployGateAab" - // if product flavor is `aab`, then this does not work ;( + public static String SUFFIX_APK_TASK_NAME = "uploadDeployGate" + public static String SUFFIX_AAB_TASK_NAME = "uploadDeployGateAab" @Nonnull static String uploadApkTaskName(@Nonnull String variantName) { - return "$AGGREGATION_APK_TASK_NAME${variantName.capitalize()}" + return "$SUFFIX_APK_TASK_NAME${variantName.capitalize()}" } @Nonnull static String uploadAabTaskName(@Nonnull String variantName) { - return "$AGGREGATION_AAB_TASK_NAME${variantName.capitalize()}" + return "$SUFFIX_AAB_TASK_NAME${variantName.capitalize()}" } @Nonnull diff --git a/src/test/acceptance/com/deploygate/gradle/plugins/AcceptanceTestBaseSpec.groovy b/src/test/acceptance/com/deploygate/gradle/plugins/AcceptanceTestBaseSpec.groovy index f79f33f2..2f2f293e 100644 --- a/src/test/acceptance/com/deploygate/gradle/plugins/AcceptanceTestBaseSpec.groovy +++ b/src/test/acceptance/com/deploygate/gradle/plugins/AcceptanceTestBaseSpec.groovy @@ -45,6 +45,15 @@ abstract class AcceptanceTestBaseSpec extends Specification { abstract AGPEnv[] getTestTargetAGPEnvs() + AGPEnv[] getAppBundleTestTargetAGPEnvs() { + return testTargetAGPEnvs.findAll { isAppBundleSupport(it.agpVersion) } + } + + boolean isAppBundleSupport(String agpVersion) { + def version = VersionString.tryParse(agpVersion) + return version.major >= 4 || version.major == 3 && version.minor > 1 + } + def setup() { testAndroidProject = new TestAndroidProject(testProjectDir) testDeployGatePlugin = new TestDeployGatePlugin() @@ -90,6 +99,28 @@ abstract class AcceptanceTestBaseSpec extends Specification { runner.withArguments("existsTask", "-PtaskName=uploadDeployGateFlavor2Flavor4Release").build() runner.withArguments("existsTask", "-PtaskName=uploadDeployGateCustomApk").build() + if (isAppBundleSupport(agpVersion)) { + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor3Debug").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor3Debug").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor4Debug").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor4Debug").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor3Release").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor3Release").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor4Release").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor4Release").build() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabCustomApk").build() + } else { + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor3Debug").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor3Debug").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor4Debug").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor4Debug").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor3Release").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor3Release").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor1Flavor4Release").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabFlavor2Flavor4Release").buildAndFail() + runner.withArguments("existsTask", "-PtaskName=uploadDeployGateAabCustomApk").buildAndFail() + } + where: agpEnv << testTargetAGPEnvs agpVersion = agpEnv.agpVersion as String @@ -126,6 +157,12 @@ abstract class AcceptanceTestBaseSpec extends Specification { result.contains("uploadDeployGateFlavor1Flavor4Debug") result.contains("uploadDeployGateFlavor2Flavor4Debug") result.contains("uploadDeployGateCustomApk") + // regardless of aab support + !result.contains("uploadDeployGateAabFlavor1Flavor3Release") + !result.contains("uploadDeployGateAabFlavor2Flavor3Release") + !result.contains("uploadDeployGateAabFlavor1Flavor4Release") + !result.contains("uploadDeployGateAabFlavor2Flavor4Release") + !result.contains("uploadDeployGateAabCustomApk") where: agpEnv << testTargetAGPEnvs @@ -134,7 +171,7 @@ abstract class AcceptanceTestBaseSpec extends Specification { } @Unroll - def "flavor1Flavor3Debug #agpVersion"() { + def "flavor1Flavor3Debug apk #agpVersion"() { given: testAndroidProject.gradleProperties([ "agpVersion": agpVersion @@ -168,7 +205,41 @@ abstract class AcceptanceTestBaseSpec extends Specification { } @Unroll - def "flavor2Flavor3Debug #agpVersion"() { + def "flavor1Flavor3Debug aab #agpVersion"() { + given: + testAndroidProject.gradleProperties([ + "agpVersion": agpVersion + ]) + + def runner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("uploadDeployGateAabFlavor1Flavor3Debug" /*, "--stacktrace" */) + + and: + def buildResult = runner.build() + def result = wireMockRule.findRequestsMatching(postRequestedFor(urlPathEqualTo("/api/users/appOwner/apps")).build()) + def request = result.requests.first() + + expect: + buildResult.task(":uploadDeployGateAabFlavor1Flavor3Debug").outcome == TaskOutcome.SUCCESS + result.requests.size() == 1 + request.getPart("token").body.asString() == "api token" + request.getPart("file").body.present + missingPart(request, "message") + missingPart(request, "distribution_key") + missingPart(request, "release_note") + missingPart(request, "visibility") + + where: + agpEnv << appBundleTestTargetAGPEnvs + agpVersion = agpEnv.agpVersion as String + gradleVersion = agpEnv.gradleVersion as String + } + + @Unroll + def "flavor2Flavor3Debug apk #agpVersion"() { given: testAndroidProject.gradleProperties([ "agpVersion": agpVersion @@ -202,7 +273,41 @@ abstract class AcceptanceTestBaseSpec extends Specification { } @Unroll - def "flavor1Flavor4Debug #agpVersion"() { + def "flavor2Flavor3Debug aab #agpVersion"() { + given: + testAndroidProject.gradleProperties([ + "agpVersion": agpVersion + ]) + + def runner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("uploadDeployGateAabFlavor2Flavor3Debug" /*, "--stacktrace" */) + + and: + def buildResult = runner.build() + def result = wireMockRule.findRequestsMatching(postRequestedFor(urlPathEqualTo("/api/users/appOwner/apps")).build()) + def request = result.requests.first() + + expect: + buildResult.task(":uploadDeployGateAabFlavor2Flavor3Debug").outcome == TaskOutcome.SUCCESS + result.requests.size() == 1 + request.getPart("token").body.asString() == "api token" + request.getPart("file").body.present + request.getPart("message").body.asString() == "flavor2Flavor3Debug" + missingPart(request, "distribution_key") + missingPart(request, "release_note") + missingPart(request, "visibility") + + where: + agpEnv << appBundleTestTargetAGPEnvs + agpVersion = agpEnv.agpVersion as String + gradleVersion = agpEnv.gradleVersion as String + } + + @Unroll + def "flavor1Flavor4Debug apk #agpVersion"() { given: testAndroidProject.gradleProperties([ "agpVersion": agpVersion @@ -236,7 +341,41 @@ abstract class AcceptanceTestBaseSpec extends Specification { } @Unroll - def "flavor2Flavor4Debug should fail unless assembling #agpVersion"() { + def "flavor1Flavor4Debug aab #agpVersion"() { + given: + testAndroidProject.gradleProperties([ + "agpVersion": agpVersion + ]) + + def runner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("uploadDeployGateAabFlavor1Flavor4Debug" /*, "--stacktrace" */) + + and: + def buildResult = runner.build() + def result = wireMockRule.findRequestsMatching(postRequestedFor(urlPathEqualTo("/api/users/appOwner/apps")).build()) + def request = result.requests.first() + + expect: + buildResult.task(":uploadDeployGateAabFlavor1Flavor4Debug").outcome == TaskOutcome.SUCCESS + result.requests.size() == 1 + request.getPart("token").body.asString() == "api token" + request.getPart("file").body.present + request.getPart("message").body.asString() == "flavor1Flavor4Debug" + missingPart(request, "distribution_key") + missingPart(request, "release_note") + missingPart(request, "visibility") + + where: + agpEnv << appBundleTestTargetAGPEnvs + agpVersion = agpEnv.agpVersion as String + gradleVersion = agpEnv.gradleVersion as String + } + + @Unroll + def "flavor2Flavor4Debug apk should fail unless assembling #agpVersion"() { given: testAndroidProject.gradleProperties([ "agpVersion": agpVersion @@ -261,7 +400,32 @@ abstract class AcceptanceTestBaseSpec extends Specification { } @Unroll - def "flavor2Flavor4Debug require assembling #agpVersion"() { + def "flavor2Flavor4Debug aab should fail unless bundling #agpVersion"() { + given: + testAndroidProject.gradleProperties([ + "agpVersion": agpVersion + ]) + + def runner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("uploadDeployGateAabFlavor2Flavor4Debug" /*, "--stacktrace" */) + + and: + def buildResult = runner.buildAndFail() + + expect: + buildResult.task(":uploadDeployGateAabFlavor2Flavor4Debug").getOutcome() == TaskOutcome.FAILED + + where: + agpEnv << appBundleTestTargetAGPEnvs + agpVersion = agpEnv.agpVersion as String + gradleVersion = agpEnv.gradleVersion as String + } + + @Unroll + def "flavor2Flavor4Debug apk require assembling #agpVersion"() { given: testAndroidProject.gradleProperties([ "agpVersion": agpVersion @@ -305,7 +469,51 @@ abstract class AcceptanceTestBaseSpec extends Specification { } @Unroll - def "customApk #agpVersion"() { + def "flavor2Flavor4Debug aab require bundling #agpVersion"() { + given: + testAndroidProject.gradleProperties([ + "agpVersion": agpVersion + ]) + + def assembleRunner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("bundleFlavor2Flavor4Debug" /*, "--stacktrace" */) + + def uploadRunner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("uploadDeployGateAabFlavor2Flavor4Debug" /*, "--stacktrace" */) + + and: + def assembleBuildResult = assembleRunner.build() + + and: + def uploadBuildResult = uploadRunner.build() + def result = wireMockRule.findRequestsMatching(postRequestedFor(urlPathEqualTo("/api/users/appOwner/apps")).build()) + def request = result.requests.first() + + expect: + assembleBuildResult.task(":bundleFlavor2Flavor4Debug").outcome == TaskOutcome.SUCCESS + uploadBuildResult.task(":uploadDeployGateAabFlavor2Flavor4Debug").outcome == TaskOutcome.SUCCESS + result.requests.size() == 1 + request.getPart("token").body.asString() == "api token" + request.getPart("file").body.present + request.getPart("message").body.asString() == "flavor2Flavor4Debug" + missingPart(request, "distribution_key") + missingPart(request, "release_note") + missingPart(request, "visibility") + + where: + agpEnv << appBundleTestTargetAGPEnvs + agpVersion = agpEnv.agpVersion as String + gradleVersion = agpEnv.gradleVersion as String + } + + @Unroll + def "customApk apk #agpVersion"() { given: testAndroidProject.gradleProperties([ "agpVersion": agpVersion @@ -338,6 +546,40 @@ abstract class AcceptanceTestBaseSpec extends Specification { gradleVersion = agpEnv.gradleVersion as String } + @Unroll + def "customApk aab #agpVersion"() { + given: + testAndroidProject.gradleProperties([ + "agpVersion": agpVersion + ]) + + def runner = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath(testDeployGatePlugin.loadPluginClasspath()) + .withGradleVersion(gradleVersion) + .withArguments("uploadDeployGateAabCustomApk" /*, "--stacktrace" */) + + and: + def buildResult = runner.build() + def result = wireMockRule.findRequestsMatching(postRequestedFor(urlPathEqualTo("/api/users/appOwner/apps")).build()) + def request = result.requests.first() + + expect: + buildResult.task(":uploadDeployGateAabCustomApk").outcome == TaskOutcome.SUCCESS + result.requests.size() == 1 + request.getPart("token").body.asString() == "api token" + request.getPart("file").body.present + request.getPart("message").body.asString() == "custom message" + request.getPart("distribution_key").body.asString() == "custom distributionKey" + request.getPart("release_note").body.asString() == "custom releaseNote" + request.getPart("visibility").body.asString() == "custom visibility" + + where: + agpEnv << appBundleTestTargetAGPEnvs + agpVersion = agpEnv.agpVersion as String + gradleVersion = agpEnv.gradleVersion as String + } + private static boolean missingPart(LoggedRequest request, String name) { return request.parts.isEmpty() || !request.parts.any { it.name == name } } diff --git a/src/test/acceptance/com/deploygate/gradle/plugins/VersionString.groovy b/src/test/acceptance/com/deploygate/gradle/plugins/VersionString.groovy new file mode 100644 index 00000000..c5599bf7 --- /dev/null +++ b/src/test/acceptance/com/deploygate/gradle/plugins/VersionString.groovy @@ -0,0 +1,81 @@ +package com.deploygate.gradle.plugins + +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import javax.annotation.Nullable +import java.util.regex.Pattern + +class VersionString { + private static final Logger LOGGER = LoggerFactory.getLogger(this.getClass()) + private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)(?:\\.(\\d+))?\$") + + @Nullable + static VersionString tryParse(@Nullable String version) { + if (!version) { + return null + } + + LOGGER.info(version) + + def versions = version.split("-", 2) + + try { + def matcher = VERSION_PATTERN.matcher(versions[0]) + + if (!matcher.find() || matcher.groupCount() < 2) { + return null + } + + def major = matcher.group(1).toInteger() + def minor = matcher.group(2).toInteger() + def patch = 0 + + if (matcher.groupCount() >= 3) { + patch = matcher.group(3)?.toInteger() ?: 0 + } + + String addition = null + + if (versions.length == 2) { + addition = versions[1] + } + + new VersionString(major, minor, patch, addition) + } catch (NumberFormatException ignore) { + return null + } + } + + final int major + final int minor + final int patch + + @Nullable + final String addition + + VersionString(int major, int minor, int patch, @Nullable String addition) { + this.major = major + this.minor = minor + this.patch = patch + this.addition = addition + } + + @Override + String toString() { + def builder = new StringBuffer() + + builder.append(major) + builder.append(".") + builder.append(minor) + builder.append(".") + builder.append(patch) + + if (addition != null) { + builder.append("-") + builder.append(addition) + } + + return builder.toString() + } +} diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy index 96091bb3..eabdfd7e 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadApkTaskSpec.groovy @@ -31,7 +31,6 @@ class UploadApkTaskSpec extends Specification { and: def task = project.tasks.create("UploadApkTask", UploadApkTask) task.variantName = "dep1" - task.lazyPackageApplication = Optional.of("DUMMY") when: "signing is required" task.configuration = new UploadArtifactTask.Configuration(isSigningReady: false) diff --git a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy index 4922aa46..823ebd4f 100644 --- a/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy +++ b/src/test/groovy/com/deploygate/gradle/plugins/tasks/UploadArtifactTaskSpec.groovy @@ -162,7 +162,6 @@ class UploadArtifactTaskSpec extends Specification { and: def task = project.tasks.create("UploadArtifactTaskStub", UploadArtifactTaskStub) task.variantName = "dep1" - task.lazyPackageApplication = Optional.of("DUMMY") when: "apkFile is required" task.configuration = new UploadArtifactTask.Configuration(artifactFile: null, isSigningReady: true) From 1013849593d1ae6be2d8e728a1637143cf1b77c7 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Wed, 18 Dec 2019 15:47:32 +0900 Subject: [PATCH 10/10] Fixed apkInfo/aabInfo from package application task --- .../artifacts/PackageAppTaskCompat.groovy | 25 +++++++++++-------- .../internal/agp/AndroidGradlePlugin.groovy | 4 +++ .../AGPBasedUploadAabTaskFactory.groovy | 12 ++++----- .../AGPBasedUploadApkTaskFactory.groovy | 2 +- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy index cfb09cb8..932a1e14 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/artifacts/PackageAppTaskCompat.groovy @@ -3,6 +3,7 @@ package com.deploygate.gradle.plugins.artifacts import com.deploygate.gradle.plugins.internal.agp.AndroidGradlePlugin import groovy.transform.PackageScope +import org.gradle.api.Project import javax.annotation.Nonnull @@ -11,8 +12,7 @@ class PackageAppTaskCompat { } @Nonnull - static ApkInfo getApkInfo(@Nonnull /* PackageApplication */ packageAppTask) { - String variantName = packageAppTask.name + static ApkInfo getApkInfo(@Nonnull /* PackageApplication */ packageAppTask, @Nonnull String variantName) { // outputScope is retrieved by the reflection Collection apkNames = packageAppTask.outputScope.apkDatas*.outputFileName File outputDir = packageAppTask.outputDirectory @@ -28,17 +28,22 @@ class PackageAppTaskCompat { } @Nonnull - static AabInfo getAabInfo(@Nonnull /* PackageApplication */ packageAppTask) { - String variantName = packageAppTask.name - // outputScope is retrieved by the reflection - Collection apkNames = packageAppTask.outputScope.apkDatas*.outputFileName - File outputDir = packageAppTask.outputDirectory - // FIXME toooooooooooo dirty hack! - File aabFile = new File(outputDir.getPath().replaceFirst("/apk/", "/bundle/"), ((String) apkNames[0]).replaceFirst("\\.apk\$", ".aab")) + static AabInfo getAabInfo(@Nonnull /* PackageApplication */ packageAppTask, @Nonnull String variantName, @Nonnull Project project) { + final String aabName + + if (AndroidGradlePlugin.isAppBundleArchiveNameChanged()) { + // outputScope is retrieved by the reflection + Collection apkNames = packageAppTask.outputScope.apkDatas*.outputFileName + aabName = ((String) apkNames[0]).replaceFirst("\\.apk\$", ".aab") + } else { + aabName = "${project.properties["archivesBaseName"] as String}.aab" + } + + def outputDir = new File(project.buildDir, "outputs/bundle/${variantName}") return new DirectAabInfo( variantName, - aabFile, + new File(outputDir, aabName), ) } diff --git a/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy b/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy index 751501c4..1d7eeb48 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/internal/agp/AndroidGradlePlugin.groovy @@ -57,6 +57,10 @@ class AndroidGradlePlugin { return getVersion().major >= 4 || getVersion().major == 3 && getVersion().minor > 2 } + static boolean isAppBundleArchiveNameChanged() { + return getVersion().major >= 4 || getVersion().major == 3 && getVersion().minor >= 5 + } + @Nonnull static String androidAssembleTaskName(@Nonnull String variantName) { return "assemble${variantName.capitalize()}" diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy index 1b3be668..102987f8 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadAabTaskFactory.groovy @@ -1,6 +1,6 @@ package com.deploygate.gradle.plugins.tasks.factory -import com.deploygate.gradle.plugins.artifacts.DirectAabInfo + import com.deploygate.gradle.plugins.artifacts.PackageAppTaskCompat import com.deploygate.gradle.plugins.dsl.NamedDeployment import com.deploygate.gradle.plugins.internal.agp.IApplicationVariant @@ -35,12 +35,12 @@ class AGPBasedUploadAabTaskFactory extends DeployGateTaskFactory implements Uplo dgTask.lazyPackageApplication = applicationVariant.lazyPackageApplication() - // cannot get an aab name from package application - def baseName = project.properties["archivesBaseName"] as String - def aabInfo = new DirectAabInfo(variantName, new File(project.buildDir, "outputs/bundle/${variantName}/${baseName}.aab")) + applicationVariant.lazyPackageApplication().configure { packageAppTask -> + def aabInfo = PackageAppTaskCompat.getAabInfo(packageAppTask, variantName, project) - dgTask.configuration = UploadAabTask.createConfiguration(deployment, aabInfo) - dgTask.applyTaskProfile() + dgTask.configuration = UploadAabTask.createConfiguration(deployment, aabInfo) + dgTask.applyTaskProfile() + } } @Override diff --git a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy index 27979cfb..a7bdf30c 100644 --- a/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy +++ b/src/main/groovy/com/deploygate/gradle/plugins/tasks/factory/AGPBasedUploadApkTaskFactory.groovy @@ -35,7 +35,7 @@ class AGPBasedUploadApkTaskFactory extends DeployGateTaskFactory implements Uplo dgTask.lazyPackageApplication = applicationVariant.lazyPackageApplication() applicationVariant.lazyPackageApplication().configure { packageAppTask -> - def apkInfo = PackageAppTaskCompat.getApkInfo(packageAppTask) + def apkInfo = PackageAppTaskCompat.getApkInfo(packageAppTask, variantName) def configuration = UploadApkTask.createConfiguration(deployment, apkInfo) dgTask.configuration = configuration