eleven / messenger Public

deploy: pin the releases repo's 'latest' pointer to the Mac app — server releases stop stealing it (#939)

Sparkle's SUFeedURL is releases/latest/download/appcast.xml, baked into every
installed Mac app. GitHub hands 'latest' to the newest plain release, so each
per-sha server publish (the supply-chain-defense flow) silently repointed it —
the appcast fetch has been 404ing on every Mac since, discovered while minting
0.7.0. Server releases now create with --latest=false; the Mac release claims
--latest explicitly.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 19c5a313216b7da2a51c9f6bd29e2953c60b5e2c parent 1559c14
2 files changed, +12 −3
  • deploy/release-server.sh +7 −2
  • ios/release-mac.sh +5 −1
diff --git a/deploy/release-server.sh b/deploy/release-server.sh
index 842caa5..eadeb26 100755
--- a/deploy/release-server.sh
+++ b/deploy/release-server.sh
@@ -90,7 +90,7 @@ mirror_upload() {
sign_and_upload() {
"$TOOL" release sign --key "$KEY" --in "$1" --out "$TMP/manifest.json"
gh release view server -R "$REPO" >/dev/null 2>&1 || \
- gh release create server -R "$REPO" --title "Server release feed" \
+ gh release create server -R "$REPO" --title "Server release feed" --latest=false \
--notes "Rolling release: manifest.json is the channel feed instances update from. See the messenger repo's docs/server-releases.md."
gh release upload server "$TMP/manifest.json" -R "$REPO" --clobber
"$TOOL" release verify --in "$TMP/manifest.json"
@@ -119,7 +119,12 @@ publish)
if gh release view "server-$VER" -R "$REPO" >/dev/null 2>&1; then
echo "release-server: server-$VER already exists on $REPO (promote it, or land a new commit)" >&2; exit 1
fi
- gh release create "server-$VER" -R "$REPO" --title "Server $VER" --notes "$NOTES" \
+ # --latest=false: the repo's "latest" pointer belongs to the MAC app —
+ # Sparkle's baked-in SUFeedURL is releases/latest/download/appcast.xml, and
+ # GitHub hands "latest" to the newest plain release by default, so every
+ # server publish was silently 404ing every Mac's update check (found
+ # 2026-07-14: the feed pointed at server-414bdeb0, no appcast there).
+ gh release create "server-$VER" -R "$REPO" --title "Server $VER" --notes "$NOTES" --latest=false \
"$TMP/$BIN" "$TMP/$BIN.sha256" "$TMP/$BIN_ARM" "$TMP/$BIN_ARM.sha256"
# Binaries mirror before the manifest that points at them, so the mirror
# never serves a feed whose mirror-side binaries don't exist yet. Keys copy
diff --git a/ios/release-mac.sh b/ios/release-mac.sh
index 8d14f5b..2d60cb6 100755
--- a/ios/release-mac.sh
+++ b/ios/release-mac.sh
@@ -153,8 +153,12 @@ fi
NOTES_ARG=(--notes "$APP_NAME $VERSION for macOS.")
[ -n "$NOTES_MD" ] && NOTES_ARG=(--notes-file "$NOTES_MD")
+# --latest (explicit): Sparkle's SUFeedURL is releases/latest/download/
+# appcast.xml, so the Mac release must always hold the repo's "latest"
+# pointer — server releases publish with --latest=false for the same reason
+# (release-server.sh; the pointer theft 404'd every Mac's update check).
gh release create "v$VERSION" -R "$RELEASES_REPO" \
- --title "$APP_NAME $VERSION" "${NOTES_ARG[@]}" \
+ --title "$APP_NAME $VERSION" "${NOTES_ARG[@]}" --latest \
"$APPCAST_DIR/$APP_NAME-$VERSION.dmg" "$APPCAST_DIR/appcast.xml"
echo