12345678set -eu910JAVA_HOME="/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home"11if [ ! -d "$JAVA_HOME" ]; then12 echo "refusing to publish: required Java 17 runtime not found at $JAVA_HOME" >&213 exit 114fi15export JAVA_HOME1617ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)18cd "$ROOT_DIR"1920212223. "$ROOT_DIR/scripts/kepr-build-helpers.sh"2425PROPERTIES_FILE="$ROOT_DIR/local.properties"26if [ ! -r "$PROPERTIES_FILE" ]; then27 echo "refusing to publish: local.properties is missing or unreadable" >&228 exit 129fi3031property() {32 33 34 sed -n "s/^$1=//p" "$PROPERTIES_FILE" | sed -n '1p'35}3637STORE_FILE_PROPERTY=$(property peachStoreFile)38STORE_PASSWORD=$(property peachStorePassword)39KEY_ALIAS=$(property peachKeyAlias)40KEY_PASSWORD=$(property peachKeyPassword)4142if [ -z "$STORE_FILE_PROPERTY" ] || [ -z "$STORE_PASSWORD" ] ||43 [ -z "$KEY_ALIAS" ] || [ -z "$KEY_PASSWORD" ]; then44 echo "refusing to publish: incomplete release signing configuration" >&245 exit 146fi4748case "$STORE_FILE_PROPERTY" in49 /*) STORE_FILE="$STORE_FILE_PROPERTY" ;;50 *) STORE_FILE="$ROOT_DIR/$STORE_FILE_PROPERTY" ;;51esac52if [ ! -f "$STORE_FILE" ] || [ ! -r "$STORE_FILE" ]; then53 echo "refusing to publish: configured release keystore is missing or unreadable" >&254 exit 155fi5657585960SDK_ROOT="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}"61if [ -z "$SDK_ROOT" ]; then62 SDK_ROOT=$(property sdk.dir)63fi64if [ -z "$SDK_ROOT" ] || [ ! -d "$SDK_ROOT/build-tools" ]; then65 echo "refusing to publish: Android SDK build-tools directory not found" >&266 exit 167fi6869BUILD_TOOLS_DIR=$(find_stable_build_tools_dir "$SDK_ROOT" || true)70if [ -z "$BUILD_TOOLS_DIR" ]; then71 echo "refusing to publish: no versioned build-tools directory has apksigner and aapt2" >&272 exit 173fi74APKSIGNER="$BUILD_TOOLS_DIR/apksigner"75AAPT2="$BUILD_TOOLS_DIR/aapt2"7677ROOT_VERSION=$(read_root_semver "$ROOT_DIR/VERSION" || true)78if [ -z "$ROOT_VERSION" ]; then79 echo "refusing to publish: VERSION is missing or not strict semantic version" >&280 exit 181fi8283"$ROOT_DIR/gradlew" --no-configuration-cache :app:assembleRelease8485case "${KEPR_TARGET:-}" in86 android-arm64)87 APK_NAME="app-arm64-v8a-release.apk"88 EXPECTED_ABI="arm64-v8a"89 ;;90 android-x86)91 APK_NAME="app-x86_64-release.apk"92 EXPECTED_ABI="x86_64"93 ;;94 *)95 echo "refusing to publish: unsupported KEPR_TARGET '${KEPR_TARGET:-unset}'" >&296 exit 197 ;;98esac99100APK="$ROOT_DIR/app/build/outputs/apk/release/$APK_NAME"101METADATA="$ROOT_DIR/app/build/outputs/apk/release/output-metadata.json"102if [ ! -f "$APK" ] || [ ! -r "$APK" ]; then103 echo "refusing to publish: release APK was not produced" >&2104 exit 1105fi106if [ ! -f "$METADATA" ] || [ ! -r "$METADATA" ]; then107 echo "refusing to publish: Gradle output metadata was not produced" >&2108 exit 1109fi110111BADGING_FILE=$(mktemp "${TMPDIR:-/tmp}/peach-apk-badging.XXXXXX")112cleanup_badging() {113 [ -e "$BADGING_FILE" ] && trash "$BADGING_FILE"114}115trap cleanup_badging EXIT HUP INT TERM116"$AAPT2" dump badging "$APK" > "$BADGING_FILE"117if ! validate_release_metadata \118 "$METADATA" \119 "$BADGING_FILE" \120 "$ROOT_VERSION" \121 "com.peachpasswords" \122 "$APK_NAME" \123 "$EXPECTED_ABI"; then124 exit 1125fi126127128129130SIGNING_OUTPUT=$("$APKSIGNER" verify --verbose --print-certs "$APK" 2>/dev/null) || {131 echo "refusing to publish: apksigner verification failed" >&2132 exit 1133}134if ! printf '%s\n' "$SIGNING_OUTPUT" | grep -Eq 'Verified using v[234] scheme.*: true'; then135 echo "refusing to publish: APK is not signed with APK Signature Scheme v2 or newer" >&2136 exit 1137fi138139PINNED_RELEASE_CERT_SHA256="e10b975178f0bee7fb5a4802519da70ec2988b6ef7d8c9401fbbcff5a1137668"140CERT_DIGEST_COUNT=$(printf '%s\n' "$SIGNING_OUTPUT" | grep -c 'certificate SHA-256 digest:' || true)141if [ "$CERT_DIGEST_COUNT" -ne 1 ]; then142 echo "refusing to publish: release APK must have exactly one signer certificate" >&2143 exit 1144fi145CERT_DIGEST=$(printf '%s\n' "$SIGNING_OUTPUT" |146 sed -n 's/.*certificate SHA-256 digest:[[:space:]]*//p' |147 sed -n '1p' | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')148if [ "$CERT_DIGEST" != "$PINNED_RELEASE_CERT_SHA256" ]; then149 echo "refusing to publish: APK signer certificate does not match the pinned Peach release digest" >&2150 exit 1151fi152153154155156mkdir -p "$ROOT_DIR/build/kepr"157STAGED_NAME="peach-android-${ROOT_VERSION}-${KEPR_TARGET}.apk"158cp "$APK" "$ROOT_DIR/build/kepr/$STAGED_NAME"159echo "release APK verified and staged: build/kepr/$STAGED_NAME"