From 6733228c5254a89a59a18cfbcccfca2fa123c462 Mon Sep 17 00:00:00 2001 From: Tomaz Zaman Date: Tue, 18 Aug 2026 12:59:51 +0200 Subject: [PATCH 73/77] mono-publish-release: land images before flipping latest.json Publishing rsynced the release dir and latest.json(+.sig) in a single rsync, so the live manifest could advertise a release before its images finished landing - a device polling in that window would fetch an image that 404s or fails its sha256 check. Split into two phases: rsync the release dir to completion first, then rsync latest.json(+.sig). rsync renames each file into place atomically, so the manifest swap is atomic and only happens once the images it points at are present. Co-Authored-By: Claude Opus 4.8 --- scripts/mono-publish-release.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/mono-publish-release.sh b/scripts/mono-publish-release.sh index 07fb2b8470..67b2b4ea4c 100755 --- a/scripts/mono-publish-release.sh +++ b/scripts/mono-publish-release.sh @@ -50,7 +50,12 @@ json_tag=$(sed -n 's/.*"tag": *"\([^"]*\)".*/\1/p' releases/latest.json | head - if [ -n "${MONO_PUBLISH_DEST:-}" ]; then echo "mono-publish: publishing to $MONO_PUBLISH_DEST" - rsync -a "$OUT" releases/latest.json releases/latest.json.sig "$MONO_PUBLISH_DEST/" + # Two-phase publish so the live manifest never points at images that have + # not landed yet: rsync the release dir to COMPLETION first, then flip + # latest.json(+.sig) in a separate step. rsync renames each file into + # place atomically, so the manifest swap itself is atomic too. + rsync -a "$OUT" "$MONO_PUBLISH_DEST/" + rsync -a releases/latest.json releases/latest.json.sig "$MONO_PUBLISH_DEST/" else echo "mono-publish: MONO_PUBLISH_DEST unset, nothing rsynced" >&2 fi -- 2.47.3