Re-add automation folder; support multiple arch builds
parent
e34f7e166d
commit
393829e2aa
@ -0,0 +1,86 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
FROM openjdk:8-alpine
|
||||
|
||||
MAINTAINER Colin Lee "colinlee@mozilla.com"
|
||||
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
#-- Configuration -----------------------------------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
ENV GLIBC_VERSION "2.27-r0"
|
||||
ENV ANDROID_BUILD_TOOLS "27.0.3"
|
||||
ENV ANDROID_SDK_VERSION "3859397"
|
||||
ENV ANDROID_PLATFORM_VERSION "27"
|
||||
ENV PROJECT_REPOSITORY "https://github.com/mozilla-mobile/fenix.git"
|
||||
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
#-- System ------------------------------------------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
RUN apk add --no-cache --virtual=.build-dependencies \
|
||||
bash \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
python \
|
||||
py-pip \
|
||||
unzip \
|
||||
wget
|
||||
|
||||
RUN pip install --upgrade pip
|
||||
|
||||
RUN pip install \
|
||||
taskcluster
|
||||
|
||||
RUN wget https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub -O /etc/apk/keys/sgerrand.rsa.pub \
|
||||
&& wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk -O /tmp/glibc.apk \
|
||||
&& wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-bin-${GLIBC_VERSION}.apk -O /tmp/glibc-bin.apk \
|
||||
&& apk add --no-cache /tmp/glibc.apk /tmp/glibc-bin.apk \
|
||||
&& rm -rf /tmp/* \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
#-- Android -----------------------------------------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
RUN mkdir -p /build/android-sdk
|
||||
WORKDIR /build
|
||||
|
||||
ENV ANDROID_HOME /build/android-sdk
|
||||
ENV ANDROID_SDK_HOME /build/android-sdk
|
||||
ENV PATH ${PATH}:${ANDROID_SDK_HOME}/tools:${ANDROID_SDK_HOME}/tools/bin:${ANDROID_SDK_HOME}/platform-tools:/opt/tools:${ANDROID_SDK_HOME}/build-tools/${ANDROID_BUILD_TOOLS}
|
||||
|
||||
RUN curl -L https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_VERSION}.zip > sdk.zip \
|
||||
&& unzip sdk.zip -d ${ANDROID_SDK_HOME} \
|
||||
&& rm sdk.zip
|
||||
|
||||
RUN mkdir -p /build/android-sdk/.android/
|
||||
RUN touch /build/android-sdk/.android/repositories.cfg
|
||||
|
||||
RUN yes | sdkmanager --licenses
|
||||
|
||||
RUN sdkmanager --verbose "platform-tools" \
|
||||
"platforms;android-${ANDROID_PLATFORM_VERSION}" \
|
||||
"build-tools;${ANDROID_BUILD_TOOLS}" \
|
||||
"extras;android;m2repository" \
|
||||
"extras;google;m2repository"
|
||||
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
#-- Project -----------------------------------------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
RUN git clone $PROJECT_REPOSITORY
|
||||
|
||||
WORKDIR /build/fenix
|
||||
|
||||
RUN ./gradlew --no-daemon assemble test lint detektCheck ktlint
|
||||
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
#-- Addendum ----------------------------------------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# Alphine Linux creates a bash profile that overrides our PATH again. Let's fix that.
|
||||
RUN echo "export PATH=$PATH" >> /etc/profile
|
@ -0,0 +1,44 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
// This gradle scripts generates a "unique" version code for our release versions.
|
||||
//
|
||||
// The result of the version code depends on the timezone. We assume that this script will only be used
|
||||
// for release versions and running on our build servers with a fixed timezone.
|
||||
//
|
||||
// The version code is composed like: yDDDHHmm
|
||||
// * y = Double digit year, with 18 subtracted: 2018 -> 18 -> 0
|
||||
// * DDD = Day of the year, pad with zeros if needed: September 6th -> 249
|
||||
// * HH = Hour in day (00-23)
|
||||
// * mm = Minute in hour
|
||||
//
|
||||
// For September 6th, 2018, 9:41 am this will generate the versionCode: 2490941 (0-249-09-41).
|
||||
//
|
||||
// Note that we only use this generated version code for builds we want to distribute. For local
|
||||
// debug builds we use a fixed versionCode to not mess with the caching mechanism of the build
|
||||
// system.
|
||||
|
||||
ext {
|
||||
def today = new Date()
|
||||
|
||||
// We use the current year (double digit) and subtract 18. We first released Reference Browser in
|
||||
// 2018 so this value will start counting at 0 and increment by one every year.
|
||||
def year = String.valueOf((new SimpleDateFormat("yy").format(today) as int) - 18)
|
||||
|
||||
// We use the day in the Year (e.g. 248) as opposed to month + day (0510) because it's one digit shorter.
|
||||
// If needed we pad with zeros (e.g. 25 -> 025)
|
||||
def day = String.format("%03d", (new SimpleDateFormat("D").format(today) as int))
|
||||
|
||||
// We append the hour in day (24h) and minute in hour (7:26 pm -> 1926). We do not append
|
||||
// seconds. This assumes that we do not need to build multiple release(!) builds the same
|
||||
// minute.
|
||||
def time = new SimpleDateFormat("HHmm").format(today)
|
||||
|
||||
generatedVersionCode = (year + day + time) as int
|
||||
|
||||
println("Generated versionCode: $generatedVersionCode")
|
||||
println()
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import os
|
||||
import taskcluster
|
||||
|
||||
|
||||
def write_secret_to_file(path, data, key, base64decode=False):
|
||||
path = os.path.join(os.path.dirname(__file__), '../../' + path)
|
||||
with open(path, 'w') as f:
|
||||
value = data['secret'][key]
|
||||
if base64decode:
|
||||
value = base64.b64decode(value)
|
||||
f.write(value)
|
||||
|
||||
|
||||
def fetch_secret_from_taskcluster(name):
|
||||
secrets = taskcluster.Secrets({'baseUrl': 'http://taskcluster/secrets/v1'})
|
||||
return secrets.get(name)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Fetch a taskcluster secret value and save it to a file.')
|
||||
|
||||
parser.add_argument('-s', dest="secret", action="store", help="name of the secret")
|
||||
parser.add_argument('-k', dest='key', action="store", help='key of the secret')
|
||||
parser.add_argument('-f', dest="path", action="store", help='file to save secret to')
|
||||
parser.add_argument(
|
||||
'--decode', dest="decode", action="store_true", default=False,
|
||||
help='base64 decode secret before saving to file'
|
||||
)
|
||||
|
||||
result = parser.parse_args()
|
||||
|
||||
secret = fetch_secret_from_taskcluster(result.secret)
|
||||
write_secret_to_file(result.path, secret, result.key, result.decode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,89 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import argparse
|
||||
import fnmatch
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def collect_apks(path, pattern):
|
||||
matches = []
|
||||
for root, dirnames, filenames in os.walk(path):
|
||||
for filename in fnmatch.filter(filenames, pattern):
|
||||
matches.append(os.path.join(root, filename))
|
||||
return matches
|
||||
|
||||
|
||||
def zipalign(path):
|
||||
unsigned_apks = collect_apks(path, '*-unsigned.apk')
|
||||
print("Found {apk_count} APK(s) to zipalign in {path}".format(apk_count=len(unsigned_apks), path=path))
|
||||
for apk in unsigned_apks:
|
||||
print("Zipaligning", apk)
|
||||
split = os.path.splitext(apk)
|
||||
print(subprocess.check_output(["zipalign", "-f", "-v", "-p", "4", apk, split[0] + "-aligned" + split[1]]))
|
||||
|
||||
|
||||
def sign(path, store, store_token, key_alias, key_token):
|
||||
unsigned_apks = collect_apks(path, '*-aligned.apk')
|
||||
print("Found {apk_count} APK(s) to sign in {path}".format(apk_count=len(unsigned_apks), path=path))
|
||||
|
||||
for apk in unsigned_apks:
|
||||
print("Signing", apk)
|
||||
print(subprocess.check_output([
|
||||
"apksigner", "sign",
|
||||
"--ks", store,
|
||||
"--ks-key-alias", key_alias,
|
||||
"--ks-pass", "file:%s" % store_token,
|
||||
"--key-pass", "file:%s" % key_token,
|
||||
"-v",
|
||||
"--out", apk.replace('unsigned', 'signed'), apk]))
|
||||
|
||||
|
||||
def archive_result(path, archive):
|
||||
if not os.path.exists(archive):
|
||||
os.makedirs(archive)
|
||||
|
||||
signed_apks = collect_apks(path, '*-signed-*.apk')
|
||||
print("Found {apk_count} APK(s) to archive in {path}".format(apk_count=len(signed_apks), path=path))
|
||||
|
||||
for apk in signed_apks:
|
||||
print("Verifying", apk)
|
||||
print(subprocess.check_output(['apksigner', 'verify', apk]))
|
||||
|
||||
destination = archive + "/" + os.path.basename(apk)
|
||||
print("Archiving", apk)
|
||||
print(" `->", destination)
|
||||
os.rename(apk, destination)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Zipaligns, signs and archives APKs')
|
||||
parser.add_argument('--path', dest="path", action="store", help='Root path to search for APK files')
|
||||
parser.add_argument('--zipalign', dest="zipalign", action="store_true", default=False,
|
||||
help='Zipaligns APKs before signing')
|
||||
parser.add_argument('--archive', metavar="PATH", dest="archive", action="store", default=False,
|
||||
help='Path to save sign APKs to')
|
||||
|
||||
parser.add_argument('--store', metavar="PATH", dest="store", action="store", help='Path to keystore')
|
||||
parser.add_argument('--store-token', metavar="PATH", dest="store_token", action="store",
|
||||
help='Path to keystore password file')
|
||||
parser.add_argument('--key-alias', metavar="ALIAS", dest="key_alias", action="store", help='Key alias')
|
||||
parser.add_argument('--key-token', metavar="PATH", dest="key_token", action="store",
|
||||
help='Path to key password file')
|
||||
|
||||
result = parser.parse_args()
|
||||
|
||||
if result.zipalign:
|
||||
zipalign(result.path)
|
||||
|
||||
sign(result.path, result.store, result.store_token, result.key_alias, result.key_token)
|
||||
|
||||
if result.archive:
|
||||
archive_result(result.path, result.archive)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,27 @@
|
||||
object Versions {
|
||||
const val kotlin = "1.3.10"
|
||||
const val coroutines = "1.0.1"
|
||||
const val geckoNightly = "66.0.20181217093726"
|
||||
|
||||
const val androidx_appcompat = "1.0.2"
|
||||
const val androidx_constraintlayout = "1.1.3"
|
||||
|
||||
const val junit = "4.12"
|
||||
const val test_tools = "1.0.2"
|
||||
const val espresso_core = "2.2.2"
|
||||
}
|
||||
|
||||
object Deps {
|
||||
const val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
|
||||
const val kotlin_coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutines}"
|
||||
|
||||
const val geckoview_nightly_arm = "org.mozilla.geckoview:geckoview-nightly-armeabi-v7a:${Versions.geckoNightly}"
|
||||
const val geckoview_nightly_x86 = "org.mozilla.geckoview:geckoview-nightly-x86:${Versions.geckoNightly}"
|
||||
|
||||
const val androidx_appcompat = "androidx.appcompat:appcompat:${Versions.androidx_appcompat}"
|
||||
const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.androidx_constraintlayout}"
|
||||
|
||||
const val junit = "junit:junit:${Versions.junit}"
|
||||
const val tools_test_runner = "com.android.support.test:runner:${Versions.test_tools}"
|
||||
const val tools_espresso_core = "com.android.support.test.espresso:espresso-core:${Versions.espresso_core}"
|
||||
}
|
Loading…
Reference in New Issue