fix(ios): retry transient App Store Connect errors in Xcode Cloud monitor

This commit is contained in:
tianma-if committed 2026-09-11 01:28:33 +08:00
1 parent d9e720ac7c
commit 9f0df716ca
1 file changed
+31 -16
+31 -16
View File
@@ -96,22 +96,37 @@ jobs:
token = encoded.decode() if isinstance(encoded, bytes) else encoded
return token
def api(method, path, body=None):
request = urllib.request.Request(
"https://api.appstoreconnect.apple.com" + path,
data=None if body is None else json.dumps(body).encode(),
method=method,
)
request.add_header("Authorization", f"Bearer {ensure_token()}")
if body is not None:
request.add_header("Content-Type", "application/json")
try:
with urllib.request.urlopen(request) as response:
payload = response.read().decode()
return json.loads(payload) if payload else {}
except urllib.error.HTTPError as error:
details = error.read().decode()
raise SystemExit(f"App Store Connect API {method} {path} failed ({error.code}): {details}")
def invalidate_token():
global token, token_exp
token = None
token_exp = 0
def api(method, path, body=None, attempts=5):
last_error = None
for attempt in range(1, attempts + 1):
request = urllib.request.Request(
"https://api.appstoreconnect.apple.com" + path,
data=None if body is None else json.dumps(body).encode(),
method=method,
)
request.add_header("Authorization", f"Bearer {ensure_token()}")
if body is not None:
request.add_header("Content-Type", "application/json")
try:
with urllib.request.urlopen(request) as response:
payload = response.read().decode()
return json.loads(payload) if payload else {}
except urllib.error.HTTPError as error:
details = error.read().decode()
last_error = f"App Store Connect API {method} {path} failed ({error.code}): {details}"
if error.code in (401, 429, 500, 502, 503, 504) and attempt < attempts:
if error.code == 401:
invalidate_token()
print(f"{last_error} retrying {attempt}/{attempts - 1}", flush=True)
time.sleep(min(30, 2 ** attempt))
continue
raise SystemExit(last_error)
raise SystemExit(last_error or f"App Store Connect API {method} {path} failed")
if mode == "monitor":
if not build_run_id: