-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathbuild_release_apk.sh
More file actions
executable file
·141 lines (120 loc) · 4.22 KB
/
Copy pathbuild_release_apk.sh
File metadata and controls
executable file
·141 lines (120 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env bash
set -euo pipefail
# build_release_apk.sh — Build the Andruav Android app as a signed release APK.
# Signing credentials are read from a gitignored keystore.properties file at
# the project root. If the file is absent the build falls back to the debug
# keystore (see app/build.gradle signingConfigs), which is fine for local
# testing but NOT for a production/SourceForge release.
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$PROJECT_DIR"
DEFAULT_OUT_DIR="$PROJECT_DIR/app/build/outputs/apk/release"
CLEAN=1
OUTPUT_DIR="$DEFAULT_OUT_DIR"
usage() {
cat <<EOF
Usage: $0 [options]
Options:
-o, --output-dir DIR Copy the final APK to DIR (default: $DEFAULT_OUT_DIR)
-n, --no-clean Skip ./gradlew clean before building
-h, --help Show this help
EOF
exit 1
}
while [[ $# -gt 0 ]]; do
case "$1" in
-o|--output-dir)
OUTPUT_DIR="$2"
shift 2
;;
-n|--no-clean)
CLEAN=0
shift
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1" >&2
usage
;;
esac
done
# Resolve ANDROID_HOME from the environment or from local.properties.
if [[ -z "${ANDROID_HOME:-}" ]]; then
if [[ -f "$PROJECT_DIR/local.properties" ]]; then
ANDROID_HOME="$(grep '^sdk.dir=' "$PROJECT_DIR/local.properties" | cut -d= -f2- || true)"
# Remove any trailing whitespace / CR.
ANDROID_HOME="$(printf '%s' "$ANDROID_HOME" | tr -d '\r')"
fi
fi
if [[ -z "${ANDROID_HOME:-}" || ! -d "$ANDROID_HOME" ]]; then
cat <<EOF >&2
Error: ANDROID_HOME is not set and no valid sdk.dir was found in local.properties.
Please set ANDROID_HOME to your Android SDK directory, e.g.:
export ANDROID_HOME=/home/mhefny/TDisk/Android/SDK
EOF
exit 1
fi
export ANDROID_HOME
# Require keystore.properties for a signed release. The Gradle script falls
# back to the debug keystore when it's missing, so we only warn here and let
# the build proceed — but make it very visible.
KEYSTORE_PROPS="$PROJECT_DIR/keystore.properties"
if [[ ! -f "$KEYSTORE_PROPS" ]]; then
echo "Warning: keystore.properties not found at $KEYSTORE_PROPS" >&2
echo " Release will be signed with the DEBUG keystore (not suitable for production)." >&2
echo " Create keystore.properties with storeFile/storePassword/keyAlias/keyPassword." >&2
else
echo "==> Using signing credentials from $KEYSTORE_PROPS"
fi
# Validate the SDK components this project expects.
REQUIRED_PLATFORM="$ANDROID_HOME/platforms/android-34"
REQUIRED_BUILD_TOOLS="$ANDROID_HOME/build-tools/34.0.0"
if [[ ! -d "$REQUIRED_PLATFORM" ]]; then
echo "Error: missing required SDK platform: $REQUIRED_PLATFORM" >&2
exit 1
fi
if [[ ! -d "$REQUIRED_BUILD_TOOLS" ]]; then
echo "Error: missing required build tools: $REQUIRED_BUILD_TOOLS" >&2
exit 1
fi
# Sanity-check the Java version.
JAVA_VERSION_OUTPUT=$(java -version 2>&1 | head -n1)
JAVA_MAJOR=$(echo "$JAVA_VERSION_OUTPUT" | sed -E 's/.* version "([0-9]+)(\.[0-9]+)*".*/\1/')
if [[ -z "$JAVA_MAJOR" ]]; then
JAVA_MAJOR=$(echo "$JAVA_VERSION_OUTPUT" | sed -E 's/.* version "([0-9]+)\..*/\1/')
fi
if [[ "${JAVA_MAJOR:-0}" -lt 17 ]]; then
echo "Warning: Java 17+ is recommended for this project. Found: $JAVA_VERSION_OUTPUT" >&2
fi
# Build.
if [[ "$CLEAN" -eq 1 ]]; then
echo "==> Cleaning previous build artifacts..."
./gradlew clean --no-daemon
fi
echo "==> Building release APK..."
./gradlew :app:assembleRelease --no-daemon
# Locate the built APK.
APK_PATH=$(find "$PROJECT_DIR/app/build/outputs/apk/release" -maxdepth 1 -name '*.apk' -type f | sort -V | tail -n1)
if [[ -z "$APK_PATH" ]]; then
echo "Error: no APK found in $PROJECT_DIR/app/build/outputs/apk/release" >&2
exit 1
fi
APK_NAME=$(basename "$APK_PATH")
# Copy to the requested output directory (skip if it's already there).
mkdir -p "$OUTPUT_DIR"
FINAL_PATH="$OUTPUT_DIR/$APK_NAME"
if [[ "$(readlink -f "$APK_PATH")" != "$(readlink -f "$FINAL_PATH")" ]]; then
cp -f "$APK_PATH" "$FINAL_PATH"
fi
echo ""
echo "==> Release APK built successfully:"
echo " $FINAL_PATH"
ls -lh "$FINAL_PATH"
# Optional verification.
APK_SIGNER="$REQUIRED_BUILD_TOOLS/apksigner"
if [[ -x "$APK_SIGNER" ]]; then
echo ""
echo "==> APK signer verification:"
"$APK_SIGNER" verify --verbose "$FINAL_PATH" || true
fi