diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 02afde7..65085f0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -42,10 +42,10 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: v${{ steps.get_version.outputs.version }} - release_name: Release v${{ steps.get_version.outputs.version }} + tag_name: ${{ steps.get_version.outputs.version }} + release_name: ${{ steps.get_version.outputs.version }} body: | - Automated release v${{ steps.get_version.outputs.version }} + Automated release ${{ steps.get_version.outputs.version }} Published to: - Maven Central Portal diff --git a/README.md b/README.md index d63eb57..3781124 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ buildscript { dependencies { ... - classpath 'com.appswithlove.updraft:updraft:2.2.8' + classpath 'com.appswithlove.updraft:updraft:2.2.9' } } ``` @@ -32,7 +32,7 @@ or ```kotlin plugins { - id("com.appswithlove.updraft") version "2.2.8" + id("com.appswithlove.updraft") version "2.2.9" } ``` @@ -114,7 +114,7 @@ buildscript { ... } dependencies { - classpath 'com.appswithlove.updraft:updraft:2.2.8' + classpath 'com.appswithlove.updraft:updraft:2.2.9' ... } } diff --git a/gradle.properties b/gradle.properties index 5c3a5de..b1a8456 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ GROUP=com.appswithlove.updraft POM_ARTIFACT_ID=updraft -VERSION_NAME=2.2.8 +VERSION_NAME=2.2.9 POM_NAME=updraft-plugin-android POM_DESCRIPTION=This is a gradle Android plugin for automated uploads to Updraft diff --git a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy index 87dc590..de8c6fb 100644 --- a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy +++ b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy @@ -1,163 +1,117 @@ package com.appswithlove.updraft -import groovy.json.JsonSlurperClassic import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.process.ExecOperations -import javax.inject.Inject /** * A plugin for uploading apk files to updraft.*/ class UpdraftPlugin implements Plugin { - private final ExecOperations execOps - - @Inject - UpdraftPlugin(ExecOperations execOperations) { - this.execOps = execOperations - } - @Override void apply(Project project) { project.extensions.create('updraft', UpdraftExtension.class) project.android.applicationVariants.all { variant -> - def plugin = this String variantName = variant.name String variantNameCapitalized = variantName.capitalize() - String basePath = getProject().getProjectDir().getAbsolutePath() - String filename = variant.outputs[0].outputFile + String projectBasePath = getProject().getProjectDir().getAbsolutePath() + + def uploadUrlsProvider = project.providers.provider { project.updraft.urls } + def uploadUrls = uploadUrlsProvider.map { urlsMap -> + def urlsForVariant = urlsMap[variantNameCapitalized] + if (urlsForVariant == null) { + return [] + } + if (urlsForVariant instanceof String) { + return [urlsForVariant] + } + return urlsForVariant + } - def urls = project.updraft.urls[variantNameCapitalized] def gitBranchProvider = project.providers.of(GitBranchValueSource.class) {} def gitTagsProvider = project.providers.of(GitTagsValueSource.class) {} def gitCommitProvider = project.providers.of(GitCommitValueSource.class) {} def gitUrlProvider = project.providers.of(GitUrlValueSource.class) {} - String releaseNotes = getReleaseNotes(project, variant) - String whatsNew = createCurlParam(releaseNotes, "whats_new") + def releaseNotesProvider = project.providers.provider { getReleaseNotes(project, variant) } - // Registers a task for every available build variant / flavor - project.tasks.register("updraft${variantNameCapitalized}") { - // Declares that the project runs after the build, not before. - // If not stated, it will run at every gradle sync. - - String gitBranch = createCurlParam(gitBranchProvider.get(), "custom_branch") - String gitTags = createCurlParam(gitTagsProvider.get(), "custom_tags") - String gitCommit = createCurlParam(gitCommitProvider.get(), "custom_commit") - String gitUrl = createCurlParam(gitUrlProvider.get(), "custom_URL") - - doLast { - // APK - def apkFile = new File(filename) - String fileWithoutExt = apkFile.name.take(apkFile.name.lastIndexOf('.')) - - if (apkFile != null && !apkFile.exists()) { - def apkFolder = new File(apkFile.getParent()) - for (File currentFile in apkFolder.listFiles()) { - if (currentFile.getName().startsWith(fileWithoutExt)) { - apkFile = currentFile - } - } - } + def apkFileProvider = project.provider { + def buildDir = project.layout.buildDirectory.get().asFile + def apkDir = new File(buildDir, "outputs/apk/${variant.flavorName}/${variant.buildType.name}") - if (apkFile != null && !apkFile.exists()) { - throw new GradleException("Could not find a build artifact. (Make sure to run assemble${variantNameCapitalized} before)") + if (apkDir.exists() && apkDir.isDirectory()) { + def apkFiles = apkDir.listFiles({ file -> file.name.endsWith(".apk") } as FileFilter) + + if (apkFiles && apkFiles.size() > 1) { + throw new GradleException("More than one .apk file exists in ${apkDir}: ${apkFiles*.name}") } - plugin.upload(apkFile, urls, gitBranch, gitTags, gitCommit, gitUrl, whatsNew) + return apkFiles ? apkFiles[0] : null } + return null + } + def apkFile = apkFileProvider.flatMap { file -> + file ? project.layout.file(project.provider { file }) : project.objects.fileProperty() } - // Registers a task for every available build variant / flavor - project.tasks.register("updraftBundle${variantNameCapitalized}") { - // Declares that the project runs after the build, not before. - // If not stated, it will run at every gradle sync. - - String gitBranch = createCurlParam(gitBranchProvider.get(), "custom_branch") - String gitTags = createCurlParam(gitTagsProvider.get(), "custom_tags") - String gitCommit = createCurlParam(gitCommitProvider.get(), "custom_commit") - String gitUrl = createCurlParam(gitUrlProvider.get(), "custom_URL") - - doLast { - def apkFile = new File(filename) - String fileWithoutExt = apkFile.name.take(apkFile.name.lastIndexOf('.')) - - // AAB - def bundlePath = - "${basePath}/build/outputs/bundle/${variantName}/${fileWithoutExt}.aab" - - def aabFile = new File(bundlePath) - if (aabFile != null && !aabFile.exists()) { - def aabFolder = new File(aabFile.getParent()) - for (File currentFile in aabFolder.listFiles()) { - println("file $currentFile.path") - if (currentFile.getName().startsWith(fileWithoutExt)) { - aabFile = currentFile - } - } - } + def aabFileProvider = project.provider { + def buildDir = project.layout.buildDirectory.get().asFile + def bundleDir = new File(buildDir, "outputs/bundle/${variantName}") - if (aabFile != null && !aabFile.exists()) { - throw new GradleException("Could not find a build artifact. (Make sure to run bundle${variantNameCapitalized} before). \n We tried following location ${bundlePath}") + if (bundleDir.exists() && bundleDir.isDirectory()) { + def aabFiles = bundleDir.listFiles({ file -> file.name.endsWith(".aab") } as FileFilter) + + if (aabFiles && aabFiles.size() > 1) { + throw new GradleException("More than one .aab file exists in ${bundleDir}: ${aabFiles*.name}") } - plugin.upload(aabFile, urls, gitBranch, gitTags, gitCommit, gitUrl, whatsNew) + return aabFiles ? aabFiles[0] : null } + return null + } + def aabFile = aabFileProvider.flatMap { file -> + file ? project.layout.file(project.provider { file }) : project.objects.fileProperty() } - } - } - - private void upload(file, urls, gitBranch, gitTags, gitCommit, gitUrl, whatsNew) { - if (urls == null || urls.isEmpty()) { - throw new GradleException( - 'There was no url provided for this buildVariant. Please check for typos.' - ) - } - - if (urls instanceof String) { - println("--------------------------------------") - println("Url was not wrapped in array. Doing it for you. :)") - println("url --> [url]") - println("--------------------------------------") - urls = [urls] - } - for (String url in urls) { - //Build and execute of the curl command for Updraft upload - List curlArgs = [ - '-X', 'PUT', - '-F', "app=@${file}", - '-F', "build_type=Gradle", - gitBranch, - gitUrl, - gitTags, - gitCommit, - whatsNew, - url - ].findAll { it != '' } // Filter out empty strings - - new ByteArrayOutputStream().withStream { os -> - execOps.exec { - executable 'curl' - args curlArgs - standardOutput os + // Registers a task for every available build variant / flavor + project.tasks.register("updraft${variantNameCapitalized}", UpdraftTask) { + outputFile.set(apkFile) + isBundle.set(false) + basePath.set(projectBasePath) + currentVariantName.set(variantName) + urls.set(uploadUrls) + gitBranch.set(gitBranchProvider) + gitTags.set(gitTagsProvider) + gitCommit.set(gitCommitProvider) + gitUrl.set(gitUrlProvider) + releaseNotes.set(releaseNotesProvider) + + doFirst { + def outputFile = apkFile.getOrNull()?.asFile + if (outputFile == null || !outputFile.exists()) { + throw new GradleException("Could not find a build artifact. (Make sure to run assemble${variantNameCapitalized} task first)") + } } + } - def execResponse = new JsonSlurperClassic().parseText(os.toString()) - - if (execResponse instanceof HashMap && execResponse.size() > 0) { - if (execResponse.containsKey("success") && execResponse["success"] == "ok") { - def publicUrl = execResponse["public_link"] - ok(publicUrl) - } else if (execResponse.containsKey("detail") && execResponse["detail"] == "Not found.") { - throw new GradleException('Could not updraft to the given url. Please recheck that.') - } else { - throw new GradleException(os.toString()) + // Registers a task for every available build variant / flavor + project.tasks.register("updraftBundle${variantNameCapitalized}", UpdraftTask) { + outputFile.set(aabFile) + isBundle.set(true) + basePath.set(projectBasePath) + currentVariantName.set(variantName) + urls.set(uploadUrls) + gitBranch.set(gitBranchProvider) + gitTags.set(gitTagsProvider) + gitCommit.set(gitCommitProvider) + gitUrl.set(gitUrlProvider) + releaseNotes.set(releaseNotesProvider) + + doFirst { + def outputFile = aabFile.getOrNull()?.asFile + if (outputFile == null || !outputFile.exists()) { + throw new GradleException("Could not find a build artifact. (Make sure to run bundle${variantNameCapitalized} task first)") } - } else { - println(execResponse) - ok(null) } } } @@ -198,22 +152,4 @@ class UpdraftPlugin implements Plugin { } } } - - private static void ok(String publicUrl) { - println() - println("--------------------------------------") - println("Your App was successfully updrafted!") - if (publicUrl != null) { - println("Get it here -> $publicUrl") - } - println("--------------------------------------") - } - - private static String createCurlParam(String text, String name) { - if (text.isBlank() || text.isEmpty()) { - "" - } else { - "-F ${name}=${text} " - } - } } diff --git a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftTask.groovy b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftTask.groovy new file mode 100644 index 0000000..90052b7 --- /dev/null +++ b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftTask.groovy @@ -0,0 +1,125 @@ +package com.appswithlove.updraft + +import groovy.json.JsonSlurperClassic +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.Optional +import org.gradle.process.ExecOperations + +import javax.inject.Inject + +abstract class UpdraftTask extends DefaultTask { + + @Inject + abstract ExecOperations getExecOperations() + + @InputFile + @Optional + abstract RegularFileProperty getOutputFile() + + @Input + abstract Property getIsBundle() + + @Input + abstract Property getBasePath() + + @Input + abstract Property getCurrentVariantName() + + @Input + abstract ListProperty getUrls() + + @Input + abstract Property getGitBranch() + + @Input + abstract Property getGitTags() + + @Input + abstract Property getGitCommit() + + @Input + abstract Property getGitUrl() + + @Input + abstract Property getReleaseNotes() + + @TaskAction + void upload() { + def fileToUpload = outputFile.asFile.get() + + def uploadUrls = urls.get() + if (uploadUrls == null || uploadUrls.isEmpty()) { + throw new GradleException('There was no url provided for this buildVariant. Please check for typos.') + } + + if (uploadUrls instanceof String) { + println("--------------------------------------") + println("Url was not wrapped in array. Doing it for you. :)") + println("url --> [url]") + println("--------------------------------------") + uploadUrls = [uploadUrls] + } + + for (String url in uploadUrls) { + List curlArgs = [ + '-X', 'PUT', + '-F', "app=@${fileToUpload}", + '-F', "build_type=Gradle", + createCurlParam(gitBranch.get(), "custom_branch"), + createCurlParam(gitUrl.get(), "custom_URL"), + createCurlParam(gitTags.get(), "custom_tags"), + createCurlParam(gitCommit.get(), "custom_commit"), + createCurlParam(releaseNotes.get(), "whats_new"), + url + ].findAll { it != '' } + + new ByteArrayOutputStream().withStream { os -> + getExecOperations().exec { + executable 'curl' + args curlArgs + standardOutput os + } + + def execResponse = new JsonSlurperClassic().parseText(os.toString()) + + if (execResponse instanceof HashMap && execResponse.size() > 0) { + if (execResponse.containsKey("success") && execResponse["success"] == "ok") { + def publicUrl = execResponse["public_link"] + println() + println("--------------------------------------") + println("Your App was successfully updrafted!") + if (publicUrl != null) { + println("Get it here -> $publicUrl") + } + println("--------------------------------------") + } else if (execResponse.containsKey("detail") && execResponse["detail"] == "Not found.") { + throw new GradleException('Could not updraft to the given url. Please recheck that.') + } else { + throw new GradleException(os.toString()) + } + } else { + println(execResponse) + println() + println("--------------------------------------") + println("Your App was successfully updrafted!") + println("--------------------------------------") + } + } + } + } + + private static String createCurlParam(String text, String name) { + if (text == null || text.isBlank()) { + "" + } else { + "-F ${name}=${text}" + } + } +}