Skip to content

Address issue #238: Code-Sign the macdown CLI Binary#239

Merged
schuyler merged 4 commits intomainfrom
claude/resolve-issue-238-xg81E
Dec 31, 2025
Merged

Address issue #238: Code-Sign the macdown CLI Binary#239
schuyler merged 4 commits intomainfrom
claude/resolve-issue-238-xg81E

Conversation

@schuyler
Copy link
Copy Markdown
Owner

Summary

Add explicit code signing for the macdown CLI binary in the release workflow to ensure it passes Homebrew Cask's signature verification.

Changes

  1. New "Sign CLI binary explicitly" step (after build, before verification):

    • Signs CLI binary at Contents/SharedSupport/bin/macdown
    • Uses --force --options runtime --timestamp flags
    • Re-signs app bundle to update code signature seal
  2. Enhanced "Verify code signature" step:

    • Verifies CLI binary signature with codesign -vvv --strict
    • Verifies Developer ID signing identity
    • Verifies hardened runtime flag is present
  3. Enhanced "Verify app bundle inside DMG" step:

    • Verifies CLI binary exists in DMG
    • Verifies signature and Developer ID
    • Verifies hardened runtime flag

Why this is needed

The CodeSignOnCopy attribute in Xcode only performs basic code signing without hardened runtime or secure timestamp, which is insufficient for Homebrew Cask/Gatekeeper requirements.

Related Issue

Related to #238

Manual Testing Plan

Phase 1: Workflow Verification

  • Trigger release workflow with a test tag
  • Verify workflow completes without errors in CLI signing steps

Phase 2: Code Signature Verification

# Verify CLI binary after mounting DMG
CLI_PATH="/Volumes/MacDown 3000/MacDown 3000.app/Contents/SharedSupport/bin/macdown"
codesign -vvv --strict "$CLI_PATH"
codesign -dvv "$CLI_PATH" 2>&1 | grep "Authority="  # Should show Developer ID
codesign -dvv "$CLI_PATH" 2>&1 | grep "flags="      # Should contain "runtime"

Phase 3: Homebrew Cask Verification

Review Notes

  • Groucho (Architecture): Recommended adding explicit signing step after build with --options runtime --timestamp
  • Chico (Code Review): Identified critical path issue (SharedSupport vs MacOS) and need to re-sign app bundle; both issues fixed
  • Harpo (Docs): No documentation updates needed - existing docs describe signing at appropriate level
  • Zeppo (Testing): Provided comprehensive manual testing plan for verifying signatures

Add explicit code signing for the macdown CLI binary in the release
workflow to ensure it passes Homebrew Cask's signature verification.

Changes:
- Add "Sign CLI binary explicitly" step after build with:
  - Hardened runtime (--options runtime)
  - Secure timestamp (--timestamp)
  - Developer ID Application certificate
- Add CLI binary verification in "Verify code signature" step:
  - Signature validation
  - Developer ID check
  - Hardened runtime verification
- Add CLI binary verification in DMG verification step

The CodeSignOnCopy attribute in Xcode only performs basic signing
without hardened runtime or timestamp, which is insufficient for
Homebrew Cask/Gatekeeper requirements.

Related to #238
Address code review feedback:

1. Fix CLI binary path: Changed from Contents/MacOS/bin/macdown to
   Contents/SharedSupport/bin/macdown (dstSubfolderSpec=12 in Xcode
   maps to SharedSupport, not MacOS)

2. Add app bundle re-signing: After re-signing the CLI binary with
   hardened runtime, we must re-sign the app bundle to update the
   code signature seal. This ensures notarization doesn't fail due
   to a broken seal.

Related to #238
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 31, 2025

Code Coverage Report

Current Coverage: 51.28%

