This guide covers building a distributable, signed and notarized PangoLock release. Notarization requires an Apple Developer account (a paid membership) and a Developer ID Application certificate — these cannot be done in CI without those credentials, so the maintainer runs the signed steps locally (or in a CI job with secrets configured).
A quick local (unsigned) build for testing:
scripts/build-release.sh # → dist/PangoLock-<version>.zip (unsigned)
- Apple Developer Program membership.
- A Developer ID Application certificate in your login keychain.
- Your Team ID (10 chars) and the certificate's identity string, e.g.
Developer ID Application: Your Name (TEAMID). - An app‑specific password for notarization, stored as a notarytool profile.
Nothing secret is committed to this repo — provide these via environment/keychain
at build time. CODE_SIGN_STYLE defaults to Automatic and there is no
DEVELOPMENT_TEAM baked into the project.
- Update
MARKETING_VERSIONinPangoLock.xcodeproj(Debug + Release). - Move the
CHANGELOG.mdUnreleased notes under a new## [x.y.z]heading.
DEVELOPMENT_TEAM=TEAMID \
SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
scripts/build-release.sh --signThis produces dist/PangoLock.app (Release, hardened runtime + App Sandbox) and
dist/PangoLock-<version>.zip.
Verify the signature and that the runtime/entitlements are present:
codesign --verify --deep --strict --verbose=2 dist/PangoLock.app
codesign -d --entitlements :- dist/PangoLock.appStore credentials once as a notarytool keychain profile:
xcrun notarytool store-credentials PangoLock-Notary \
--apple-id "you@example.com" --team-id TEAMID --password "APP_SPECIFIC_PASSWORD"Submit and wait, then staple the ticket to the app:
xcrun notarytool submit dist/PangoLock-<version>.zip \
--keychain-profile PangoLock-Notary --wait
xcrun stapler staple dist/PangoLock.appRe‑zip the stapled app for distribution:
ditto -c -k --keepParent dist/PangoLock.app dist/PangoLock-<version>.ziphdiutil create -volname "PangoLock" -srcfolder dist/PangoLock.app \
-ov -format UDZO dist/PangoLock-<version>.dmg
# Sign + notarize + staple the DMG the same way as the zip if distributing it.git tag -a v<version> -m "PangoLock v<version>"
git push origin v<version>Create a GitHub Release for the tag, paste the CHANGELOG.md section, and attach
the notarized .zip (and .dmg if built). CI (build + tests) must be green on
main before tagging.
spctl -a -vv PangoLock.app # should say: accepted, source=Notarized Developer ID
xcrun stapler validate PangoLock.app