Skip to content

Sign and notarize the macOS DMG with a Developer ID - #323

Open
JuergenFleiss wants to merge 6 commits into
aTrainTranscription:developfrom
JuergenFleiss:feature_macos_signing
Open

JuergenFleiss wants to merge 6 commits into
aTrainTranscription:developfrom
JuergenFleiss:feature_macos_signing

Conversation

@JuergenFleiss

@JuergenFleiss JuergenFleiss commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Sign the macOS app and DMG with a Developer ID, notarize both, and staple their tickets.

  • With the Apple secrets set, build-macos-dmg signs every Mach-O file, the frameworks and the app with the hardened runtime, notarizes and staples the app, then signs, notarizes and staples the DMG. spctl checks both.
  • Without the secrets (forks, contributors) the app keeps PyInstaller's ad-hoc signature and stays available as a workflow artifact.
  • publish-macos-to-zenodo requires the signing-verified output, so an ad-hoc build can never become a release.
  • The existing startup checks stay and now run on the signed app, in build-macos-dmg and on macOS 27 from the DMG. The hardened runtime only applies to the Developer ID build, so this is where a missing entitlement shows.
  • Fixes the XML header of entitlements.plist and documents the signature check and the secrets.

Split out into separate PRs: #325 (Zenodo draft ID), #326 (Windows artifact download).

#324 (startup checks in PR CI) is seperate, intended to run on PR

References

Follows #316. Closes #239.

Screenshots / Examples

  • Missing signing secrets: the build produces an ad-hoc test artifact; the publishing job refuses it.

Verification Steps

  • uv run --no-sync pytest tests/unit/test_release_macos_signing.py runs the publishing guard and the DMG signing step against stubbed codesign, spctl and notarization (14 cases).
  • Release workflow on the fork for 27d6217 (run): Developer ID signing, app and DMG notarization, stapling, architecture, minimum-OS and signature checks passed. That run did not start the signed app; a new workflow_dispatch run on this branch covers the startup under the hardened runtime.
  • Tagged publication to GitHub and Zenodo is not verified yet.

When the Apple secrets are set, build-macos-dmg signs every Mach-O file,
the frameworks and the app with the hardened runtime, notarizes and
staples the app and the DMG, and checks both with spctl. Without the
secrets the app keeps PyInstaller's ad-hoc signature, so forks still build.
Fixes the XML header of entitlements.plist and documents the signature
check and the secrets.

Refs aTrainTranscription#239
A secret ending with a newline split the grep pattern, so the identity
check passed and codesign then failed with "no identity found". Match
the quoted identity and reject line breaks with a clear error.
@JuergenFleiss

Copy link
Copy Markdown
Collaborator Author

@gerardo-navarro @BW-Projects could one of you have a look?

@JuergenFleiss
JuergenFleiss marked this pull request as ready for review October 22, 2026 15:29
The startup checks stay in the release workflow and now run on the
Developer ID build: the hardened runtime only applies there, so an
ad-hoc build in PR CI cannot catch a missing entitlement. The macOS 27
check starts the app from the signed DMG again before publishing.

The PR CI startup jobs, the Zenodo draft-ID handoff with the release
lock, and the narrower Windows artifact download move to their own PRs.
@JuergenFleiss JuergenFleiss changed the title Sign and notarize macOS releases and move startup checks to PR CI Sign and notarize the macOS DMG with a Developer ID Oct 23, 2026
@gerardo-navarro

Copy link
Copy Markdown
Contributor

@gerardo-navarro @BW-Projects could one of you have a look?

@JuergenFleiss I will have a look at this. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build the macOS release artifact in GitHub Actions, triggered on tag push

2 participants