Coverage Details (Summary)
Name                                                                                                                                   Coverage            
-------------------------------------------------------------------------------------------------------------------------------------- ------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)         
MacDown 3000.app                                                                                                                       57.79% (7207/12472) 
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Document/MPDocument.m                                                      50.23% (762/1517)   
        MPEditorPreferenceKeyWithValueKey                                                                                              85.71% (6/7)        
        MPEditorKeysToObserve                                                                                                          100.00% (14/14)     
        __MPEditorKeysToObserve_block_invoke                                                                                           100.00% (9/9)       
        MPEditorPreferencesToObserve                                                                                                   100.00% (13/13)     
        __MPEditorPreferencesToObserve_block_invoke                                                                                    100.00% (8/8)       
        MPRectStringForAutosaveName                                                                                                    100.00% (6/6)       
        MPAreNilableStringsEqual                                                                                                       100.00% (3/3)       
        MPGetWebViewBackgroundColor                                                                                                    0.00% (0/9)         
        -[NSURL(Convert) absoluteBaseURLString]                                                                                        0.00% (0/6)         
        -[WebView(Shortcut) enclosingScrollView]                                                                                       100.00% (3/3)       
        -[MPPreferences(Hoedown) extensionFlags]                                                                                       75.00% (21/28)      
        -[MPPreferences(Hoedown) rendererFlags]                                                                                        66.67% (8/12)       
        MPGetPreviewLoadingCompletionHandler                                                                                           100.00% (25/25)     
        __MPGetPreviewLoadingCompletionHandler_block_invoke                                                                            100.00% (22/22)     
        -[MPDocument preferences]                                                                                                      100.00% (3/3)       
        -[MPDocument markdown]                                                                                                         100.00% (3/3)       
        -[MPDocument setMarkdown:]                                                                                                     100.00% (3/3)       
        -[MPDocument html]                                                                                                             0.00% (0/3)         
        -[MPDocument toolbarVisible]                                                                                                   0.00% (0/3)         
        -[MPDocument previewVisible]                                                                                                   100.00% (3/3)       
        -[MPDocument editorVisible]                                                                                                    100.00% (3/3)       
        -[MPDocument needsHtml]                                                                                                        0.00% (0/5)         
        -[MPDocument setTotalWords:]                                                                                                   0.00% (0/7)         
        -[MPDocument setTotalCharacters:]                                                                                              0.00% (0/7)         
        -[MPDocument setTotalCharactersNoSpaces:]                                                                                      0.00% (0/8)         
        -[MPDocument setAutosaveName:]                                                                                                 100.00% (4/4)       
        -[MPDocument init]                                                                                                             88.89% (8/9)        
        -[MPDocument windowNibName]                                                                                                    100.00% (3/3)       
        -[MPDocument windowControllerDidLoadNib:]                                                                                      100.00% (85/85)     
        __41-[MPDocument windowControllerDidLoadNib:]_block_invoke                                                                     100.00% (4/4)       
        -[MPDocument reloadFromLoadedString]                                                                                           100.00% (8/8)       
        -[MPDocument close]                                                                                                            0.00% (0/20)        
        +[MPDocument autosavesInPlace]                                                                                                 100.00% (2/2)       
        +[MPDocument writableTypes]                                                                                                    100.00% (3/3)       
        -[MPDocument isDocumentEdited]                                                                                                 100.00% (5/5)       
        -[MPDocument writeToURL:ofType:error:]                                                                                         0.00% (0/15)        
        -[MPDocument dataOfType:error:]                                                                                                100.00% (3/3)       
        -[MPDocument readFromData:ofType:error:]                                                                                       100.00% (8/8)       
        -[MPDocument prepareSavePanel:]                                                                                                76.92% (30/39)      
        __31-[MPDocument prepareSavePanel:]_block_invoke                                                                               100.00% (12/12)     
        -[MPDocument printInfo]                                                                                                        0.00% (0/12)        
        -[MPDocument printOperationWithSettings:error:]                                                                                0.00% (0/7)         
        -[MPDocument printDocumentWithSettings:showPrintPanel:delegate:didPrintSelector:contextInfo:]                                  0.00% (0/17)        
        -[MPDocument validateUserInterfaceItem:]                                                                                       0.00% (0/41)        
        -[MPDocument splitViewDidResizeSubviews:]                                                                                      100.00% (4/4)       

... (2355 more lines truncated)

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

@schuyler schuyler merged commit b3b39d3 into main Dec 31, 2025
6 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