Skip to content

Commit 3d117c9

Browse files
committed
fix: improve notarization with manual polling and 60min timeout
- Submit without --wait flag to avoid built-in timeout issues - Poll status every 30 seconds with custom retry logic - Increase total timeout to 60 minutes (Apple can be slow) - Show notarization log on failure for debugging - Apply same approach to both app and DMG notarization
1 parent 0e24474 commit 3d117c9

File tree

1 file changed

+88
-9
lines changed

1 file changed

+88
-9
lines changed

.github/workflows/build-release.yml

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,52 @@ jobs:
151151
ls -lh notarization.zip
152152
153153
echo "Submitting for notarization..."
154-
xcrun notarytool submit notarization.zip \
154+
# Submit without --wait, then poll manually with longer timeout
155+
SUBMIT_OUTPUT=$(xcrun notarytool submit notarization.zip \
155156
--keychain-profile "notary-profile" \
156-
--wait \
157-
--timeout 30m \
158-
2>&1 | tee notarization-output.txt
157+
--output-format json 2>&1)
159158
160-
# Show result
161-
cat notarization-output.txt
159+
echo "$SUBMIT_OUTPUT"
160+
SUBMISSION_ID=$(echo "$SUBMIT_OUTPUT" | grep -o '"id"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/')
161+
162+
if [ -z "$SUBMISSION_ID" ]; then
163+
echo "Failed to get submission ID"
164+
exit 1
165+
fi
166+
167+
echo "Submission ID: $SUBMISSION_ID"
168+
echo "SUBMISSION_ID=$SUBMISSION_ID" >> $GITHUB_ENV
169+
170+
# Poll for completion (up to 60 minutes, checking every 30 seconds)
171+
MAX_ATTEMPTS=120
172+
ATTEMPT=0
173+
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
174+
ATTEMPT=$((ATTEMPT + 1))
175+
echo "Checking status (attempt $ATTEMPT/$MAX_ATTEMPTS)..."
176+
177+
STATUS_OUTPUT=$(xcrun notarytool info "$SUBMISSION_ID" \
178+
--keychain-profile "notary-profile" \
179+
--output-format json 2>&1)
180+
181+
STATUS=$(echo "$STATUS_OUTPUT" | grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*: *"\([^"]*\)".*/\1/')
182+
echo "Status: $STATUS"
183+
184+
if [ "$STATUS" = "Accepted" ]; then
185+
echo "Notarization successful!"
186+
break
187+
elif [ "$STATUS" = "Invalid" ] || [ "$STATUS" = "Rejected" ]; then
188+
echo "Notarization failed with status: $STATUS"
189+
xcrun notarytool log "$SUBMISSION_ID" --keychain-profile "notary-profile"
190+
exit 1
191+
fi
192+
193+
sleep 30
194+
done
195+
196+
if [ "$STATUS" != "Accepted" ]; then
197+
echo "Notarization timed out after 60 minutes"
198+
exit 1
199+
fi
162200
163201
echo "Stapling notarization ticket..."
164202
xcrun stapler staple "export/${{ env.APP_NAME }}.app"
@@ -189,10 +227,51 @@ jobs:
189227
# Notarize the DMG
190228
echo "Notarizing DMG..."
191229
ls -lh "build/${{ env.APP_NAME }}-v${VERSION}.dmg"
192-
xcrun notarytool submit "build/${{ env.APP_NAME }}-v${VERSION}.dmg" \
230+
231+
SUBMIT_OUTPUT=$(xcrun notarytool submit "build/${{ env.APP_NAME }}-v${VERSION}.dmg" \
193232
--keychain-profile "notary-profile" \
194-
--wait \
195-
--timeout 30m
233+
--output-format json 2>&1)
234+
235+
echo "$SUBMIT_OUTPUT"
236+
DMG_SUBMISSION_ID=$(echo "$SUBMIT_OUTPUT" | grep -o '"id"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/')
237+
238+
if [ -z "$DMG_SUBMISSION_ID" ]; then
239+
echo "Failed to get DMG submission ID"
240+
exit 1
241+
fi
242+
243+
echo "DMG Submission ID: $DMG_SUBMISSION_ID"
244+
245+
# Poll for completion (up to 60 minutes)
246+
MAX_ATTEMPTS=120
247+
ATTEMPT=0
248+
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
249+
ATTEMPT=$((ATTEMPT + 1))
250+
echo "Checking DMG status (attempt $ATTEMPT/$MAX_ATTEMPTS)..."
251+
252+
STATUS_OUTPUT=$(xcrun notarytool info "$DMG_SUBMISSION_ID" \
253+
--keychain-profile "notary-profile" \
254+
--output-format json 2>&1)
255+
256+
STATUS=$(echo "$STATUS_OUTPUT" | grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*: *"\([^"]*\)".*/\1/')
257+
echo "Status: $STATUS"
258+
259+
if [ "$STATUS" = "Accepted" ]; then
260+
echo "DMG notarization successful!"
261+
break
262+
elif [ "$STATUS" = "Invalid" ] || [ "$STATUS" = "Rejected" ]; then
263+
echo "DMG notarization failed with status: $STATUS"
264+
xcrun notarytool log "$DMG_SUBMISSION_ID" --keychain-profile "notary-profile"
265+
exit 1
266+
fi
267+
268+
sleep 30
269+
done
270+
271+
if [ "$STATUS" != "Accepted" ]; then
272+
echo "DMG notarization timed out after 60 minutes"
273+
exit 1
274+
fi
196275
197276
# Staple the DMG
198277
xcrun stapler staple "build/${{ env.APP_NAME }}-v${VERSION}.dmg"

0 commit comments

Comments
 (0)