This tutorial will outline how to upload released APKs to a remote server via SFTP/SSH, using gradle-ssh-plugin.
Add the plugin in your project build script:
buildscript {
dependencies {
classpath 'org.hidetake:gradle-ssh-plugin:2.8.0'
}
}
In your app build script, apply the plugin and configure the remote:
apply plugin: 'org.hidetake.ssh'
remotes {
ftp {
user = 'username'
host = 'my.hostname.com'
identity = file("${rootDir}/gradle_deploy.key")
}
}
ssh.settings {
knownHosts = allowAnyHosts
}
We will be using SSH key authentication via the gradle_deploy.key
key, in the root project directory. This has been generated via standard ssh-keygen
and authorized on the remote machine.
If you project has multiple flavors, you can specify a different remote destination directory for each flavor by using Gradle’s ExtraPropertiesExtension
:
productFlavors {
myflavor {
project.ext['uploadDestinationPath_myflavor'] = '/pub/client/android/myflavor/'
}
}
Next, we will create two tasks:
release<Flavor><BuildType>
, that will assemble the APK and copy it (and its Proguard mapping file, if any) to the releases/
directory in the project dirupload<Flavor><BuildType>
, that will upload the APK created via the release task above to the configured remoteAdd the following to your main module build script (app):
android.applicationVariants.all { variant ->
String today = new Date().format('yyyyMMdd_HHmmss')
def outBaseName = "${variant.flavorName}_${variant.versionName}_${variant.versionCode}_${today}"
def isRelease = variant.buildType.name == 'release'
def suffix = isRelease ? "" : variant.buildType.name.capitalize()
def destDir = "${rootDir}/releases"
def apkName = "${outBaseName}.apk"
def proguardMappingName = "${outBaseName}_mapping.txt"
def releaseBuildTask = tasks.create(name: "release" + variant.flavorName.capitalize(), type: Copy) {
group "release"
description "Packages a release APK for the flavor ${variant.flavorName} and copies the Proguard mapping file into releases/"
from(variant.outputs[0].outputFile.path) {
rename '.*', apkName
}
into destDir
if (variant.mappingFile != null) {
from(variant.mappingFile.path) {
rename '.*', proguardMappingName
}
into destDir
}
}
releaseBuildTask.dependsOn variant.assemble
def uploadTask = tasks.create(name: "upload" + variant.flavorName.capitalize() + suffix) {
group "release"
doLast {
ssh.run {
session(remotes.ftp) {
def src;
def dest = project.ext["uploadDestinationPath_${variant.flavorName}"]
if (variant.mappingFile != null) {
print "copying ${apkName}, ${proguardMappingName} to ${dest}"
src = files("${destDir}/${apkName}", "${destDir}/${proguardMappingName}")
} else {
print "copying ${apkName} to ${dest}"
src = "${destDir}/${apkName}"
}
put from: src, into: dest
}
}
}
}
uploadTask.dependsOn releaseBuildTask
}