Skip to content

fix: notarize and staple release DMGs so Gatekeeper accepts them - #459

Open
mvanhorn wants to merge 1 commit into
automazeio:mainfrom
mvanhorn:fix/398-vibeproxy-dmg-notarize
Open

fix: notarize and staple release DMGs so Gatekeeper accepts them#459
mvanhorn wants to merge 1 commit into
automazeio:mainfrom
mvanhorn:fix/398-vibeproxy-dmg-notarize

Conversation

@mvanhorn

Copy link
Copy Markdown

Summary

In .github/workflows/release.yml, add a "Notarize DMG" step in the build-signed job immediately after "Create DMG" and before "Create ZIP archive" / "Calculate checksums" (ordering matters: stapling modifies the DMG, so the sha256 must be computed after stapling - the existing step order already ensures this). The new step, guarded by if [ -f "VibeProxy-${{ matrix.arch }}.dmg" ] to match the workflow's existing non-fatal DMG handling, runs `xcrun notarytool submit "VibeProxy-${{ matrix.arch }}.dmg" --apple-id ... --team-id ...

Why this matters

A user downloaded VibeProxy-arm64.dmg from the official releases and found that while the app bundle inside is correctly notarized and stapled (spctl --assess --type execute accepts it), the DMG itself is only codesigned, not notarized: spctl --assess --type open --context context:primary-signature rejects it with "Unnotarized Developer ID" and xcrun stapler validate confirms no ticket is stapled. The release notes claim "Code Signed & Notarized - No Gatekeeper warnings", so the DMG artifact contradicts the stated guarantee. Root cause is visible in .github/workflows/release.yml: the "Notarize App" step submits and staples only VibeProxy.app; the subsequent "Create DMG" step codesigns the DMG via create-dmg's --codesign flag but never submits the DMG to notarytool or staples it.

See #398.

Testing

  • Happy path: tag-triggered release run produces VibeProxy-arm64.dmg and VibeProxy-x86_64.dmg that pass xcrun stapler validate and spctl --assess --type open --context context:primary-signature (verified in-workflow by the new validate/assess commands; workflow YAML validated locally with actionlint/yamllint since CI secrets cannot be exercised from a fork). - Edge case: create-dmg fails and no DMG exists (the step uses || true) - the notarize step's existence guard skips cleanly instead of erroring on a missing file. - Error path: notarytool returns a non-Accepted status for the DMG - the step prints the notarytool log for the submission id and exits 1, failing the release rather than shipping an unnotarized DMG. - Regression guard: sha256 files still match the final (stapled) DMG bytes because "Calculate checksums" runs after the new notarize/staple step.

Fixes #398

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.

v1.8.x macOS DMG fails Gatekeeper notarization assessment

1 participant