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>
109 lines
4.3 KiB
Bash
Executable File
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
|