Improve build.sh logging, validation, and option parsing
This commit is contained in:
parent
15ec7eba0c
commit
0467ff1f68
160
build.sh
160
build.sh
@ -29,21 +29,6 @@ SDKMANAGER="${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager"
|
||||
VERSION=$(grep versionName uhabits-android/build.gradle.kts | sed -e 's/.*"\([^"]*\)".*/\1/g')
|
||||
BOOT_TIMEOUT=360
|
||||
|
||||
if [ -z $VERSION ]; then
|
||||
echo "Could not parse app version from: uhabits-android/build.gradle.kts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${ANDROID_HOME}/platform-tools/adb" ]; then
|
||||
echo "Error: ANDROID_HOME is not set correctly; ${ANDROID_HOME}/platform-tools/adb not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$EMULATOR" ]; then
|
||||
echo "Error: Not found: $EMULATOR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Logging
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@ -59,12 +44,73 @@ log_info() {
|
||||
echo -e "$COLOR* $1 $NC"
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
local COLOR='\033[0;90m'
|
||||
local NC='\033[0m'
|
||||
echo -e "${COLOR}$1 $NC"
|
||||
}
|
||||
|
||||
run() {
|
||||
log_debug "$*"
|
||||
"$@"
|
||||
}
|
||||
|
||||
fail() {
|
||||
log_error "BUILD FAILED"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Validation
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
if [ -z $VERSION ]; then
|
||||
log_error "Could not parse app version from: uhabits-android/build.gradle.kts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${ANDROID_HOME}/platform-tools/adb" ]; then
|
||||
log_error "ANDROID_HOME is not set correctly; ${ANDROID_HOME}/platform-tools/adb not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$EMULATOR" ]; then
|
||||
log_error "Not found: $EMULATOR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MISSING_DEPS=0
|
||||
IS_MACOS=0
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
IS_MACOS=1
|
||||
fi
|
||||
|
||||
check_cmd() {
|
||||
local cmd=$1
|
||||
local brew_pkg=$2
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
if [ $IS_MACOS -eq 1 ] && [ -n "$brew_pkg" ]; then
|
||||
log_error "Required command not found: $cmd (try: brew install $brew_pkg)"
|
||||
else
|
||||
log_error "Required command not found: $cmd"
|
||||
fi
|
||||
MISSING_DEPS=1
|
||||
fi
|
||||
}
|
||||
|
||||
check_cmd flock flock
|
||||
check_cmd timeout coreutils
|
||||
check_cmd ts moreutils
|
||||
check_cmd rsync rsync
|
||||
check_cmd pgrep ""
|
||||
check_cmd pkill ""
|
||||
|
||||
if [ $MISSING_DEPS -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
gradle_run() {
|
||||
log_debug "./gradlew $*"
|
||||
mkdir -p build
|
||||
if ! $GRADLE "$@" > "$GRADLE_LOG" 2>&1; then
|
||||
log_error "Gradle command failed: $*"
|
||||
@ -80,15 +126,19 @@ gradle_run() {
|
||||
core_build() {
|
||||
log_info "Formatting code..."
|
||||
gradle_run ktlintFormat || fail
|
||||
log_info "Upgrading yarn lock..."
|
||||
gradle_run kotlinUpgradeYarnLock || fail
|
||||
log_info "Building uhabits-core..."
|
||||
gradle_run kotlinUpgradeYarnLock || fail
|
||||
gradle_run :uhabits-core:build || fail
|
||||
}
|
||||
|
||||
# Android
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
android_accept_licenses() {
|
||||
log_info "Accepting Android SDK licenses..."
|
||||
yes | run $SDKMANAGER --licenses
|
||||
}
|
||||
|
||||
android_setup() {
|
||||
API=$1
|
||||
AVDNAME=${AVD_PREFIX}${API}
|
||||
@ -101,11 +151,11 @@ android_setup() {
|
||||
done
|
||||
|
||||
log_info "Removing existing Android virtual device..."
|
||||
$AVDMANAGER delete avd --name $AVDNAME
|
||||
run $AVDMANAGER delete avd --name $AVDNAME
|
||||
|
||||
log_info "Creating new Android virtual device (API $API)..."
|
||||
(echo "y" | $SDKMANAGER --install "system-images;android-$API;google_apis;x86_64") || return 1
|
||||
$AVDMANAGER create avd \
|
||||
run $SDKMANAGER --install "system-images;android-$API;google_apis;x86_64" || return 1
|
||||
run $AVDMANAGER create avd \
|
||||
--name $AVDNAME \
|
||||
--package "system-images;android-$API;google_apis;x86_64" \
|
||||
--device "Nexus 4" || return 1
|
||||
@ -114,21 +164,22 @@ android_setup() {
|
||||
) 10>/tmp/uhabitsTest.lock
|
||||
|
||||
log_info "Launching emulator..."
|
||||
EMULATOR_LOG="build/emulator-${API}.log"
|
||||
$EMULATOR \
|
||||
-avd $AVDNAME \
|
||||
-port 6${API}0 \
|
||||
1>/dev/null 2>&1 &
|
||||
1>"$EMULATOR_LOG" 2>&1 &
|
||||
|
||||
log_info "Waiting for emulator to boot..."
|
||||
export ADB="$ADB -s emulator-6${API}0"
|
||||
timeout $BOOT_TIMEOUT $ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82'
|
||||
run timeout $BOOT_TIMEOUT $ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82'
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error "Emulator failed to boot after $BOOT_TIMEOUT seconds."
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Saving snapshot..."
|
||||
$ADB emu avd snapshot save fresh-install
|
||||
run $ADB emu avd snapshot save fresh-install
|
||||
}
|
||||
|
||||
android_boot_attempt() {
|
||||
@ -141,32 +192,33 @@ android_boot_attempt() {
|
||||
done
|
||||
|
||||
log_info "Launching emulator..."
|
||||
EMULATOR_LOG="build/emulator-${API}.log"
|
||||
$EMULATOR \
|
||||
-avd $AVDNAME \
|
||||
-port 6${API}0 \
|
||||
-snapshot fresh-install \
|
||||
-no-snapshot-save \
|
||||
-wipe-data \
|
||||
1>/dev/null 2>&1 &
|
||||
1>"$EMULATOR_LOG" 2>&1 &
|
||||
|
||||
log_info "Waiting for emulator to boot..."
|
||||
export ADB="$ADB -s emulator-6${API}0"
|
||||
sleep 5
|
||||
timeout $BOOT_TIMEOUT $ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82'
|
||||
run timeout $BOOT_TIMEOUT $ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82'
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error "Emulator failed to boot after $BOOT_TIMEOUT seconds."
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Disabling animations..."
|
||||
$ADB root || return 1
|
||||
run $ADB root || return 1
|
||||
sleep 5
|
||||
$ADB shell settings put global window_animation_scale 0 || return 1
|
||||
$ADB shell settings put global transition_animation_scale 0 || return 1
|
||||
$ADB shell settings put global animator_duration_scale 0 || return 1
|
||||
run $ADB shell settings put global window_animation_scale 0 || return 1
|
||||
run $ADB shell settings put global transition_animation_scale 0 || return 1
|
||||
run $ADB shell settings put global animator_duration_scale 0 || return 1
|
||||
|
||||
log_info "Acquiring wake lock..."
|
||||
$ADB shell 'echo android-test > /sys/power/wake_lock' || return 1
|
||||
run $ADB shell 'echo android-test > /sys/power/wake_lock' || return 1
|
||||
|
||||
}
|
||||
|
||||
@ -188,13 +240,13 @@ android_test() {
|
||||
|
||||
if [ -n "$RELEASE" ]; then
|
||||
log_info "Installing release APK..."
|
||||
$ADB install -r ${ANDROID_OUTPUTS_DIR}/apk/release/uhabits-android-release.apk || return 1
|
||||
run $ADB install -r ${ANDROID_OUTPUTS_DIR}/apk/release/uhabits-android-release.apk || return 1
|
||||
else
|
||||
log_info "Installing debug APK..."
|
||||
$ADB install -t -r ${ANDROID_OUTPUTS_DIR}/apk/debug/uhabits-android-debug.apk || return 1
|
||||
run $ADB install -t -r ${ANDROID_OUTPUTS_DIR}/apk/debug/uhabits-android-debug.apk || return 1
|
||||
fi
|
||||
log_info "Installing test APK..."
|
||||
$ADB install -r ${ANDROID_OUTPUTS_DIR}/apk/androidTest/debug/uhabits-android-debug-androidTest.apk || return 1
|
||||
run $ADB install -r ${ANDROID_OUTPUTS_DIR}/apk/androidTest/debug/uhabits-android-debug-androidTest.apk || return 1
|
||||
|
||||
for size in medium large; do
|
||||
OUT_INSTRUMENT=${ANDROID_OUTPUTS_DIR}/instrument-${API}.txt
|
||||
@ -220,8 +272,8 @@ android_test() {
|
||||
log_error "Saving logcat: $OUT_LOGCAT..."
|
||||
$ADB logcat -d > $OUT_LOGCAT
|
||||
log_error "Fetching test screenshots..."
|
||||
$ADB pull /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots ${ANDROID_OUTPUTS_DIR}/
|
||||
$ADB shell rm -r /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/
|
||||
run $ADB pull /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots ${ANDROID_OUTPUTS_DIR}/
|
||||
run $ADB shell rm -r /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
@ -258,7 +310,6 @@ android_test_parallel() {
|
||||
if [ $ret_code != 0 ]; then
|
||||
success=1
|
||||
fi
|
||||
echo pid=$pid ret_code=$ret_code success=$success
|
||||
done
|
||||
|
||||
# Print all logs
|
||||
@ -287,15 +338,15 @@ android_build() {
|
||||
log_info "Building release APK..."
|
||||
gradle_run updateTranslators
|
||||
gradle_run :uhabits-android:assembleRelease
|
||||
cp -v \
|
||||
uhabits-android/build/outputs/apk/release/uhabits-android-release.apk \
|
||||
log_info "Copying release APK..."
|
||||
cp uhabits-android/build/outputs/apk/release/uhabits-android-release.apk \
|
||||
uhabits-android/build/loop-"$VERSION"-release.apk
|
||||
fi
|
||||
|
||||
log_info "Building debug APK..."
|
||||
gradle_run :uhabits-android:assembleDebug || fail
|
||||
cp -v \
|
||||
uhabits-android/build/outputs/apk/debug/uhabits-android-debug.apk \
|
||||
log_info "Copying debug APK..."
|
||||
cp uhabits-android/build/outputs/apk/debug/uhabits-android-debug.apk \
|
||||
uhabits-android/build/loop-"$VERSION"-debug.apk
|
||||
|
||||
log_info "Building instrumentation APK..."
|
||||
@ -313,23 +364,20 @@ android_build() {
|
||||
}
|
||||
|
||||
android_accept_images() {
|
||||
find ${ANDROID_OUTPUTS_DIR}/test-screenshots -name '*.expected*' -delete
|
||||
rsync -av ${ANDROID_OUTPUTS_DIR}/test-screenshots/ uhabits-android/src/androidTest/assets/
|
||||
log_info "Accepting test screenshots..."
|
||||
run find ${ANDROID_OUTPUTS_DIR}/test-screenshots -name '*.expected*' -delete
|
||||
run rsync -av ${ANDROID_OUTPUTS_DIR}/test-screenshots/ uhabits-android/src/androidTest/assets/
|
||||
}
|
||||
|
||||
# General
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
_parse_opts() {
|
||||
if ! OPTS="$(getopt -o r --long release -n 'build.sh' -- "$@")" ; then
|
||||
exit 1;
|
||||
fi
|
||||
eval set -- "$OPTS"
|
||||
|
||||
while true; do
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-r | --release ) RELEASE=1; shift ;;
|
||||
* ) break ;;
|
||||
-r ) RELEASE=1; shift ;;
|
||||
-c ) CLEAN=1; shift ;;
|
||||
* ) shift ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
@ -340,6 +388,7 @@ CI/CD script for Loop Habit Tracker.
|
||||
|
||||
Usage:
|
||||
build.sh build [options]
|
||||
build.sh android-accept-licenses
|
||||
build.sh android-setup <API>
|
||||
build.sh android-tests <API> [options]
|
||||
build.sh android-tests-parallel <API> <API>... [options]
|
||||
@ -347,17 +396,20 @@ Usage:
|
||||
|
||||
Commands:
|
||||
build Build the app and run small tests
|
||||
android-accept-licenses Accept all Android SDK licenses
|
||||
android-setup Create Android virtual machine
|
||||
android-tests Run medium and large Android tests on an emulator
|
||||
android-tests-parallel Tests multiple API levels simultaneously
|
||||
android-accept-images Copy fetched images to corresponding assets folder
|
||||
|
||||
Options:
|
||||
-r --release Build and test release version, instead of debug
|
||||
-c Remove build folders before building
|
||||
-r Build and test release version, instead of debug
|
||||
END
|
||||
}
|
||||
|
||||
clean() {
|
||||
log_info "Cleaning build folders..."
|
||||
rm -rf uhabits-android/.gradle
|
||||
rm -rf uhabits-android/android-pickers/build
|
||||
rm -rf uhabits-android/build
|
||||
@ -379,11 +431,13 @@ main() {
|
||||
case "$1" in
|
||||
build)
|
||||
shift; _parse_opts "$@"
|
||||
clean
|
||||
log_info "Formatting code..."
|
||||
if [ -n "$CLEAN" ]; then clean; fi
|
||||
core_build
|
||||
android_build
|
||||
;;
|
||||
android-accept-licenses)
|
||||
android_accept_licenses
|
||||
;;
|
||||
android-setup)
|
||||
shift; _parse_opts "$@"
|
||||
android_setup $1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user