koopa-admin-log/scripts/taler-monitoring/android-test/run-android-variant-matrix.sh
Hernâni Marques 4296ac946c
android-test: self-build only current stable, not older releases
Milestone/older matrix slots use F-Droid APKs when still hosted; skip
if missing. Rebuild remains limited to stable-self (and master/fix).
2026-07-17 21:57:33 +02:00

323 lines
11 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Run Android wallet smoke against several build / published variants.
#
# Default order:
# 1) stable-self — rebuild STABLE_TAG (always WARN on fail)
# 2) published — current F-Droid suggested APK
# 3) older / milestones — releases near **3 / 6 / 9 / 12 months** (WARN only)
# 4) master — tip (always WARN on fail)
#
# Severity (released apps):
# Age ≤ BLOCKER_MAX_AGE_DAYS (default **14**) → **BLOCKER** on fail (FAIL_FAST)
# Age > 14 days, incl. 3/6/9/12month samples → **WARN** only
# master / stable-self → WARN
#
# Env:
# STABLE_TAG, STABLE_APK_URL, STABLE_APK_NAME
# MASTER_BRANCH, FIX_BRANCH
# VARIANTS default: stable-self,published,older,master
# INCLUDE_OLDER=1 expand token "older" / "milestones" (default 1)
# MILESTONE_DAYS default "90 180 270 365" (≈ 3,6,9,12 months)
# MILESTONE_TOLERANCE_DAYS default 50 — max distance to accept a tag
# BLOCKER_MAX_AGE_DAYS default 14
# PUBLISHED_FORCE_BLOCKER=1 always treat current published as blocker
# FAIL_FAST=1, GUI=0, STACK=…
#
set -euo pipefail
ROOT=$(cd "$(dirname "$0")" && pwd)
# shellcheck source=lib_android_env.sh
. "$ROOT/lib_android_env.sh"
# shellcheck source=lib_release_age.sh
. "$ROOT/lib_release_age.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}"
: "${VARIANTS:=stable-self,published,older,master}"
: "${INCLUDE_OLDER:=1}"
: "${MILESTONE_DAYS:=90 180 270 365}"
: "${MILESTONE_TOLERANCE_DAYS:=50}"
: "${BLOCKER_MAX_AGE_DAYS:=14}"
: "${PUBLISHED_FORCE_BLOCKER:=0}"
: "${FAIL_FAST:=1}"
: "${GUI:=0}"
: "${STACK:=auto}"
: "${TALER_ANDROID_SRC:=$HOME/taler/taler-android}"
export TALER_ANDROID_SRC BLOCKER_MAX_AGE_DAYS MILESTONE_DAYS MILESTONE_TOLERANCE_DAYS
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 BLOCKER_MAX_AGE_DAYS=$BLOCKER_MAX_AGE_DAYS" | tee -a "$SUMMARY"
echo "milestones(days)=$MILESTONE_DAYS tolerance=$MILESTONE_TOLERANCE_DAYS (always WARN)" | tee -a "$SUMMARY"
echo "out: $MATRIX_OUT" | tee -a "$SUMMARY"
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"
# --- expand VARIANTS (token "older" → concrete older-pub / older-self entries) ---
# Append one older release as WARN-only — **F-Droid APK only** (no self-build).
# Returns 0 if queued, 1 if skipped (no published APK).
append_older_warn() {
local t="$1" age="$2" target="${3:-}"
local vn meta apk_vc apk_url
vn="${t#wallet-}"
if [ -n "$target" ]; then
echo " milestone ~${target}d → $t (age=${age}d) severity=WARN" | tee -a "$SUMMARY"
else
echo " older $t (age=${age}d) severity=WARN" | tee -a "$SUMMARY"
fi
meta=$(fdroid_apk_for_version_name "$vn" 2>/dev/null || true)
if [ -n "$meta" ]; then
apk_vc="${meta%%|*}"
apk_url="${meta#*|}"
if fdroid_apk_exists "$apk_url"; then
out+=("older-pub:${vn}:${apk_vc}:warn")
return 0
fi
echo " SKIP $t — no F-Droid APK at ${apk_url:-?} (self-build only for current stable)" | tee -a "$SUMMARY"
else
echo " SKIP $t — cannot map F-Droid versionCode (self-build only for current stable)" | tee -a "$SUMMARY"
fi
return 1
}
expand_variants() {
local raw="$1"
local -a out=()
local v tag vn age sev line t target
IFS=',' read -r -a toks <<<"$raw"
for v in "${toks[@]}"; do
v=$(echo "$v" | tr -d '[:space:]')
[ -n "$v" ] || continue
if [ "$v" = "older" ] || [ "$v" = "older-releases" ] || [ "$v" = "milestones" ]; then
[ "$INCLUDE_OLDER" = "1" ] || continue
# 3/6/9/12-month samples: published APK only, always WARN.
local found=0 queued=0
while read -r t age target; do
[ -n "$t" ] || continue
[ "$t" = "$STABLE_TAG" ] && continue
found=1
if append_older_warn "$t" "$age" "$target"; then
queued=$((queued + 1))
fi
done < <(select_milestone_tags "$STABLE_TAG" 2>/dev/null || true)
if [ "$found" = "0" ]; then
echo " (no milestone tags within ±${MILESTONE_TOLERANCE_DAYS}d of $MILESTONE_DAYS)" | tee -a "$SUMMARY"
elif [ "$queued" = "0" ]; then
echo " (milestone tags found but none still on F-Droid — no older APK smokes)" | tee -a "$SUMMARY"
fi
else
out+=("$v")
fi
done
printf '%s\n' "${out[@]}"
}
mapfile -t VLIST < <(expand_variants "$VARIANTS")
echo "expanded variants: ${VLIST[*]}" | tee -a "$SUMMARY"
declare -a RESULTS=()
declare -a WARNINGS=()
overall=0
severity_for_published_current() {
if [ "${PUBLISHED_FORCE_BLOCKER}" = "1" ]; then
echo blocker
return
fi
local days
days=$(release_age_days "$STABLE_TAG" 2>/dev/null || true)
severity_from_age_days "$days"
}
run_published_apk() {
local label="$1"
local apk_url="$2"
local apk_name="$3"
local sev="$4"
local out="$MATRIX_OUT/$label"
mkdir -p "$out"
echo "" | tee -a "$SUMMARY"
echo "-------- variant: $label (F-Droid APK) [$(echo "$sev" | tr 'a-z' 'A-Z')] --------" | tee -a "$SUMMARY"
echo " url=$apk_url" | tee -a "$SUMMARY"
local smoke="$ROOT/run-android-pay-smoke.sh"
[ "$GUI" = "1" ] && smoke="$ROOT/run-android-gui-smoke.sh"
local strict=1
[ "$sev" = "warn" ] && strict="${SMOKE_STRICT_WARN:-0}"
[ "$sev" = "blocker" ] && strict="${SMOKE_STRICT:-1}"
set +e
env STACK="$STACK" \
APK_URL="$apk_url" \
APK_NAME="$apk_name" \
APK_PATH="" \
PKG=net.taler.wallet.fdroid \
OUT_DIR="$out" \
SERIAL="$SERIAL" \
AUTO_START_EMULATOR=0 \
SMOKE_STRICT="$strict" \
"$smoke"
local rc=$?
set -e
echo "$label exit=$rc severity=$sev" | tee -a "$SUMMARY"
echo "$label $rc $sev $apk_url" >>"$MATRIX_OUT/results.tsv"
return "$rc"
}
run_selfbuild() {
local label="$1"
local ref="$2"
local sev="${3:-warn}"
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"
local strict="${SMOKE_STRICT:-1}"
[ "$sev" = "warn" ] && strict="${SMOKE_STRICT_SELF:-0}"
[ "$sev" = "blocker" ] && strict="${SMOKE_STRICT:-1}"
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" \
TALER_ANDROID_SRC="$TALER_ANDROID_SRC" \
"$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"
}
record_result() {
local v="$1" rc="$2" sev="$3"
if [ "$rc" -eq 0 ]; then
RESULTS+=("$v:OK($sev)")
return
fi
case "$sev" in
warn)
echo "WARN: $v failed rc=$rc — not a blocker; continuing" | tee -a "$SUMMARY"
WARNINGS+=("$v:$rc")
RESULTS+=("$v:WARN($rc)")
;;
blocker)
echo "BLOCKER: $v failed rc=$rc (release within ${BLOCKER_MAX_AGE_DAYS}d window)" | tee -a "$SUMMARY"
RESULTS+=("$v:BLOCKER($rc)")
overall=1
if [ "$FAIL_FAST" = "1" ]; then
echo "FAIL_FAST: stopping after blocker $v" | tee -a "$SUMMARY"
return 2
fi
;;
soft)
echo "FAIL: $v rc=$rc" | tee -a "$SUMMARY"
RESULTS+=("$v:FAIL($rc)")
overall=1
if [ "$FAIL_FAST" = "1" ]; then
echo "FAIL_FAST: stopping after $v" | tee -a "$SUMMARY"
return 2
fi
;;
esac
return 0
}
for raw in "${VLIST[@]}"; do
v=$(echo "$raw" | tr -d '[:space:]')
[ -n "$v" ] || continue
rc=0
sev=warn
stop=0
case "$v" in
published|fdroid|stable-published)
sev=$(severity_for_published_current)
age=$(release_age_days "$STABLE_TAG" 2>/dev/null || echo "?")
echo "published current: tag=$STABLE_TAG age_days=$age → severity=$sev" | tee -a "$SUMMARY"
run_published_apk "published" "$STABLE_APK_URL" "$STABLE_APK_NAME" "$sev" || rc=$?
;;
stable-self|stable|self-stable|release-self)
# rebuild of stable: always warn (toolchain), age does not make self-build a blocker
sev=warn
run_selfbuild "stable-self" "$STABLE_TAG" warn || rc=$?
;;
master|main)
sev=warn
run_selfbuild "master" "$MASTER_BRANCH" warn || rc=$?
;;
fix|fix-branch|inference)
sev=soft
run_selfbuild "fix" "$FIX_BRANCH" soft || rc=$?
;;
older-pub:*)
# older-pub:VERSION:VC:SEV
IFS=':' read -r _ vn apk_vc sev <<<"$v"
: "${sev:=warn}"
label="older-pub-${vn}"
url="https://f-droid.org/repo/net.taler.wallet.fdroid_${apk_vc}.apk"
name="net.taler.wallet.fdroid_${apk_vc}.apk"
age=$(release_age_days "wallet-${vn}" 2>/dev/null || echo "?")
echo "older published $vn age_days=$age severity=$sev" | tee -a "$SUMMARY"
run_published_apk "$label" "$url" "$name" "$sev" || rc=$?
v="$label"
;;
older-self:*)
# Explicit older-self is disabled by policy (self-build = current stable only).
echo "SKIP $v — self-build only for current stable ($STABLE_TAG); use older-pub or published" | tee -a "$SUMMARY"
RESULTS+=("$v:SKIP(no-selfbuild-older)")
continue
;;
*)
# raw git ref: only master-like / fix via named tokens; bare wallet-* tags → no self-build
if [[ "$v" =~ ^wallet-[0-9] ]]; then
echo "SKIP self-build $v — only current stable self-build ($STABLE_TAG) is enabled" | tee -a "$SUMMARY"
RESULTS+=("$v:SKIP(no-selfbuild-older)")
continue
fi
sev=warn
run_selfbuild "ref-${v//\//-}" "$v" warn || rc=$?
;;
esac
record_result "$v" "$rc" "$sev" || stop=$?
[ "$stop" = "2" ] && break
done
echo "" | tee -a "$SUMMARY"
echo "=== matrix done (overall=$overall) ===" | tee -a "$SUMMARY"
echo "rule: age ≤ ${BLOCKER_MAX_AGE_DAYS}d → BLOCKER; 3/6/9/12mo milestones + older → WARN only" | 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 "Artifacts: $MATRIX_OUT"
exit "$overall"