Skip to content

Instantly share code, notes, and snippets.

@brettwold
Last active July 21, 2021 02:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brettwold/7a60de32dc23697d64c1 to your computer and use it in GitHub Desktop.
Save brettwold/7a60de32dc23697d64c1 to your computer and use it in GitHub Desktop.
Upload APK file S3 bucket

Publish Android APKs to S3

Usage

Setup your S3 variables. Highly recommend that the access key and id are referred to as environment variables then they don't end up in your source repo. The snippet below sets up the variables for all projects in your build but you can do it on an individual project basis as well if you prefer.

allprojects {

    project.ext.AWS_S3_BUCKET = "my.bucket"
    project.ext.AWS_S3_KEY_SECRET = "${aws_accesskey}"
    project.ext.AWS_S3_KEY_ID = "${aws_accessid}"
    project.ext.AWS_S3_APK_TARGET_FOLDER = "apks"
}

In the gradle script for each application you want to upload simply include the s3-upload script

apply from: 's3-upload.gradle'

You should then find you get additional task(s) for your application in the form

publish${flavor}ApkToS3

This script makes use of CURL so you need to make sure it is installed on the machine where you run the task.

import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import java.text.SimpleDateFormat
android.applicationVariants.all { variant ->
task ("publish${variant.name.capitalize()}ApkToS3", dependsOn: "${variant.name}CustomPlatformSigning") << {
if (!project.hasProperty('AWS_S3_BUCKET') || !project.hasProperty('AWS_S3_KEY_ID') || !project.hasProperty('AWS_S3_KEY_SECRET')) {
throw new GradleException("Please set AWS_S3_BUCKET, AWS_S3_KEY_ID and AWS_S3_KEY_SECRET properties.")
}
def bucket = project.AWS_S3_BUCKET
def keyId = project.AWS_S3_KEY_ID
def keySecret = project.AWS_S3_KEY_SECRET
def prefix = project.hasProperty('AWS_S3_APK_TARGET_FOLDER') ? project.AWS_S3_APK_TARGET_FOLDER + "/" : ""
def targetPath = prefix + "${project.name}-${variant.versionName}.apk"
def apkFile = variant.outputs[0].outputFile
def contentType = "application/vnd.android.package-archive"
def date = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZZ").format(new Date())
def resource = "/${bucket}/${targetPath}"
def data = "PUT\n\n${contentType}\n${date}\n${resource}"
def signingKey = new SecretKeySpec(keySecret.getBytes(), "HmacSHA1");
def mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
def sig = mac.doFinal(data.getBytes()).encodeBase64()
exec {
executable "curl"
args '-k', '-X', 'PUT',
'-T', apkFile.getAbsolutePath(),
'-H', 'Date: ' + date,
'-H', 'Authorization: AWS ' + keyId + ':' + sig,
'-H', 'Content-Type: ' + contentType,
'-H', "Host: ${bucket}.s3.amazonaws.com",
'https://' + bucket + '.s3.amazonaws.com/' + targetPath
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment