+def notarize(dmg, bundle_id):
+ p = subprocess.run(
+ ['xcrun', 'altool', '--notarize-app', '-t', 'osx', '-f', dmg, '--primary-bundle-id', bundle_id, '-u', config.get('apple_id'), '-p', config.get('apple_password'), '--output-format', 'xml'],
+ capture_output=True
+ )
+
+ def string_after(process, key):
+ lines = p.stdout.decode('utf-8').splitlines()
+ for i in range(0, len(lines)):
+ if lines[i].find(key) != -1:
+ return lines[i+1].strip().replace('<string>', '').replace('</string>', '')
+
+ request_uuid = string_after(p, "RequestUUID")
+ if request_uuid is None:
+ raise Error('No RequestUUID found in response from Apple')
+
+ for i in range(0, 30):
+ print('Checking up on %s' % request_uuid)
+ p = subprocess.run(['xcrun', 'altool', '--notarization-info', request_uuid, '-u', config.get('apple_id'), '-p', config.get('apple_password'), '--output-format', 'xml'], capture_output=True)
+ status = string_after(p, 'Status')
+ print('Got %s' % status)
+ if status == 'invalid':
+ raise Error("Notarization failed")
+ elif status == 'success':
+ subprocess.run(['xcrun', 'stapler', 'staple', dmg])
+ return
+ else:
+ print("Could not understand xcrun response")
+ print(p)
+ time.sleep(30)
+
+ raise Error("Notarization timed out")
+
+