From acfa73ab43b834fcc3dcd0c9037d0d652c6f9102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Fri, 22 Apr 2022 12:20:01 +0400 Subject: [PATCH] nix: build unsigned Android APK, sign separately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has several benefits: * Less abuse of `extra-sandbox-paths` Nix option * Less inputs to the Android release build derivation * Easier for users to sign the build themselves * Simplification of `scripts/release-android.sh` * Preparation for building using Nix Flakes The only two remaining credentials passed via `extra-sandbox-paths` is the Infura and OpenSea API keys, and there is no way around that other than passing them via Nix arguments, but that would cause them to end up in `/nix/store` as part of `.drv` files. I'm also renaming `release-fdroid` to `build-fdroid` to be consistent. Depends on: https://github.com/status-im/status-jenkins-lib/pull/42 Signed-off-by: Jakub SokoĊ‚owski --- Makefile | 50 +++++++++++-------- android/app/build.gradle | 31 ++++-------- android/gradle.properties | 2 - ci/Jenkinsfile.android | 7 ++- ci/Jenkinsfile.combined | 2 +- ci/Jenkinsfile.ios | 2 +- ci/Jenkinsfile.nix-cache | 2 +- ci/tests/Jenkinsfile.e2e-prs | 2 +- ci/tools/Jenkinsfile.fastlane-clean | 2 +- ci/tools/Jenkinsfile.playstore-meta | 2 +- nix/README.md | 1 - nix/config.nix | 1 - nix/mobile/android/default.nix | 7 +-- nix/mobile/android/keystore.nix | 44 ---------------- nix/mobile/android/release.nix | 25 +++------- nix/scripts/build.sh | 2 +- nix/shells.nix | 2 +- .../{release-android.sh => build-android.sh} | 19 ++----- scripts/generate-keystore.sh | 5 +- scripts/sign-android.sh | 48 ++++++++++++++++++ 20 files changed, 112 insertions(+), 144 deletions(-) delete mode 100644 nix/mobile/android/keystore.nix rename scripts/{release-android.sh => build-android.sh} (80%) create mode 100755 scripts/sign-android.sh diff --git a/Makefile b/Makefile index 7eae2bbc38..374b2af632 100644 --- a/Makefile +++ b/Makefile @@ -32,10 +32,12 @@ ifndef BUILD_TAG export BUILD_TAG := $(shell git rev-parse --short HEAD) endif -# We don't want to use /run/user/$UID because it runs out of space too easilly +# We don't want to use /run/user/$UID because it runs out of space too easilly. export TMPDIR = /tmp/tmp-status-react-$(BUILD_TAG) -# this has to be specified for both the Node.JS server process and the Qt process +# This has to be specified for both the Node.JS server process and the Qt process. export REACT_SERVER_PORT ?= 5001 +# The path can be anything, but home is usually safest. +export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore # Our custom config is located in nix/nix.conf export NIX_CONF_DIR = $(PWD)/nix @@ -153,11 +155,12 @@ update-fleets: ##@prepare Download up-to-date JSON file with current fleets stat | jq --indent 4 --sort-keys . \ > resources/config/fleets.json -keystore: export TARGET := keytool -keystore: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore -keystore: ##@prepare Generate a Keystore for signing Android APKs +$(KEYSTORE_PATH): export TARGET := keytool +$(KEYSTORE_PATH): @./scripts/generate-keystore.sh +keystore: $(KEYSTORE_PATH) ##@prepare Generate a Keystore for signing Android APKs + fdroid-max-watches: SHELL := /bin/sh fdroid-max-watches: ##@prepare Bump max_user_watches to avoid ENOSPC errors sysctl fs.inotify.max_user_watches=524288 @@ -190,23 +193,26 @@ xcode-clean: ##@prepare Clean XCode derived data and archives #---------------- release: release-android release-ios ##@build Build release for Android and iOS -release-android: export BUILD_ENV ?= prod -release-android: export BUILD_TYPE ?= nightly -release-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER) -release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore -release-android: export ANDROID_APK_SIGNED ?= true -release-android: export ANDROID_ABI_SPLIT ?= false -release-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86 -release-android: keystore ##@build Build release for Android - scripts/release-android.sh +build-fdroid: export BUILD_ENV = prod +build-fdroid: export BUILD_TYPE = release +build-fdroid: export ANDROID_ABI_SPLIT = false +build-fdroid: export ANDROID_ABI_INCLUDE = armeabi-v7a;arm64-v8a;x86;x86_64 +build-fdroid: ##@build Build release for F-Droid + @scripts/build-android.sh -release-fdroid: export BUILD_ENV = prod -release-fdroid: export BUILD_TYPE = release -release-fdroid: export ANDROID_APK_SIGNED = false -release-fdroid: export ANDROID_ABI_SPLIT = false -release-fdroid: export ANDROID_ABI_INCLUDE = armeabi-v7a;arm64-v8a;x86;x86_64 -release-fdroid: ##@build Build release for F-Droid - scripts/release-android.sh +build-android: SHELL := /bin/sh +build-android: export BUILD_ENV ?= prod +build-android: export BUILD_TYPE ?= nightly +build-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER) +build-android: export ANDROID_ABI_SPLIT ?= false +build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86 +build-android: ##@build Build unsigned Android APK + @scripts/build-android.sh + +release-android: export TARGET := keytool +release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore +release-android: keystore build-android ##@build Build signed Android APK + @scripts/sign-android.sh result/app-release-unsigned.apk release-ios: export TARGET := ios release-ios: export BUILD_ENV ?= prod @@ -221,7 +227,7 @@ jsbundle-android: export BUILD_ENV ?= prod jsbundle-android: ##@jsbundle Compile JavaScript and Clojurescript into app directory # Call nix-build to build the 'targets.mobile.android.jsbundle' attribute and copy the.js files to the project root nix/scripts/build.sh targets.mobile.android.jsbundle && \ - mv result/* ./ + mv result/*.js ./ jsbundle-ios: export TARGET := ios jsbundle-ios: export BUILD_ENV ?= prod diff --git a/android/app/build.gradle b/android/app/build.gradle index 656859bbb6..9f315f76c0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -229,23 +229,6 @@ android { jumboMode true javaMaxHeapSize "8g" } - signingConfigs { - debug { - storeFile file('debug.keystore') - storePassword 'android' - keyAlias 'androiddebugkey' - keyPassword 'android' - } - /* Caution! In production, you need to generate your own keystore file. - * See: https://facebook.github.io/react-native/docs/signed-apk-android */ - release { - /* environment variables take precedence over gradle.properties file */ - storeFile file(getEnvOrConfig('KEYSTORE_PATH').replaceAll("~", System.properties['user.home'])) - storePassword getEnvOrConfig('KEYSTORE_PASSWORD') - keyAlias getEnvOrConfig('KEYSTORE_ALIAS') - keyPassword getEnvOrConfig('KEYSTORE_KEY_PASSWORD') - } - } splits { abi { reset() @@ -254,20 +237,26 @@ android { universalApk true } } + signingConfigs { + debug { + storeFile file('debug.keystore') + storePassword 'android' + keyAlias 'androiddebugkey' + keyPassword 'android' + } + } buildTypes { debug { applicationIdSuffix ".debug" debuggable true versionNameSuffix "-SNAPSHOT" - signingConfig signingConfigs.debug resValue "string", "build_config_package", "im.status.ethereum" + signingConfig signingConfigs.debug } release { minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" - if (getEnvOrConfig('ANDROID_APK_SIGNED').toBoolean()) { - signingConfig signingConfigs.release - } + signingConfig null } pr { initWith release diff --git a/android/gradle.properties b/android/gradle.properties index 643fef7709..b1a0c8a8db 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -42,8 +42,6 @@ KEYSTORE_KEY_PASSWORD=password ANDROID_ABI_SPLIT=false # Some platforms are excluded though ANDROID_ABI_INCLUDE=armeabi-v7a;arm64-v8a;x86 -# F-Droid builds need to be unsigned -ANDROID_APK_SIGNED=true org.gradle.jvmargs=-Xmx8704M diff --git a/ci/Jenkinsfile.android b/ci/Jenkinsfile.android index 8ba7aee8ea..7492cc976d 100644 --- a/ci/Jenkinsfile.android +++ b/ci/Jenkinsfile.android @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { agent { label 'linux && x86_64 && nix-2.8' } @@ -81,6 +81,11 @@ pipeline { script { apks = android.bundle() } } } + stage('Sign') { + steps { + script { apks = android.sign(apks) } + } + } } } } } diff --git a/ci/Jenkinsfile.combined b/ci/Jenkinsfile.combined index 856b056181..6c2e8645bd 100644 --- a/ci/Jenkinsfile.combined +++ b/ci/Jenkinsfile.combined @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { agent { label 'linux' } diff --git a/ci/Jenkinsfile.ios b/ci/Jenkinsfile.ios index 4106859958..873f937a01 100644 --- a/ci/Jenkinsfile.ios +++ b/ci/Jenkinsfile.ios @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { agent { label 'macos && x86_64 && nix-2.8 && xcode-13.3' } diff --git a/ci/Jenkinsfile.nix-cache b/ci/Jenkinsfile.nix-cache index d86df893ba..c26bc8980f 100644 --- a/ci/Jenkinsfile.nix-cache +++ b/ci/Jenkinsfile.nix-cache @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { agent { label params.AGENT_LABEL } diff --git a/ci/tests/Jenkinsfile.e2e-prs b/ci/tests/Jenkinsfile.e2e-prs index 1b59e594e6..6fc8ecc9d7 100644 --- a/ci/tests/Jenkinsfile.e2e-prs +++ b/ci/tests/Jenkinsfile.e2e-prs @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { diff --git a/ci/tools/Jenkinsfile.fastlane-clean b/ci/tools/Jenkinsfile.fastlane-clean index 2220c3ec45..2e5dd5e8b5 100644 --- a/ci/tools/Jenkinsfile.fastlane-clean +++ b/ci/tools/Jenkinsfile.fastlane-clean @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { agent { label 'macos' } diff --git a/ci/tools/Jenkinsfile.playstore-meta b/ci/tools/Jenkinsfile.playstore-meta index 8e69812799..2ee76b0bd7 100644 --- a/ci/tools/Jenkinsfile.playstore-meta +++ b/ci/tools/Jenkinsfile.playstore-meta @@ -1,4 +1,4 @@ -library 'status-jenkins-lib@v1.4.2' +library 'status-jenkins-lib@v1.4.3' pipeline { agent { label 'linux' } diff --git a/nix/README.md b/nix/README.md index ef314bf5f7..7e5e86e737 100644 --- a/nix/README.md +++ b/nix/README.md @@ -19,7 +19,6 @@ Here is a sample structure of the `config` attribute set: build-number = 9999; # Used for versionCode and CFBundleVersion in Android and iOS respectively android = { gradle-opts = ""; # Gradle options passed for Android builds - keystore-path = ""; # Path to keystore for signing the APK abi-split = false; # If APKs should be split based on architectures abi-include = "x86"; # Android architectures to build for }; diff --git a/nix/config.nix b/nix/config.nix index 416ff6e5ae..34ca0bd6c2 100644 --- a/nix/config.nix +++ b/nix/config.nix @@ -7,7 +7,6 @@ android = { gradle-opts = null; # Gradle options passed for Android builds - keystore-path = null; # Path to keystore for signing the APK apk-signed = true; # F-Droid builds aren't signed by us abi-split = false; # If APKs should be split based on architectures abi-include = "armeabi-v7a;arm64-v8a;x86"; # Android architectures to build for diff --git a/nix/mobile/android/default.nix b/nix/mobile/android/default.nix index 911772c35a..ca8b8d4f50 100644 --- a/nix/mobile/android/default.nix +++ b/nix/mobile/android/default.nix @@ -2,9 +2,6 @@ , status-go, androidPkgs, androidShell }: let - # For generating a temporary keystore for local development - keystore = callPackage ./keystore.nix { }; - # Import a jsbundle compiled out of clojure codebase jsbundle = callPackage ./jsbundle { }; @@ -13,12 +10,12 @@ let # TARGETS release = callPackage ./release.nix { - inherit keystore jsbundle status-go watchmanFactory; + inherit jsbundle status-go watchmanFactory; }; in { # TARGETS - inherit keystore release jsbundle; + inherit release jsbundle; shell = mkShell { buildInputs = with pkgs; [ diff --git a/nix/mobile/android/keystore.nix b/nix/mobile/android/keystore.nix deleted file mode 100644 index a6d4a5d171..0000000000 --- a/nix/mobile/android/keystore.nix +++ /dev/null @@ -1,44 +0,0 @@ -# -# Generates an ad-hoc and temporary keystore for signing debug/pr builds. -# -# WARNING: Do NOT use this to make a keystore that needs to be secret! -# Using a derivation will store the inputs in a .drv file. -# -{ stdenv, lib, pkgs }: - -let - inherit (lib) getAttr; - - gradleProps = pkgs.gradlePropParser ../../../android/gradle.properties; - - # Loading defaults from gradle.properties which should be safe. - KEYSTORE_ALIAS = getAttr "KEYSTORE_ALIAS" gradleProps; - KEYSTORE_PASSWORD = getAttr "KEYSTORE_PASSWORD" gradleProps; - KEYSTORE_KEY_PASSWORD = getAttr "KEYSTORE_KEY_PASSWORD" gradleProps; - -in stdenv.mkDerivation { - name = "status-react-android-keystore"; - - buildInputs = [ pkgs.openjdk8 ]; - - phases = [ "generatePhase" ]; - generatePhase = '' - keytool -genkey -v \ - -keyalg RSA \ - -keysize 2048 \ - -validity 10000 \ - -deststoretype pkcs12 \ - -dname "CN=, OU=, O=, L=, S=, C=" \ - -keystore "$out" \ - -alias "${KEYSTORE_ALIAS}" \ - -storepass "${KEYSTORE_PASSWORD}" \ - -keypass "${KEYSTORE_KEY_PASSWORD}" \ - >&2 - ''; - - shellHook = '' - export KEYSTORE_ALIAS="${KEYSTORE_ALIAS}" - export KEYSTORE_PASSWORD="${KEYSTORE_PASSWORD}" - export KEYSTORE_KEY_PASSWORD="${KEYSTORE_KEY_PASSWORD}" - ''; -} diff --git a/nix/mobile/android/release.nix b/nix/mobile/android/release.nix index afeae2fe24..b8b634cf5f 100644 --- a/nix/mobile/android/release.nix +++ b/nix/mobile/android/release.nix @@ -1,6 +1,6 @@ { stdenv, pkgs, deps, lib, config, callPackage, watchmanFactory, androidPkgs, patchMavenSources, - keystore, jsbundle, status-go }: + jsbundle, status-go }: { # Value for BUILD_ENV checked by Clojure code at compile time @@ -28,9 +28,6 @@ let gradleOpts = getConfig "android.gradle-opts" null; # Used to detect end-to-end builds androidAbiInclude = getConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86"; - # Keystore can be provided via config and extra-sandbox-paths. - # If it is not we use an ad-hoc one generated with default password. - keystorePath = getConfig "android.keystore-path" keystore; baseName = "${buildType}-android"; name = "status-react-build-${baseName}"; @@ -76,7 +73,6 @@ in stdenv.mkDerivation rec { # custom env variables derived from config STATUS_GO_SRC_OVERRIDE = getConfig "status-go.src-override" null; - ANDROID_APK_SIGNED = getConfig "android.apk-signed" "true"; ANDROID_ABI_SPLIT = getConfig "android.abi-split" "false"; ANDROID_ABI_INCLUDE = androidAbiInclude; @@ -88,8 +84,7 @@ in stdenv.mkDerivation rec { STATUS_GO_ANDROID_LIBDIR = status-go { inherit secretsFile; }; phases = [ - "unpackPhase" "secretsPhase" "keystorePhase" - "buildPhase" "checkPhase" "installPhase" + "unpackPhase" "secretsPhase" "buildPhase" "checkPhase" "installPhase" ]; unpackPhase = '' @@ -120,21 +115,13 @@ in stdenv.mkDerivation rec { ${patchMavenSources} ./android/build.gradle ''; - # if secretsFile is not set we use generate keystore + # Secrets file is passed to sandbox using extra-sandbox-paths. secretsPhase = if (secretsFile != "") then '' source "${secretsFile}" - ${checkEnvVarSet "KEYSTORE_ALIAS"} - ${checkEnvVarSet "KEYSTORE_PASSWORD"} - ${checkEnvVarSet "KEYSTORE_KEY_PASSWORD"} - '' else keystore.shellHook; - - # if keystorePath is set copy it into build directory - keystorePhase = - assert assertMsg (keystorePath != null) "keystorePath has to be set!"; - '' - export KEYSTORE_PATH="$PWD/status-im.keystore" - cp -a --no-preserve=ownership "${keystorePath}" "$KEYSTORE_PATH" + '' else '' + echo 'WARNING: No secrets provided!' >&2 ''; + buildPhase = let adhocEnvVars = optionalString stdenv.isLinux "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ pkgs.zlib ]}"; diff --git a/nix/scripts/build.sh b/nix/scripts/build.sh index 628a8a55ab..e5088676ce 100755 --- a/nix/scripts/build.sh +++ b/nix/scripts/build.sh @@ -58,7 +58,7 @@ nixOpts=( ${GIT_ROOT}/nix/scripts/gcroots.sh "${TARGET}" "${@}" # Run the actual build -echo "Running: nix-build "${nixOpts[@]}" "${@}" default.nix" +echo "${GRN}Running:${RST} nix-build "${nixOpts[@]}" "${@}" default.nix" nixResultPath=$(nix-build "${nixOpts[@]}" "${@}" default.nix) echo -e "\n${YLW}Extracting result${RST}: ${BLD}${nixResultPath}${RST}" diff --git a/nix/shells.nix b/nix/shells.nix index 387ad5a4b3..3e0c2f2636 100644 --- a/nix/shells.nix +++ b/nix/shells.nix @@ -58,7 +58,7 @@ let # for 'scripts/generate-keystore.sh' keytool = mkShell { - buildInputs = with pkgs; [ openjdk8 ]; + buildInputs = with pkgs; [ openjdk8 apksigner ]; }; # for targets that need 'adb' and other SDK/NDK tools diff --git a/scripts/release-android.sh b/scripts/build-android.sh similarity index 80% rename from scripts/release-android.sh rename to scripts/build-android.sh index 8f2b916658..63400001a6 100755 --- a/scripts/release-android.sh +++ b/scripts/build-android.sh @@ -26,13 +26,9 @@ config='' if [[ -n "${STATUS_GO_SRC_OVERRIDE}" ]]; then config+="status-im.status-go.src-override=\"${STATUS_GO_SRC_OVERRIDE}\";" fi -if [[ "${ANDROID_APK_SIGNED}" == "true" ]]; then - config+="status-im.android.keystore-path=\"$(must_get_env KEYSTORE_PATH)\";" -fi config+="status-im.commit-hash=\"$(git rev-parse --verify HEAD)\";" config+="status-im.build-type=\"$(must_get_env BUILD_TYPE)\";" config+="status-im.build-number=\"$(must_get_env BUILD_NUMBER)\";" -config+="status-im.android.apk-signed=\"$(must_get_env ANDROID_APK_SIGNED)\";" config+="status-im.android.abi-split=\"$(must_get_env ANDROID_ABI_SPLIT)\";" config+="status-im.android.abi-include=\"$(must_get_env ANDROID_ABI_INCLUDE)\";" nixOpts=() @@ -42,19 +38,10 @@ export SECRETS_FILE_PATH=$(mktemp) chmod 644 ${SECRETS_FILE_PATH} # If secrets file was created we want to remove it. trap "rm -vf ${SECRETS_FILE_PATH}" EXIT ERR INT QUIT + # Secrets like this can't be passed via args or they end up in derivation. -if [[ -n "${KEYSTORE_ALIAS}${KEYSTORE_ALIAS}${KEYSTORE_ALIAS}" ]]; then - # WARNING: All three have to be set! - append_env_export 'KEYSTORE_PASSWORD' - append_env_export 'KEYSTORE_ALIAS' - append_env_export 'KEYSTORE_KEY_PASSWORD' -fi -if [[ -n "${INFURA_TOKEN}" ]]; then - append_env_export 'INFURA_TOKEN' -fi -if [[ -n "${OPENSEA_API_KEY}" ]]; then - append_env_export 'OPENSEA_API_KEY' -fi +if [[ -n "${INFURA_TOKEN}" ]]; then append_env_export 'INFURA_TOKEN'; fi +if [[ -n "${OPENSEA_API_KEY}" ]]; then append_env_export 'OPENSEA_API_KEY'; fi # If no secrets were passed there's no need to pass the 'secretsFile'. if [[ -s "${SECRETS_FILE_PATH}" ]]; then diff --git a/scripts/generate-keystore.sh b/scripts/generate-keystore.sh index 592a0c14c3..0b3fc20151 100755 --- a/scripts/generate-keystore.sh +++ b/scripts/generate-keystore.sh @@ -32,7 +32,6 @@ KEYSTORE_PATH=${KEYSTORE_PATH/#\~/$HOME} if [[ -e "${KEYSTORE_PATH}" ]]; then echo -e "${YLW}Keystore file already exists:${RST} ${KEYSTORE_PATH}" >&2 - echo "${KEYSTORE_PATH}" exit 0 fi @@ -41,7 +40,7 @@ KEYSTORE_DIR=$(dirname "${KEYSTORE_PATH}") echo -e "${GRN}Generating keystore...${RST}" >&2 -keytool -genkey -v \ +exec keytool -genkey -v \ -keyalg RSA \ -keysize 2048 \ -validity 10000 \ @@ -52,5 +51,3 @@ keytool -genkey -v \ -storepass "${KEYSTORE_PASSWORD}" \ -keypass "${KEYSTORE_KEY_PASSWORD}" \ > /dev/stderr - -echo "${KEYSTORE_PATH}" diff --git a/scripts/sign-android.sh b/scripts/sign-android.sh new file mode 100755 index 0000000000..59b8c23eed --- /dev/null +++ b/scripts/sign-android.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -e + +GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel) +source "${GIT_ROOT}/scripts/colors.sh" + +function property() { + grep "${2}" "${1}" | cut -d'=' -f2 +} + +function gradle_property() { + property ${GIT_ROOT}/android/gradle.properties ${1} +} + +function env_var_or_gradle_prop() { + VAR_NAME="${1}" + if [[ -n "${!VAR_NAME}" ]]; then + echo "${!VAR_NAME}" + else + gradle_property "${VAR_NAME}" + fi +} + +function must_get_env() { + declare -n VAR_VALUE="$1" + if [[ -n "${VAR_VALUE}" ]]; then + echo "${VAR_VALUE}" + return + fi + echo -e "${RED}No required env variable:${RST} ${BLD}${!VAR_VALUE}${RST}" 1>&2 + exit 1 +} + +# If filename contains string "unsigned" change that to signed. +# Otherwise sign in-place and overwrite the current unsigned file. +if [[ "${1}" =~ unsigned ]]; then + OUTPUT_FLAGS="--out=${1/unsigned/signed}" +fi + +echo -e "${GRN}Signing APK:${RST} ${1}" >&2 + +exec apksigner sign --verbose \ + --ks="$(env_var_or_gradle_prop KEYSTORE_PATH)" \ + --ks-pass="pass:$(env_var_or_gradle_prop KEYSTORE_PASSWORD)" \ + --ks-key-alias="$(env_var_or_gradle_prop KEYSTORE_ALIAS)" \ + --key-pass="pass:$(env_var_or_gradle_prop KEYSTORE_KEY_PASSWORD)" \ + "${OUTPUT_FLAGS}" \ + "${1}"