#!/usr/bin/env bash # Run Android wallet smoke against **several build variants** so a single # "weird" developer tree or a bad local build cannot be the only sample. # # Default matrix order: # 1) **stable-self** — rebuild release **tag** (same source as published) # Failure → **WARN only** (not a hard blocker; continue matrix) # 2) **published** — F-Droid stable APK (what users install) # Failure → **BLOCKER** (matrix exit ≠ 0; FAIL_FAST stops here) # 3) **master** — rebuild origin/master # Failure → **WARN only** (tip breakage / ANR must not block stable gate) # # Why self-builds in addition to published? # Isolates "our toolchain rebuild" vs "F-Droid binary". Rebuild issues # (signing flavor, dirty host, low-RAM ANR on debug) must not block the # published-stable gate — hence warn-only for stable-self **and** master. # # Usage: # ./run-android-variant-matrix.sh # STACK=goa ./run-android-variant-matrix.sh # VARIANTS=master,stable-self ./run-android-variant-matrix.sh # STABLE_TAG=wallet-1.6.1 MASTER_BRANCH=master ./run-android-variant-matrix.sh # # Env: # STABLE_TAG default wallet-1.6.1 (must match published F-Droid release) # STABLE_APK_URL published APK (same as pay-smoke default) # MASTER_BRANCH default master # FIX_BRANCH inference fix branch (variant "fix") # VARIANTS comma list: published,stable-self,master,fix # GUI=1 use gui-smoke instead of pay-smoke after each build # FAIL_FAST=1 stop on first **blocker** failure (default 1) # MATRIX_OUT summary dir (default out-matrix-) # set -euo pipefail ROOT=$(cd "$(dirname "$0")" && pwd) # shellcheck source=lib_android_env.sh . "$ROOT/lib_android_env.sh" : "${STABLE_TAG:=wallet-1.6.1}" : "${STABLE_APK_URL:=https://f-droid.org/repo/net.taler.wallet.fdroid_854.apk}" : "${STABLE_APK_NAME:=net.taler.wallet.fdroid_854.apk}" : "${MASTER_BRANCH:=master}" : "${FIX_BRANCH:=dev/hernani-inference/fix-bank-withdraw-auto-exchange}" # Order: stable-self (warn) → published (blocker) → master. : "${VARIANTS:=stable-self,published,master}" : "${FAIL_FAST:=1}" : "${GUI:=0}" : "${STACK:=auto}" TS=$(date +%Y%m%d-%H%M%S) MATRIX_OUT="${MATRIX_OUT:-$ROOT/out-matrix-$TS}" mkdir -p "$MATRIX_OUT" SUMMARY="$MATRIX_OUT/SUMMARY.txt" : >"$SUMMARY" echo "=== Android variant matrix ===" | tee -a "$SUMMARY" echo "STACK=$STACK GUI=$GUI headless=${EMULATOR_HEADLESS} variants=$VARIANTS" | tee -a "$SUMMARY" echo "STABLE_TAG=$STABLE_TAG MASTER_BRANCH=$MASTER_BRANCH" | tee -a "$SUMMARY" echo "severity: stable-self=WARN published=BLOCKER master=WARN" | tee -a "$SUMMARY" echo "out: $MATRIX_OUT" | tee -a "$SUMMARY" # Ensure device once (headless AVD by default) android_ensure_device || { echo "no adb device — start ./start-android-emulator.sh --wait" >&2 exit 3 } export SERIAL ANDROID_SERIAL echo "device: $SERIAL" | tee -a "$SUMMARY" IFS=',' read -r -a VLIST <<<"$VARIANTS" declare -a RESULTS=() declare -a WARNINGS=() overall=0 # Severity: warn | blocker | soft # warn — log WARN, never FAIL_FAST, never overall≠0 # blocker — FAIL_FAST eligible; overall≠0 # soft — overall≠0 on fail, but FAIL_FAST only if FAIL_FAST=1 and not warn variant_severity() { case "$1" in stable-self|stable|self-stable|release-self) echo warn ;; master|main) echo warn ;; published|fdroid|stable-published) echo blocker ;; # optional fix branch etc.: soft fail (counts) unless overridden *) echo soft ;; esac } run_published() { local out="$MATRIX_OUT/published" mkdir -p "$out" echo "" | tee -a "$SUMMARY" echo "-------- variant: published (F-Droid stable binary) [BLOCKER] --------" | tee -a "$SUMMARY" local smoke="$ROOT/run-android-pay-smoke.sh" [ "$GUI" = "1" ] && smoke="$ROOT/run-android-gui-smoke.sh" set +e env STACK="$STACK" \ APK_URL="$STABLE_APK_URL" \ APK_NAME="$STABLE_APK_NAME" \ APK_PATH="" \ PKG=net.taler.wallet.fdroid \ OUT_DIR="$out" \ SERIAL="$SERIAL" \ AUTO_START_EMULATOR=0 \ SMOKE_STRICT="${SMOKE_STRICT:-1}" \ "$smoke" local rc=$? set -e echo "published exit=$rc" | tee -a "$SUMMARY" echo "published $rc blocker" >>"$MATRIX_OUT/results.tsv" return "$rc" } run_selfbuild() { local label="$1" local ref="$2" local sev="${3:-soft}" local out="$MATRIX_OUT/$label" mkdir -p "$out" echo "" | tee -a "$SUMMARY" echo "-------- variant: $label (self-build ref=$ref) [$(echo "$sev" | tr 'a-z' 'A-Z')] --------" | tee -a "$SUMMARY" # Warn-only self-build: still collect evidence; SMOKE_STRICT optional (default off for warn) local strict="${SMOKE_STRICT:-1}" if [ "$sev" = "warn" ]; then strict="${SMOKE_STRICT_SELF:-0}" fi set +e env STACK="$STACK" \ BRANCH="$ref" \ LABEL="$label" \ GUI="$GUI" \ OUT_DIR="$out" \ SERIAL="$SERIAL" \ ANDROID_SERIAL="$SERIAL" \ AUTO_START_EMULATOR=0 \ PKG=net.taler.wallet.fdroid.debug \ SMOKE_STRICT="$strict" \ "$ROOT/run-android-build-and-smoke.sh" local rc=$? set -e echo "$label (ref=$ref) exit=$rc severity=$sev" | tee -a "$SUMMARY" echo "$label $rc $ref $sev" >>"$MATRIX_OUT/results.tsv" if [ -f "$out/build-meta.txt" ]; then echo "build-meta:" | tee -a "$SUMMARY" cat "$out/build-meta.txt" | tee -a "$SUMMARY" fi return "$rc" } for raw in "${VLIST[@]}"; do v=$(echo "$raw" | tr -d '[:space:]') [ -n "$v" ] || continue rc=0 sev=$(variant_severity "$v") case "$v" in published|fdroid|stable-published) run_published || rc=$? ;; stable-self|stable|self-stable|release-self) run_selfbuild "stable-self" "$STABLE_TAG" warn || rc=$? ;; master|main) run_selfbuild "master" "$MASTER_BRANCH" warn || rc=$? ;; fix|fix-branch|inference) run_selfbuild "fix" "$FIX_BRANCH" soft || rc=$? ;; *) run_selfbuild "ref-${v//\//-}" "$v" soft || rc=$? ;; esac if [ "$rc" -ne 0 ]; then case "$sev" in warn) echo "WARN: variant $v failed rc=$rc — self-build, NOT a blocker; continuing" | tee -a "$SUMMARY" WARNINGS+=("$v:$rc") RESULTS+=("$v:WARN($rc)") # do not set overall; do not FAIL_FAST ;; blocker) echo "BLOCKER: variant $v failed rc=$rc" | tee -a "$SUMMARY" RESULTS+=("$v:BLOCKER($rc)") overall=1 if [ "$FAIL_FAST" = "1" ]; then echo "FAIL_FAST: stopping after blocker $v" | tee -a "$SUMMARY" break fi ;; soft) echo "FAIL: variant $v rc=$rc (counts toward overall)" | tee -a "$SUMMARY" RESULTS+=("$v:FAIL($rc)") overall=1 if [ "$FAIL_FAST" = "1" ]; then echo "FAIL_FAST: stopping after $v rc=$rc" | tee -a "$SUMMARY" break fi ;; esac else RESULTS+=("$v:OK") fi done echo "" | tee -a "$SUMMARY" echo "=== matrix done (overall=$overall) ===" | tee -a "$SUMMARY" for r in "${RESULTS[@]}"; do echo " $r" | tee -a "$SUMMARY" done if [ "${#WARNINGS[@]}" -gt 0 ]; then echo "warnings (non-blocking):" | tee -a "$SUMMARY" for w in "${WARNINGS[@]}"; do echo " WARN $w" | tee -a "$SUMMARY" done fi echo "" echo "Compare OUT_DIR trees under $MATRIX_OUT" echo "stable-self / master failure = WARN only; published failure = BLOCKER." exit "$overall"