Last active
January 17, 2019 11:49
-
-
Save tprochazka/457c7eebd044c0210dcc8ba49301cda9 to your computer and use it in GitHub Desktop.
Custom sign task implementation for Android Build Plugin compatible with build plugin 3.3.0 (with app bundle support)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.android.annotations.NonNull | |
import com.android.build.api.artifact.BuildableArtifact | |
import com.android.build.gradle.api.ApkVariant | |
import com.android.build.gradle.api.ApkVariantOutput | |
import com.google.common.io.Files | |
import org.gradle.api.Action | |
import org.gradle.api.DefaultTask | |
import org.gradle.api.GradleException | |
import org.gradle.api.Project | |
import org.gradle.api.tasks.InputFiles | |
import org.gradle.api.tasks.OutputFiles | |
import org.gradle.api.tasks.TaskAction | |
import java.security.SecureRandom | |
import java.util.concurrent.TimeUnit | |
class RemoteSignTask extends DefaultTask { | |
@InputFiles | |
BuildableArtifact inputFiles | |
Collection<String> originalInputNames = new HashSet<>() | |
@OutputFiles | |
Collection<File> outputFiles | |
ApkVariant applicationVariant | |
@TaskAction | |
void sign() { | |
inputFiles.files.each { File file -> | |
if (file.isDirectory()) { | |
applicationVariant.outputs.each { ApkVariantOutput output -> | |
File artifact = new File(file, output.outputFileName) | |
localFileSign(artifact, artifact) | |
outputFiles.add(artifact) | |
} | |
} else { | |
localFileSign(file, renameToSignedName(file)) | |
} | |
} | |
} | |
void localFileSign(File inputFile, File outputFile) { | |
// custom remote sign implementation. | |
} | |
static File renameToSignedName(File file) { | |
new File(file.parent, renameToSignedName(file.name)) | |
} | |
static String renameToSignedName(String fileName) { | |
return fileName.replaceFirst("[,-]unsigned", "") | |
} | |
/** | |
* Class responsible for sign task configuration | |
*/ | |
static class ConfigAction implements Action<RemoteSignTask> { | |
private final BuildableArtifact artifact | |
private final ApkVariant variant | |
ConfigAction(ApkVariant variant, BuildableArtifact artifact) { | |
this.variant = variant | |
this.artifact = artifact | |
} | |
@Override | |
@TaskAction | |
void execute(@NonNull RemoteSignTask signTask) { | |
signTask.inputFiles = artifact | |
signTask.applicationVariant = variant | |
signTask.outputFiles = new HashSet<>() | |
variant.outputs.all { ApkVariantOutput output -> | |
signTask.originalInputNames.add(output.outputFileName) | |
// hack to keep proper final name also when assemble task will be skipped | |
output.outputFileName = renameToSignedName(output.outputFileName) | |
} | |
variant.outputsAreSigned = true | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.android.build.gradle.api.ApplicationVariant | |
import com.android.build.gradle.api.BaseVariant | |
import com.android.build.gradle.internal.scope.InternalArtifactType | |
import com.android.builder.model.ProductFlavor | |
import org.gradle.api.Project | |
public class SignConfigurator { | |
/** | |
* Entry point to setup remote sign. | |
**/ | |
static void configureReleaseBuildSign(Project project) { | |
if (!RemoteSignTask.checkConfig(project)) { | |
project.getLogger().warn "Remote sign is not possible" | |
return | |
} | |
project.android.applicationVariants.whenObjectAdded { ApplicationVariant variant -> | |
if (!isReleaseBuildType(variant)) { | |
return | |
} | |
// Regular APK signing | |
def apk = variant.getFinalArtifact(InternalArtifactType.APK) | |
def signTask = project.tasks.register( | |
"remoteSign" + variant.name.capitalize() + "Apk", RemoteSignTask, | |
new RemoteSignTask.ConfigAction(variant, apk)) | |
variant.assembleProvider.configure { | |
dependsOn(signTask) | |
} | |
// App bundle signing | |
def bundle = variant.getFinalArtifact(InternalArtifactType.BUNDLE) | |
def bundleSignTask = project.tasks.register( | |
"remoteSign" + variant.name.capitalize() + "Bundle", RemoteSignTask, | |
new RemoteSignTask.ConfigAction(variant, bundle)) | |
variant.getVariantData().getTaskContainer().bundleTask.configure { | |
it.dependsOn(bundleSignTask) | |
} | |
if (variant.testVariant != null ) { | |
// Test APK signing | |
def testApk = variant.testVariant.getFinalArtifact(InternalArtifactType.APK) | |
def testSignTask = project.tasks.register( | |
"remoteSign" + variant.name.capitalize() + "AndroidTest", RemoteSignTask, | |
new RemoteSignTask.ConfigAction(variant.testVariant, testApk)) | |
variant.testVariant.assembleProvider.configure { | |
dependsOn(testSignTask) | |
} | |
variant.testVariant.connectedInstrumentTestProvider.configure { | |
dependsOn(testSignTask) | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment