Obstacles in notarizing a Kotlin-Multiplatform-based Mac app
I've followed this tutorial: https://github.com/JetBrains/compose-multiplatform/blob/master/tutorials/Signing_and_notarization_on_macOS/README.md
There were 2 problems that I've encountered.
Unable to build chain to self-signed root for signer
The command that failed:
/usr/bin/codesign -vvvv --timestamp --options runtime --force --prefix BUNLDE_PREFIX --sign 'Developer ID Application: Tanin Na Nakorn (S999999X99LE)' /Somepath/Somefile.dylib
Here's an error message:
Warning: unable to build chain to self-signed root for signer "Developer ID Application: Tanin Na Nakorn (S999999X99LE)"
If we read the error very carefully, this means we lack the intermediate and/or root certs.
If you open Keychain Access and look at your Developer ID Application certificate, you'll see the warning "This certificate is not trusted.".
The solution is to install the 4 intermediate certs as specified by this StackOverflow answer: https://stackoverflow.com/a/66083449/710895
This feels really random. Maybe if we were to use XCode, XCode might install these certs automatically. Who knows?
CloudKit query for Something-1.0.0.dmg (2/somethingsomething) failed due to "Record not found"
The command that failed was:
/usr/bin/xcrun stapler staple -v /somepath/Something-1.0.0.dmg
Here's an error message:
CloudKit query for Something-1.0.0.dmg (2/somethingsomething) failed due to "Record not found".
Could not find base64 encoded ticket in response for 2/somethingsomething
The staple and validate action failed! Error 65.
This means there's no record on CloudKit that your app has been notarized. The root cause could be anything like using a wrong cert that isn't "Developer ID Application" or some other random things.
One way to find out more is to look up the notarization error message using notarytool
.
You can see the history of notarization using this command: xcrun notarytool history --apple-id APPLE_ID --password PASSWORD --team-id TEAM_ID
.
Then, you should see each notarization record. Go to the top, which is the latest one, and get its ID. Then, you can see why it fails with this command: xcrun notarytool log --apple-id APPLE_ID --password PASSWORD --team-id TEAM_ID NOTARIZATION_ID
.
In my case, libjnidispatch.jnilib
in the resource directory wasn't code-signed. I could either improve my Gradle config to do code-sign when notarizing the app or code-sign it manually.
But I couldn't figure out how to do that with Gradle. Therefore, I've chosen to code-sign it manually for now with this command: /usr/bin/codesign -vvvv --timestamp --options runtime --force --prefix BUNDLE_PREFIX --sign 'Developer ID Application: NAME (TEAM_ID)' PATH_TO/libjnidispatch.jnilib