packaging: the rolling-release prune was eating the Android client
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m21s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m18s
Desktop (Tauri) / Update manifest (push) Successful in 4s

Run 4092 published `thoughtsync.apk` to the `dev` release. Run 4098 removed it,
four minutes later, and both runs were green.

`write-manifest.sh` prunes the rolling channel to stop ~100 MB AppImages
accumulating forever, keeping `latest.json` and anything whose name contains the
current `$APP_VERSION`. The Android assets deliberately have no version in their
names — a fixed name is the only addressable URL on a tag that never moves,
which is the entire reason the `dev` release exists — so they matched neither
rule and were swept.

They would have been swept even if they HAD carried a version: Android is a
different workflow with its own run number, so its version never equals the
desktop's `$APP_VERSION` in this script.

The keep-list is now about fixed names rather than about `latest.json`
specifically, which is what the rule always meant. A fixed-name asset is
self-limiting — each publish replaces the same name — so the accumulation this
prune exists to prevent cannot happen to one.

Worth noting how this presented: two green runs and a missing file. Nothing
failed, and the only way to see it was to ask the release what it actually held
rather than trusting that a step named "Publish" had published.
This commit is contained in:
2026-08-20 20:31:03 -04:00
parent e6da720e6b
commit 43ebb6eceb
+14 -2
View File
@@ -168,9 +168,21 @@ if [ "${PRUNE_OLD_ASSETS:-false}" = "true" ]; then
| while IFS= read -r row; do
asset_id="$(printf '%s' "$row" | grep -oE '[0-9]+' | head -1)"
asset_name="$(printf '%s' "$row" | sed -E 's/.*"name"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')"
# Keep the manifest itself and everything belonging to the current build.
# Keep FIXED-NAME assets and everything belonging to the current build.
#
# A fixed name is self-limiting: each publish replaces that same name, so
# it cannot accumulate and the reason this prune exists does not apply to
# it. It is also the only kind of URL that stays addressable on a rolling
# tag, which is the whole point of having one — deleting it breaks
# whatever was pointing at it.
#
# The Android client is on that list for a second reason too: it is built
# by a DIFFERENT workflow with its own run number, so its version never
# matches $APP_VERSION here and a version-stamped name would be pruned on
# every desktop push regardless. That is exactly what happened on run
# 4098, which swept the APK run 4092 had just published.
case "$asset_name" in
latest.json) continue ;;
latest.json|thoughtsync.apk|thoughtsync-android.json) continue ;;
*"$APP_VERSION"*) continue ;;
esac
echo " removing $asset_name"