Files
flamenet-messenger-android/scripts/release-manifest.sh
T
Paul HittandClaude Fable 5.1 4dd544083c Remove machine-writing tells from comments and docs
Emoji markers, markdown bold inside code comments, and em-dashes are
gone from source comments, string literals, scripts, Gradle files and
the markdown docs. Counted before and after:

  emoji markers   2680 -> 1 (the emoji picker's own list, which is the feature)
  em-dashes       2490 -> 9 (table placeholders and fenced code)

Two warning glyphs in user-facing strings in ChatScreens.kt are removed
as well; the sentences say the same thing without them. Two backtick
test names carried an em-dash and now carry a comma.

Nothing else changed. 1208 tests pass, counted from the result XML.
The three obfs4 interop tests are opted out with OBFS4_INTEROP_OPTOUT=1
for this run, as their own message instructs when no bridge is set up.

CONTRIBUTING gets a four-line rule so it does not grow back.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 18:52:12 -04:00

109 lines
4.3 KiB
Bash
Executable File

#!/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 <apk> [notes] > android-latest.json
set -euo pipefail
apk="${1:?usage: release-manifest.sh <apk> [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 <<MSG
No release-notes checker at:
$checker
That file lives in the flamenet-relay repository, which serves the /releases
page. Point FN_RELAY_DIR at your checkout of it, or set
FN_SKIP_RELEASE_NOTES=1 to publish $name with no notes.
MSG
exit 1
fi
if ! python3 "$checker" "$name"; then
cat >&2 <<MSG
Nothing on the /releases page mentions Android $name, so this build would ship
without a word to anyone about what changed in it.
Add a release to:
$relay_dir/Resources/releases.json
The newest release goes FIRST in the list, and it looks like this, write the
notes for somebody holding a phone, and put anything only an operator cares
about in "selfHosting" at the end:
{
"date": "$(date +%Y-%m-%d)",
"platforms": [{ "name": "android", "version": "$name" }],
"headline": "One sentence, or leave it out.",
"changes": [
{ "kind": "fixed", "text": "What a person will notice, in their words." }
]
}
"kind" is "new", "changed" or "fixed". Add an { "name": "ios", "version": … }
or { "name": "relay" } entry alongside it when the same release touched those
too, one release, every platform it landed on.
Then deploy the relay so the page and the APK go out together.
MSG
exit 1
fi
fi
sha="$(shasum -a 256 "$apk" | cut -d' ' -f1)"
# No `url` field, deliberately. The client builds the download URL from the
# relay it is signed in to and ignores anything the manifest says about where
# the APK lives, a relay that could name the host could hand its users a
# different app. Adding one here would be dead weight at best and a trap for
# the next person to implement a client at worst.
cat <<JSON
{
"versionCode": $code,
"versionName": "$name",
"sha256": "$sha",
"notes": $(python3 -c 'import json,sys; print(json.dumps(sys.argv[1]))' "$notes")
}
JSON