diff options
| -rw-r--r-- | android/app/build.gradle.kts | 7 | ||||
| -rwxr-xr-x | build-apk.sh | 2 | ||||
| -rwxr-xr-x | building/containerized-build.sh | 7 | ||||
| -rwxr-xr-x | ci/buildserver-build-android.sh | 104 | ||||
| -rwxr-xr-x | ci/buildserver-build.sh | 4 |
5 files changed, 118 insertions, 6 deletions
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 95c9cba0a6..e61156ca13 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -16,7 +16,8 @@ val extraAssetsDirectory = "${project.buildDir}/extraAssets" val defaultChangeLogAssetsDirectory = "$repoRootPath/android/src/main/play/release-notes/" val extraJniDirectory = "${project.buildDir}/extraJni" -val keystorePropertiesFile = file("${rootProject.projectDir}/keystore.properties") +val credentialsPath = "${rootProject.projectDir}/credentials" +val keystorePropertiesFile = file("$credentialsPath/keystore.properties") val keystoreProperties = Properties() if (keystorePropertiesFile.exists()) { @@ -46,10 +47,10 @@ android { if (keystorePropertiesFile.exists()) { signingConfigs { create("release") { + storeFile = file("$credentialsPath/app-keys.jks") + storePassword = keystoreProperties.getProperty("storePassword") keyAlias = keystoreProperties.getProperty("keyAlias") keyPassword = keystoreProperties.getProperty("keyPassword") - storeFile = file(keystoreProperties.getProperty("storeFile")) - storePassword = keystoreProperties.getProperty("storePassword") } } diff --git a/build-apk.sh b/build-apk.sh index f3484e677b..c781bd7fb0 100755 --- a/build-apk.sh +++ b/build-apk.sh @@ -50,7 +50,7 @@ while [ ! -z "${1:-""}" ]; do done if [[ "$GRADLE_BUILD_TYPE" == "release" ]]; then - if [ ! -f "$SCRIPT_DIR/android/keystore.properties" ]; then + if [ ! -f "$SCRIPT_DIR/android/credentials/keystore.properties" ]; then echo "ERROR: No keystore.properties file found" >&2 echo " Please configure the signing keys as described in the README" >&2 exit 1 diff --git a/building/containerized-build.sh b/building/containerized-build.sh index d2386473cb..32b75df116 100755 --- a/building/containerized-build.sh +++ b/building/containerized-build.sh @@ -12,6 +12,7 @@ REPO_MOUNT_TARGET="/build" CARGO_TARGET_VOLUME_NAME=${CARGO_TARGET_VOLUME_NAME:-"cargo-target"} CARGO_REGISTRY_VOLUME_NAME=${CARGO_REGISTRY_VOLUME_NAME:-"cargo-registry"} GRADLE_CACHE_VOLUME_NAME=${GRADLE_CACHE_VOLUME_NAME:-"gradle-cache"} +ANDROID_CREDENTIALS_DIR=${ANDROID_CREDENTIALS_DIR:-""} CONTAINER_RUNNER=${CONTAINER_RUNNER:-"podman"} SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -30,6 +31,11 @@ case ${1-:""} in container_image_name=$(cat "$SCRIPT_DIR/android-container-image.txt") build_command=("$REPO_MOUNT_TARGET/build-apk.sh" "--no-docker") optional_gradle_cache_volume=(-v "$GRADLE_CACHE_VOLUME_NAME:/root/.gradle:Z") + + if [ -n "$ANDROID_CREDENTIALS_DIR" ]; then + optional_android_credentials_volume=(-v "$ANDROID_CREDENTIALS_DIR:$REPO_MOUNT_TARGET/android/credentials:Z") + fi + shift 1 ;; *) @@ -43,5 +49,6 @@ exec "$CONTAINER_RUNNER" run --rm -it \ -v "$CARGO_TARGET_VOLUME_NAME:/root/.cargo/target:Z" \ -v "$CARGO_REGISTRY_VOLUME_NAME:/root/.cargo/registry:Z" \ "${optional_gradle_cache_volume[@]}" \ + "${optional_android_credentials_volume[@]}" \ "$container_image_name" \ "${build_command[@]}" "$@" diff --git a/ci/buildserver-build-android.sh b/ci/buildserver-build-android.sh new file mode 100755 index 0000000000..bdb1e94164 --- /dev/null +++ b/ci/buildserver-build-android.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash + +# # Setup instructions before this script will work +# +# * Follow the instructions in ../README.md +# * Import and trust the GPG keys of everyone who the build server should trust code from +# * Ensure that the machine running this script is allowed to upload to releases.mullvad.net. + +set -eu +shopt -s nullglob + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BUILD_DIR="$SCRIPT_DIR/mullvadvpn-app" +LAST_BUILT_DIR="$SCRIPT_DIR/last-built" +UPLOAD_DIR="$SCRIPT_DIR/upload" +ANDROID_CREDENTIALS_DIR="$SCRIPT_DIR/credentials-android" + +BRANCHES_TO_BUILD=("origin/master") +TAG_PATTERN_TO_BUILD=("^android/") + +upload() { + for f in MullvadVPN-*.{apk,aab}; do + sha256sum "$f" > "$f.sha256" + mv "$f" "$f.sha256" "$UPLOAD_DIR/" + done +} + +build_ref() { + ref=$1 + tag=${2:-""} + + current_hash="$(git rev-parse $ref^{commit})" + if [ -f "$LAST_BUILT_DIR/$current_hash" ]; then + # This commit has already been built + return 0 + fi + + echo "" + echo "[#] $ref: $current_hash, building new packages." + + if [[ $ref == "refs/tags/"* ]] && ! git verify-tag $ref; then + echo "!!!" + echo "[#] $ref is a tag, but it failed GPG verification!" + echo "!!!" + sleep 60 + return 0 + elif [[ $ref == "refs/remotes/"* ]] && ! git verify-commit $current_hash; then + echo "!!!" + echo "[#] $ref is a branch, but it failed GPG verification!" + echo "!!!" + sleep 60 + return 0 + fi + + # Clean our working dir and check out the code we want to build + rm -r dist/ 2&>/dev/null || true + git reset --hard + git checkout $ref + git submodule update + git clean -df + + echo "Building Android app" + ANDROID_CREDENTIALS_DIR=$ANDROID_CREDENTIALS_DIR ./building/containerized-build.sh android --app-bundle || return 0 + + # If there is a tag for this commit then we append that to the produced artifacts + # A version suffix should only be created if there is a tag for this commit and it is not a release build + if [[ -n "$tag" ]]; then + # Remove disallowed version characters from the tag + version_suffix="+${tag//[^0-9a-z_-]/}" + # Will only match paths that include *-dev-* which means release builds will not be included + # Pipes all matching names and their new name to mv + pushd dist + for original_file in MullvadVPN-*-dev-*{.apk,.aab}; do + new_file=$(echo $original_file | sed -nE "s/^(MullvadVPN-.*-dev-.*)(\.apk|\.aab)$/\1$version_suffix\2/p") + mv $original_file $new_file + done + popd + fi + + (cd dist/ && upload) || return 0 + + touch "$LAST_BUILT_DIR/$current_hash" + echo "Successfully finished Android build at $(date)" +} + +cd "$BUILD_DIR" + +while true; do + # Delete all tags. So when fetching we only get the ones existing on the remote + git tag | xargs git tag -d > /dev/null + + git fetch --prune --tags 2> /dev/null || continue + tags=( $(git tag | grep "$TAG_PATTERN_TO_BUILD") ) + + for tag in "${tags[@]}"; do + build_ref "refs/tags/$tag" "$tag" + done + + for branch in "${BRANCHES_TO_BUILD[@]}"; do + build_ref "refs/remotes/$branch" + done + + sleep 240 +done diff --git a/ci/buildserver-build.sh b/ci/buildserver-build.sh index 61b83a716b..166dab197d 100755 --- a/ci/buildserver-build.sh +++ b/ci/buildserver-build.sh @@ -124,8 +124,8 @@ build_ref() { echo "Building ARM64 installers" TARGETS=aarch64-unknown-linux-gnu ./build.sh "${BUILD_ARGS[@]}" || return 0 - echo "Building Android APK" - ./build-apk.sh --app-bundle || return 0 + #echo "Building Android APK" + #./build-apk.sh --app-bundle || return 0 ;; esac |
