- Create a developer account with Apple
- https://developer.apple.com and shell out $99 for a developer account
- Download and install X-Code from the Apple App Store
- Open and run X-Code app and install whatever extras it requires
- Open the preferences pane (cmd+,)
- click the
+
in the lower right corner - choose
Apple ID
- enter your apple ID and password
- Previously created keys can be downloaded and installed from https://developer.apple.com
- click the
- Instructions from Apple
- Open
KeyChain Access
- Create a "New Password Item"
- Keychain Item Name: Developer-altool
- Account Name: your developer account email
- Password: the application-specific password you just created
NB! Additional args such as --add-data
may be needed to build a functional binary
- Create a onefile binary
pyinstaller --onefile myapp.py
- Add the entitements.plist to the directory (see below)
- List the available keys and locate a Developer ID Application certificate:
security find-identity -p basic -v
1) ABC123 "Apple Development: [email protected] ()" 2) XYZ234 "Developer ID Installer: Aaron Ciuffo ()" 3) QRS333 "Developer ID Application: Aaron Ciuffo ()" 4) LMN343 "Developer ID Application: Aaron Ciuffo ()" 5) ZPQ234 "Apple Development: [email protected] ()" 6) ASD234 "Developer ID Application: Aaron Ciuffo ()" 7) 01010A "Developer ID Application: Aaron Ciuffo ()" 7 valid identities found
codesign --deep --force --options=runtime --entitlements ./entitlements.plist --sign "HASH_OF_DEVELOPER_ID APPLICATION" --timestamp ./dist/foo.app
- Create a temp directory to build the package:
mkdir /tmp/myapp
- Use ditto to build the pkg installer structure
ditto /path/to/myapp /tmp/myapp/path/to/install/location
- repeat for all files that should be packaged
- build the pkackage
productbuild --identifier "com.your.pkgname.pkg" --sign "HASH_OF_INSTALLER_ID" --timestamp --root /tmp/myapp / myapp.pkg
xcrun altool --notarize-app --primary-bundle-id "com.foobar.fooapp" --username="[email protected]" --password "@keychain:Developer-altool" --file ./myapp.pkg
- Check email for successful notarization
- Alternatively check status using:
xcrun altool --notarization-history 0 -u "developer@***" -p "@keychain:Developer-altool"
- Alternatively check status using:
- If notarization fails use the following to review a detailed log:
xcrun altool --notarization-info "Your-Request-UUID" \
--username "[email protected]" \
--password "@keychain:Developer-altool"
- add the notariztaion to the pkg
xcrun stapler staple ghostscript64.pkg
- Norarize a Commandline utility
- This blog details setting up:
- a developer profile & certificates
- one time passwords
- creating keychain entries to allow the
-p "@keychain:Key"
switch to work - Signing and Notarizing
- Satpling
- This blog details setting up:
- Adding an
entitlements.plist
to the signing process- ensure that embedded python libraries can be access appropriately
- Signing and Notarizing tools compiled outside of XCode
- covers:
- signing
- packaging
- notarizing
- stapling
- covers:
- Only ".app" bundles appear to work using this procedure
pyinstaller --windowed --onefile foo.py
- edit the spec file
app = BUNDLE
section to include a bundle_identifier
app = BUNDLE(exe, name='helloworld.app', icon=None, bundle_identifier='com.txoof.helloworld' )
- NOTE! Appbundles will not execute properly -- they must be run by execuing the
bundle.app/Contents/MacOS/myapp
NB! This may not work for single file executables -- use the PKG method above
- Create a
.dmg
:- clean any uneeded files out of
./dist
; only the .app should remain hdiutil create ./myapp.dmg -ov -volname "MyApp" -fs HFS+ -srcfolder "./dist"
- clean any uneeded files out of
- Shrink and make read-only:
$hdiutil convert ./myapp.dmg -format UDZO -o myapp.dmg
so glad you found a solution! I know how awful this process is, hence the gist.
It would be amazing if you forked this gist and wrote up your findings -- I'll add a link to your gist at the top. This gist is linked from a couple of places that get some traffic (e.g. stack overflow). It would be wonderful if folks could find your solution.