Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/notarize-poll-retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@smooai/smooth': patch
---

Notarization no longer throws away a good submission when the status poll blips. `notarize-and-staple.sh` used `notarytool submit --wait`, which collapses "upload the artifact" and "poll until Apple finishes" into one call — so a transient network error during the poll fails the release while Apple is still happily processing the submission. That is exactly how the first SmoothFlow 0.2.3 publish died: the upload succeeded, the status request timed out (`NSURLErrorDomain -1001`), and a ~20-minute signed build was discarded holding a valid submission id. It now submits once, captures the id, and retries the **wait** against that id rather than resubmitting, then checks `notarytool info` for `Accepted` — because `wait` returning successfully means Apple finished, not that it approved — and dumps the notary log on rejection. This matters more since th-9c3f4e: stapling the app as well as the DMG means two notarization round-trips per release, so twice the exposure to this flake.
32 changes: 31 additions & 1 deletion scripts/macos/notarize-and-staple.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,37 @@ for ARTIFACT in "$@"; do
fi

say "Notarizing $(basename "$ARTIFACT")"
xcrun notarytool submit "$SUBMIT" "${CREDS[@]}" --wait >&2
# Deliberately NOT `submit --wait`. That collapses "upload" and "poll for
# the result" into one call, so a network blip during the poll fails the
# whole step and throws away a submission Apple is already processing —
# which is exactly what happened on the first 0.2.3 attempt: the upload
# succeeded, the status poll timed out (NSURLErrorDomain -1001), and the
# release died holding a perfectly good submission id. Submit once, then
# retry the WAIT against that id. Never resubmit on a poll failure.
SUBMIT_OUT="$(xcrun notarytool submit "$SUBMIT" "${CREDS[@]}" 2>&1)" || { printf '%s\n' "$SUBMIT_OUT" >&2; exit 1; }
printf '%s\n' "$SUBMIT_OUT" >&2
SUB_ID="$(printf '%s\n' "$SUBMIT_OUT" | awk '/^ *id: /{print $2; exit}')"
[ -n "$SUB_ID" ] || { echo "error: could not parse a submission id from notarytool" >&2; exit 1; }

WAITED=0
for attempt in 1 2 3 4 5; do
if xcrun notarytool wait "$SUB_ID" "${CREDS[@]}" --timeout 30m >&2; then
WAITED=1
break
fi
echo "notarytool wait failed (attempt $attempt/5) — the submission is still queued at Apple; retrying" >&2
sleep 30
done
[ "$WAITED" = 1 ] || { echo "error: gave up waiting on submission $SUB_ID" >&2; exit 1; }

# `wait` returning 0 means Apple finished, not that it approved.
STATUS="$(xcrun notarytool info "$SUB_ID" "${CREDS[@]}" 2>&1 | awk '/^ *status: /{sub(/^ *status: */,""); print; exit}')"
echo "notarization status: ${STATUS:-unknown}" >&2
if [ "$STATUS" != "Accepted" ]; then
echo "error: notarization was not accepted (status: ${STATUS:-unknown}); log follows" >&2
xcrun notarytool log "$SUB_ID" "${CREDS[@]}" >&2 || true
exit 1
fi

# Staple the ORIGINAL (the ticket belongs on the .app/.dmg, not the zip).
say "Stapling $(basename "$ARTIFACT")"
Expand Down
Loading