ci: add macOS code signing and notarization - #116
Merged
Merged
Conversation
Replace ad-hoc signing with Developer ID Application certificate signing and Apple notarization for macOS release builds. This eliminates Gatekeeper warnings when users download the DMG. - Import Developer ID certificate from secrets into a temporary keychain - Sign .app bundle with hardened runtime and Apple timestamp - Sign DMG separately - Submit DMG to Apple notary service and staple the ticket - Gracefully fall back to ad-hoc signing when secrets are unavailable (PR/fork builds) - Clean up temporary keychain after the job completes - Add setup documentation in docs/macos-codesigning.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: developer0hye <developer.0hye@gmail.com>
developer0hye
force-pushed
the
ci/macos-codesign-notarize
branch
from
February 17, 2026 01:24
a867438 to
5e62354
Compare
The Qt platform plugin (libqcocoa.dylib) in PlugIns/ was still signed by Qt Company's Team ID, causing library validation failure under hardened runtime. Widen the find scope from Contents/Frameworks to Contents so all nested dylibs are re-signed with our Developer ID. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: developer0hye <developer.0hye@gmail.com>
notarytool submit --wait was hanging indefinitely when notarization failed. Add --timeout 10m to the command and timeout-minutes: 15 to the step. On failure, fetch the notarization log to diagnose the issue. Signed-off-by: developer0hye <developer.0hye@gmail.com>
Apple notarization timed out at 10m with "In Progress" status, likely due to the deeper code signing (hardened runtime on all nested dylibs). Increase notarytool timeout to 30m and step timeout to 35m to allow Apple's service enough time to complete. Also add codesign --verify before DMG creation to catch signing issues early. Signed-off-by: developer0hye <developer.0hye@gmail.com>
notarytool submit --wait hangs indefinitely with no diagnostic output. Split into explicit submit + poll loop with notarytool info so each poll iteration logs the full status. Also add debug steps to: - list all Mach-O binaries in the app bundle - show notarytool history (previous submission statuses) Signed-off-by: developer0hye <developer.0hye@gmail.com>
The inside-out signing approach (individually signing each dylib with --options runtime) causes Apple's notary service to hang indefinitely -- all 5 such submissions remain stuck at "In Progress" after 2+ hours. Switch back to --deep signing (which completed notarization in 59s) but add an entitlements.plist with: - allow-unsigned-executable-memory: needed by ONNX Runtime - disable-library-validation: allow loading bundled dylibs This should fix both the notarization hang and the app launch issue. Signed-off-by: developer0hye <developer.0hye@gmail.com>
hdiutil create fails with "Resource busy" immediately after codesign because macOS hasn't fully released locks on the app bundle yet. Add a brief sleep to let the system release resource locks. Signed-off-by: developer0hye <developer.0hye@gmail.com>
Apple's notary hangs indefinitely when nested dylibs/frameworks are signed with --options runtime (hardened runtime). All 5+ submissions with hardened-runtime nested code remain "In Progress" after hours, while the original submission without it was accepted in 59 seconds. New approach: sign nested code (dylibs, frameworks, plugins) with Developer ID + timestamp only, then sign the main .app bundle with --options runtime + entitlements. The entitlements grant: - allow-unsigned-executable-memory (ONNX Runtime needs this) - disable-library-validation (allow loading bundled dylibs) Signed-off-by: developer0hye <developer.0hye@gmail.com>
All approaches using individual codesign invocations (find+exec on each dylib/framework) cause Apple's notary to hang permanently. The only build that passed notarization (a674dc2d, 59 seconds) used a single codesign --deep --sign pass. Revert to this exact approach: one codesign --force --deep call with --options runtime and --timestamp on the .app bundle. Remove entitlements for now to exactly match what worked before. Entitlements can be added back once notarization is confirmed working. Signed-off-by: developer0hye <developer.0hye@gmail.com>
Remove debugging artifacts (Mach-O listing, submission history, manual polling loop) that were added during Apple notarization service outage investigation. Replace with clean notarytool submit --wait --timeout. Add entitlements.plist to codesign command for hardened runtime compatibility. Update troubleshooting docs with findings from debugging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: developer0hye <developer.0hye@gmail.com>
- Replace deprecated `codesign --deep` with inside-out signing per Apple's current requirements (macOS 13+): sign dylibs, then framework bundles, then plugins, then the main app bundle last. Entitlements are only applied to the main executable. - Run macdeployqt before copying ONNX Runtime dylibs to prevent macdeployqt from interfering with them. - Use `cp -a` with broader glob to copy both versioned dylib and symlink (libonnxruntime.dylib -> libonnxruntime.1.24.1.dylib). - Suppress only "would duplicate" rpath warnings instead of hiding all errors with `|| true`. - Restrict notarization to tag pushes (releases) to avoid unnecessary Apple API calls on every master push. Signed-off-by: developer0hye <developer.0hye@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: developer0hye <developer.0hye@gmail.com>
Document the issues found and fixed during macOS CI packaging: inside-out signing, macdeployqt framework bug, rpath ordering, dylib symlink handling, and notarization scope. Also records non-critical runtime warnings and macOS 15+ Gatekeeper changes. Signed-off-by: developer0hye <developer.0hye@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: developer0hye <developer.0hye@gmail.com>
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add Developer ID code signing and notarization for macOS release builds. This eliminates the Gatekeeper warning dialog that currently appears when users download and open the DMG.
Key Changes
MACOS_CERTIFICATEsecret (base64-encoded.p12), create a temporary keychain, and import the certificatecodesign --deep:Contents/Frameworks/.frameworkbundles (binary inside first, then the bundle)Contents/PlugIns/scripts/entitlements.plist): Grantsallow-unsigned-executable-memoryanddisable-library-validation— applied only to the main executable, not nested codemacdeployqtbefore copying ONNX Runtime dylibs to prevent interferencecp -awith broader glob to preserve symlinksxcrun notarytool submit --wait --timeout 20m, then staple the ticket. Restricted to tag pushes (releases only) to avoid unnecessary Apple API callscodesign --sign -) — no build breakagealways()stepdocs/macos-codesigning.mdwith setup instructions and troubleshooting guideRequired Secrets
MACOS_CERTIFICATE.p12(Developer ID Application cert + private key)MACOS_CERTIFICATE_PASSWORD.p12fileAPPLE_IDAPPLE_ID_PASSWORDAPPLE_TEAM_IDVerification
spctl --assess --type open --context context:primary-signature YoloLabel-macOS.dmg🤖 Generated with Claude Code