Retry a failed upload instead of losing the release
Publishing 1.2.0 put the first package up and then failed the second with "invalid username, password or token" — the same token, seconds later, and the identical command succeeded on the next run. A flake at 118 MB should not cost a rebuild, so each upload gets up to three attempts, and the attachment already on the release is dropped before every attempt so a retry cannot leave two copies. The shipped bundle was checked rather than assumed: unpacked from the release zip, `codesign --verify --deep --strict` is valid on disk and satisfies its designated requirement, and the app drives the real store — ten cards, the menu populated, the categories counted. With the quarantine flag set it is killed on launch (exit 137), which is the ad-hoc-signing limitation the README already documents. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,16 @@ Release notes come from `RELEASE_NOTES.md` when the file is present, otherwise t
|
||||
release gets a one-line note. The repository is read from `origin`, so a fork
|
||||
publishes to the fork.
|
||||
|
||||
Each upload is retried up to three times, and the existing attachment is dropped
|
||||
before every attempt so a retry cannot leave two copies. A 100 MB upload does fail
|
||||
on its own: publishing 1.2.0 got *"invalid username, password or token"* on the
|
||||
second package while the first had just gone up with the same token, and the same
|
||||
command succeeded immediately afterwards.
|
||||
|
||||
Package names contain a space — `WarpEngine Store-1.2.0-arm64.dmg` — so the list of
|
||||
files is passed one path per line rather than as one string; splitting it on
|
||||
whitespace is what broke the first attempt at publishing 1.1.0.
|
||||
|
||||
It needs `tea` installed and logged in — the devarea repo has `make tea` for that.
|
||||
Overridable: `TAG`, `REPO`, `TEA_LOGIN`, `NOTES`, `DIST`.
|
||||
|
||||
|
||||
+28
-11
@@ -99,27 +99,44 @@ RELEASE_ID="$(release_id)"
|
||||
[ -n "$RELEASE_ID" ] || die "the release $TAG could not be created or found"
|
||||
|
||||
# --- the attachments -------------------------------------------------------
|
||||
while IFS= read -r asset; do
|
||||
[ -n "$asset" ] || continue
|
||||
[ -f "$asset" ] || die "no such file: $asset"
|
||||
name="$(basename "$asset")"
|
||||
|
||||
# Replacing rather than refusing: a second run after a rebuild should land.
|
||||
old="$(tea api "/repos/$REPO/releases/$RELEASE_ID/assets" | python3 -c "
|
||||
# Anything already attached under this name, dropped: replacing rather than
|
||||
# refusing is what makes a rebuild-and-upload repeatable. Called before every
|
||||
# attempt, so a retry cannot leave two copies behind.
|
||||
drop_existing() {
|
||||
ids="$(tea api "/repos/$REPO/releases/$RELEASE_ID/assets" | python3 -c "
|
||||
import json, sys
|
||||
name = sys.argv[1]
|
||||
for a in json.load(sys.stdin):
|
||||
if a['name'] == name:
|
||||
print(a['id'])
|
||||
" "$name")"
|
||||
for id in $old; do
|
||||
say "replacing $name"
|
||||
" "$1")"
|
||||
for id in $ids; do
|
||||
say "replacing $1"
|
||||
tea api -X DELETE "/repos/$REPO/releases/$RELEASE_ID/assets/$id" >/dev/null
|
||||
done
|
||||
}
|
||||
|
||||
while IFS= read -r asset; do
|
||||
[ -n "$asset" ] || continue
|
||||
[ -f "$asset" ] || die "no such file: $asset"
|
||||
name="$(basename "$asset")"
|
||||
size="$(python3 -c "import os,sys; print(f'{os.path.getsize(sys.argv[1])/1e6:.0f} MB')" "$asset")"
|
||||
|
||||
# Retried, because a 100 MB upload does fail on its own: publishing 1.2.0 got
|
||||
# "invalid username, password or token" on the second package while the first
|
||||
# had just gone up with the same token, and the identical command succeeded on
|
||||
# the next run. One flake should not cost a rebuild.
|
||||
attempt=1
|
||||
while :; do
|
||||
drop_existing "$name"
|
||||
say "uploading $name ($size) — large packages take a few minutes"
|
||||
tea releases assets create --login "$LOGIN" --repo "$REPO" "$TAG" "$asset" >/dev/null
|
||||
if tea releases assets create --login "$LOGIN" --repo "$REPO" "$TAG" "$asset" >/dev/null; then
|
||||
break
|
||||
fi
|
||||
[ "$attempt" -lt 3 ] || die "$name could not be uploaded after $attempt attempts"
|
||||
attempt=$((attempt + 1))
|
||||
say "that failed — attempt $attempt of 3"
|
||||
done
|
||||
done < "$LIST"
|
||||
|
||||
say "done:"
|
||||
|
||||
Reference in New Issue
Block a user