Skip to content

Fix entitlements loss during app re-signing (issue #302)#472

Merged
schuyler merged 1 commit into
mainfrom
claude/pensive-edison-jw1pxz
Jun 24, 2026
Merged

Fix entitlements loss during app re-signing (issue #302)#472
schuyler merged 1 commit into
mainfrom
claude/pensive-edison-jw1pxz

Conversation

@schuyler

Copy link
Copy Markdown
Owner

Summary

Fixes a critical bug where the app bundle lost its com.apple.security.files.user-selected.read-write entitlement during the post-build re-signing step in the release workflow. This entitlement is required for NSSavePanel (Move To / Save As…) to function on macOS Sequoia and later; without it, users encounter ViewBridge error 14.

Root Cause

The release workflow re-signs the app bundle after signing the bundled CLI binary to update the code signature seal. However, codesign --force --deep replaces the existing signature entirely. If --entitlements is not passed, the re-signed app loses all entitlements that were applied by the Xcode build.

Changes

.github/workflows/release.yml

  • Re-signing step: Added --entitlements "MacDown/MacDown.entitlements" to the codesign command to preserve entitlements during the post-build re-sign
  • Verification gates: Added two new entitlement verification checks:
    • After the app bundle re-sign (before DMG creation)
    • After packaging the app inside the DMG
  • Both gates assert the presence of com.apple.security.files.user-selected.read-write and fail the build if missing
  • Updated comment to explain why --entitlements is mandatory

.github/workflows/staple-release.yml

  • Final verification gate: Added entitlement check before publishing the release to ensure the shipped app carries the required entitlement
  • Prevents a build that lost entitlements from being published

plans/release-process.md

  • Documented the entitlements re-signing requirement and the three verification gates
  • Added troubleshooting section for "Move To / Save As… fails with ViewBridge error 14" with diagnosis and solution steps

Implementation Details

  • Entitlement verification uses codesign -d --entitlements :- to extract and inspect the app's entitlements
  • Three defensive gates ensure the entitlement cannot be lost silently: after re-sign, in the DMG, and at final pre-publish verification
  • All verification failures include clear error messages referencing issue "Move To" fails on macOS Sequoia with ViewBridge error 14 #302 for user context

https://claude.ai/code/session_014YWsBJ616nvkLYKKe1NhkW

The Xcode build signs the app with CODE_SIGN_ENTITLEMENTS, but the
release pipeline re-signs the bundle (codesign --force --deep) after
sealing the bundled macdown CLI binary. That re-sign replaced the
signature without --entitlements, stripping
com.apple.security.files.user-selected.read-write from shipped builds.
Without it, NSSavePanel (Move To / Save As…) fails with ViewBridge
error 14 on macOS Sequoia and later.

- Pass --entitlements MacDown/MacDown.entitlements to the app re-sign
- Assert the entitlement is present at three gates so a build that
  loses it fails CI instead of shipping: after the re-sign and on the
  app inside the DMG (release.yml), and at final pre-publish
  verification (staple-release.yml)
- Document the re-sign requirement and a troubleshooting entry

Related to #302
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Report

Current Coverage: 62.01%

Coverage Details (Summary)
Name                                                                                                                                   Coverage            
-------------------------------------------------------------------------------------------------------------------------------------- ------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)         
MacDown 3000.app                                                                                                                       63.44% (9143/14411) 
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Preferences/MPHtmlPreferencesViewController.m                              0.00% (0/113)       
        MPPrismDefaultThemeName                                                                                                        0.00% (0/2)         
        -[MPHtmlPreferencesViewController viewIdentifier]                                                                              0.00% (0/3)         
        -[MPHtmlPreferencesViewController toolbarItemImage]                                                                            0.00% (0/3)         
        -[MPHtmlPreferencesViewController toolbarItemLabel]                                                                            0.00% (0/2)         
        -[MPHtmlPreferencesViewController viewWillAppear]                                                                              0.00% (0/4)         
        -[MPHtmlPreferencesViewController changeStylesheet:]                                                                           0.00% (0/7)         
        -[MPHtmlPreferencesViewController changeHighlightingTheme:]                                                                    0.00% (0/7)         
        -[MPHtmlPreferencesViewController invokeStylesheetFunction:]                                                                   0.00% (0/23)        
        -[MPHtmlPreferencesViewController invokeHighlightingThemeFunction:]                                                            0.00% (0/33)        
        -[MPHtmlPreferencesViewController loadStylesheets]                                                                             0.00% (0/14)        
        -[MPHtmlPreferencesViewController loadHighlightingThemes]                                                                      0.00% (0/15)        
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Extension/DOMNode+Text.m                                                   100.00% (111/111)   
        MPAccumulatedTextCountMake                                                                                                     100.00% (7/7)       
        MPAccumulatedTextCountZero                                                                                                     100.00% (3/3)       
        MPAccumulatedTextCountAdd                                                                                                      100.00% (5/5)       
        MPGetStringAccumulatedTextCount                                                                                                100.00% (34/34)     
        __MPGetStringAccumulatedTextCount_block_invoke                                                                                 100.00% (3/3)       
        __MPGetStringAccumulatedTextCount_block_invoke.5                                                                               100.00% (4/4)       
        MPGetChildrenAccumulatedTextCount                                                                                              100.00% (6/6)       
        MPGetNodeAccumulatedTextCount                                                                                                  100.00% (32/32)     
        MPTextCountForString                                                                                                           100.00% (9/9)       
        -[DOMNode(Text) textCount]                                                                                                     100.00% (8/8)       
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Utility/FileURLInlining.m                                                  26.60% (25/94)      
        +[FileURLInlining inlineFromIterable:]                                                                                         0.00% (0/11)        
        -[FileURLInlining initWithURL:]                                                                                                0.00% (0/6)         
        -[FileURLInlining init]                                                                                                        100.00% (3/3)       
        -[FileURLInlining inlineContent]                                                                                               0.00% (0/9)         
        -[FileURLInlining imageContent]                                                                                                0.00% (0/12)        
        +[FileURLInlining mimeTypeForFilePath:]                                                                                        100.00% (22/22)     
        -[FileURLInlining clippingContent]                                                                                             0.00% (0/4)         
        +[FileURLInlining isTextClippingAtPath:]                                                                                       0.00% (0/12)        
        +[FileURLInlining textContentFromClipping:]                                                                                    0.00% (0/15)        
    /Users/runner/work/macdown3000/macdown3000/Dependency/peg-markdown-highlight/HGMarkdownHighlightingStyle.m                         89.23% (58/65)      
        +[HGMarkdownHighlightingStyle colorFromARGBColor:]                                                                             100.00% (6/6)       
        -[HGMarkdownHighlightingStyle initWithType:attributesToAdd:toRemove:fontTraitsToAdd:]                                          88.89% (8/9)        
        -[HGMarkdownHighlightingStyle initWithStyleAttributes:baseFont:]                                                               88.00% (44/50)      
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Utility/MPResourceWatcherSet.m                                             93.62% (88/94)      
        -[MPResourceWatcherSet init]                                                                                                   100.00% (6/6)       
        -[MPResourceWatcherSet dealloc]                                                                                                0.00% (0/3)         
        -[MPResourceWatcherSet watchedPaths]                                                                                           100.00% (3/3)       
        -[MPResourceWatcherSet updateWatchedPaths:]                                                                                    100.00% (16/16)     
        -[MPResourceWatcherSet addWatcherForPath:]                                                                                     100.00% (32/32)     
        __42-[MPResourceWatcherSet addWatcherForPath:]_block_invoke                                                                    100.00% (6/6)       
        __42-[MPResourceWatcherSet addWatcherForPath:]_block_invoke.37                                                                 93.33% (14/15)      
        __42-[MPResourceWatcherSet addWatcherForPath:]_block_invoke_2                                                                  75.00% (6/8)        

... (3320 more lines truncated)

📊 **Full coverage report available in workflow artifacts**

@schuyler schuyler merged commit abadf6b into main Jun 24, 2026
10 checks passed
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.

2 participants