koopa-admin-log/scripts/taler-monitoring/android-test/run-android-variant-matrix.sh
Hernâni Marques e359cf79c2
android-test: sample 3/6/9/12-month wallet tags as WARN only
Pick nearest release tags to 90/180/270/365 days for the older matrix
slot; failures there never hard-block (only ≤14d releases can).
2026-07-17 21:57:01 +02:00

320 lines
10 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 (pub APK if possible, else self-build).
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
fi
echo " (no F-Droid APK for $vn — self-build only)" | tee -a "$SUMMARY"
fi
out+=("older-self:${t}:warn")
}
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
# Prefer 3/6/9/12-month samples (always WARN). Fall back: nothing if no tags nearby.
local found=0
while read -r t age target; do
[ -n "$t" ] || continue
[ "$t" = "$STABLE_TAG" ] && continue
append_older_warn "$t" "$age" "$target"
found=1
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"
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:*)
# older-self:TAG:SEV or older-self:TAG
IFS=':' read -r _ tag sev <<<"$v"
: "${sev:=$(severity_for_tag "$tag")}"
label="older-self-${tag}"
age=$(release_age_days "$tag" 2>/dev/null || echo "?")
echo "older self-build $tag age_days=$age severity=$sev" | tee -a "$SUMMARY"
run_selfbuild "$label" "$tag" "$sev" || rc=$?
v="$label"
;;
*)
# raw git ref — warn unless looks like wallet-X.Y and young
if [[ "$v" =~ ^wallet-[0-9] ]]; then
sev=$(severity_for_tag "$v")
run_selfbuild "ref-${v}" "$v" "$sev" || rc=$?
else
sev=warn
run_selfbuild "ref-${v//\//-}" "$v" warn || rc=$?
fi
;;
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"