#!/usr/bin/env bash # Write the update manifest for a built APK. # # 🔴 The version in the manifest is read back OUT of the APK, never typed. A # manifest that claims a version the APK is not is worse than no manifest: it # either offers an update that installs as the same build (and so appears to do # nothing), or fails to offer one that exists. Reading it from the artifact is # what makes the two incapable of disagreeing. # # Usage: scripts/release-manifest.sh [notes] > android-latest.json set -euo pipefail apk="${1:?usage: release-manifest.sh [notes]}" notes="${2:-}" [ -f "$apk" ] || { echo "no such APK: $apk" >&2; exit 1; } # aapt2 ships with the build tools; find the newest one rather than pinning a # version that will be wrong on the next machine. sdk="${ANDROID_HOME:-$HOME/Library/Android/sdk}" aapt2="$(find "$sdk/build-tools" -maxdepth 2 -name aapt2 -type f 2>/dev/null | sort -V | tail -1)" [ -n "$aapt2" ] || { echo "aapt2 not found under $sdk/build-tools" >&2; exit 1; } badging="$("$aapt2" dump badging "$apk")" code="$(sed -n "s/.*versionCode='\([0-9]*\)'.*/\1/p" <<<"$badging" | head -1)" name="$(sed -n "s/.*versionName='\([^']*\)'.*/\1/p" <<<"$badging" | head -1)" [ -n "$code" ] && [ -n "$name" ] || { echo "could not read version from $apk" >&2; exit 1; } # --------------------------------------------------------------------------- # 🔴 **A build does not ship without its release notes.** # # The gate lives here, on the manifest, because the manifest is the step that # cannot be skipped — it is what the in-app updater reads, so an APK published # without it offers nobody an update. A reminder in a checklist would be # skipped on exactly the busy evening the notes matter most. # # ⚠️ It matches on `versionName` read out of the APK above, never on a number # typed here, for the same reason the manifest does: the two cannot disagree. # # The changelog lives in the relay repository because that is what serves the # page, and the check lives THERE too — see Scripts/covers-android.py. Parsing # the JSON here would leave a second copy of the schema to drift. if [ "${FN_SKIP_RELEASE_NOTES:-}" = "1" ]; then # Loud, and on stderr: a skipped gate that printed nothing would be a gate # nobody remembered turning off. echo "⚠️ FN_SKIP_RELEASE_NOTES=1 — writing a manifest for $name with no" >&2 echo " release notes. Nothing on /releases will mention this build." >&2 else relay_dir="${FN_RELAY_DIR:-$(cd "$(dirname "$0")/../.." && pwd)/flamenet-relay}" checker="$relay_dir/Scripts/covers-android.py" if [ ! -f "$checker" ]; then cat >&2 <&2 <