fix(mac): prune dangling symlinks before codesign so Gatekeeper accepts the bundle#10108
Conversation
…ts the bundle A signed, notarised and stapled pgAdmin 4.app was rejected by Gatekeeper with "invalid destination for symbolic link in bundle". Gatekeeper walks every symlink in the bundle and rejects the whole app if any link does not resolve to a real file inside it; notarisation does not catch this, so a broken link slips through stapling and only surfaces as a Gatekeeper failure on the end user's machine. The embedded Python.framework ships such links: an arm64-only build still carries a bin/python3-intel64 launcher symlink (whose target _strip_architecture deletes when it removes the foreign-arch files), and the bundled Tcl/Tk frameworks carry PrivateHeaders links pointing at a Versions/Current that has none. Add a _prune_dangling_symlinks step that removes every dangling symlink in the bundle after architecture stripping and before signing, then fails the build if any remain, so this cannot slip past notarisation again.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughA new ChangesmacOS Build — Dangling Symlink Pruning
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
A signed, notarised and stapled
pgAdmin 4.appis rejected by Gatekeeper even though signing and notarisation are completely valid:Gatekeeper walks every symlink in the bundle and rejects the whole app if any link does not resolve to a real file inside it. Notarisation does not catch this, so a broken link slips through stapling and only surfaces as a Gatekeeper failure on the end user's machine.
The embedded
Python.framework(pulled in viarelocatable-python) ships three such dangling links:Versions/3.13)bin/python3-intel64_strip_architecture, leaving the linkFrameworks/Tcl.framework/PrivateHeadersVersions/Current/PrivateHeaders, which does not existFrameworks/Tk.framework/PrivateHeadersFix
Add a
_prune_dangling_symlinksstep to the macOS build pipeline that removes every dangling symlink in the bundle, rather than hunting individual offenders by name, so a future stray link cannot reintroduce the problem. It runs after_strip_architecture(which orphans the intel link by deleting its target) and before the codesign steps, and it then re-scans and fails the build if anything still dangles, so this can never silently slip past notarisation again.Verification
bash -npasses on both scripts.find -type l ! -exec test -e {} \;prune idiom was exercised on a scratch tree: it deletes dangling links, preserves valid symlinks and real files, and the post-check guard passes.Full end-to-end confirmation (
spctl -aaccepting a freshly signed/notarised/stapled build) requires the codesign credentials and a real Mac, and should be done as part of the next macOS package build.Summary by CodeRabbit