From 4006db9646eb51a5a2af0699c273f0417bdf5359 Mon Sep 17 00:00:00 2001 From: Kristina Quinones Date: Tue, 30 Dec 2025 10:10:16 -0500 Subject: [PATCH] Add comprehensive notarization workflow documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created and updated documentation files to include critical notarization workflow for GitHub release distribution: - APP_STORE_RELEASE.md: Added complete notarization workflow section with step-by-step instructions, troubleshooting, and warnings about Gatekeeper errors when skipping notarization - claude.md: New file with Claude Code-specific instructions including detailed notarization workflow, project structure, and release checklists - APP_STORE_BUILD_GUIDE.md: Added GitHub Release Distribution section with notarization workflow and troubleshooting guide - .cursorrules: Updated with notarization workflow instructions (not tracked) Key additions: - 6-step notarization workflow (build, DMG, notarize, staple, verify, upload) - Clear warnings about Gatekeeper blocking non-notarized apps - Troubleshooting commands for failed notarizations - Explanation of why each step matters This ensures future releases to GitHub always include proper notarization, preventing the "malware" warning that users experienced with v1.0.3. πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- tibok/APP_STORE_BUILD_GUIDE.md | 95 ++++++++++- tibok/APP_STORE_RELEASE.md | 291 +++++++++++++++++++++++++++++++++ tibok/claude.md | 268 ++++++++++++++++++++++++++++++ 3 files changed, 652 insertions(+), 2 deletions(-) create mode 100644 tibok/APP_STORE_RELEASE.md create mode 100644 tibok/claude.md diff --git a/tibok/APP_STORE_BUILD_GUIDE.md b/tibok/APP_STORE_BUILD_GUIDE.md index 4b13d73..02c2acd 100644 --- a/tibok/APP_STORE_BUILD_GUIDE.md +++ b/tibok/APP_STORE_BUILD_GUIDE.md @@ -445,9 +445,89 @@ EOF --- +## GitHub Release Distribution (Direct Download) + +For distributing DMG files outside the Mac App Store (e.g., GitHub releases), you must complete the full notarization workflow to avoid Gatekeeper warnings. + +### Complete Notarization Workflow + +**IMPORTANT**: Always run ALL steps in order. Skipping notarization will cause "malware" warnings on user machines. + +```bash +# 1. Build and sign the app bundle +./scripts/build-release-dmg.sh F2PFRMGC9V + +# 2. Create DMG from signed app +./scripts/create-dmg.sh + +# 3. Notarize with Apple (THIS STEP IS CRITICAL - DO NOT SKIP) +xcrun notarytool submit .build/release/Tibok-.dmg \ + --keychain-profile "TIBOK_NOTARIZATION" \ + --wait + +# 4. Staple notarization ticket to DMG +xcrun stapler staple .build/release/Tibok-.dmg + +# 5. Verify notarization +xcrun stapler validate .build/release/Tibok-.dmg + +# 6. Upload to GitHub release +gh release upload v .build/release/Tibok-.dmg +``` + +### Why Each Step Matters + +1. **Build & Sign**: Code signs app with Developer ID certificate (required for notarization) +2. **Create DMG**: Packages signed app into distributable disk image +3. **Notarize**: Apple scans for malware and approves the app (prevents Gatekeeper warnings) +4. **Staple**: Attaches notarization ticket to DMG (works offline) +5. **Verify**: Confirms notarization succeeded +6. **Upload**: Makes notarized DMG available for download + +### What Happens If You Skip Notarization? + +Users will see this error when trying to open the app: +``` +"Apple could not verify 'tibok' is free of malware that may harm your Mac +or compromise your privacy." +``` + +The app will be blocked by macOS Gatekeeper and won't run. Users would need to: +- Right-click β†’ Open (override Gatekeeper) +- Or go to System Settings β†’ Privacy & Security β†’ "Allow anyway" + +This creates a terrible user experience. **Always complete the full notarization workflow.** + +### Notarization Troubleshooting + +**Check notarization history:** +```bash +xcrun notarytool history --keychain-profile "TIBOK_NOTARIZATION" +``` + +**View detailed logs if notarization fails:** +```bash +xcrun notarytool log --keychain-profile "TIBOK_NOTARIZATION" +``` + +**Common notarization failures:** +- **Not signed with Developer ID**: Must use Developer ID Application certificate (not Mac App Store cert) +- **Invalid entitlements**: Check `tibok/Resources/tibok-dmg.entitlements` +- **Missing hardened runtime**: Verify `--options runtime` in codesign command +- **Unsigned frameworks**: All embedded frameworks must be signed + +**Verify app signature before notarizing:** +```bash +codesign --verify --deep --strict --verbose=2 .build/release/tibok.app +``` + +--- + ## Summary -The key to successful App Store builds for tibok is: +The key to successful builds for tibok: + +### For App Store Distribution (Xcode Cloud) 1. **Assets.xcassets in `sources` section** with `buildPhase: resources` 2. **Icon name consistency**: ASSETCATALOG_COMPILER_APPICON_NAME and CFBundleIconName both = "AppIcon" @@ -456,7 +536,18 @@ The key to successful App Store builds for tibok is: 5. **Dynamic build number injection** via ci_post_clone.sh 6. **Entitlements file restoration** after each XcodeGen run -This configuration has been validated through v1.0.2 build #11 and beyond. +### For Direct Distribution (GitHub Releases) + +1. **Sign with Developer ID Application certificate** +2. **Create DMG** from signed app +3. **Notarize with Apple** (CRITICAL - prevents Gatekeeper warnings) +4. **Staple notarization ticket** to DMG +5. **Verify notarization** succeeded +6. **Upload to GitHub** release + +**Never skip notarization for direct distribution.** + +This configuration has been validated through v1.0.3 and beyond. --- diff --git a/tibok/APP_STORE_RELEASE.md b/tibok/APP_STORE_RELEASE.md new file mode 100644 index 0000000..dfc1b2d --- /dev/null +++ b/tibok/APP_STORE_RELEASE.md @@ -0,0 +1,291 @@ +# Tibok - App Store Release Information + +## Current Version: 1.0.3 + +Last updated: 2025-12-30 + +--- + +## App Store Promotional Text +(170 character maximum) + +**Native Markdown editor with git integration. Write, organize, and version control your docsβ€”all in one elegant macOS app.** + +--- + +## App Store Description + +**Tibok** is a native macOS markdown editor designed for developers, writers, and anyone who values simplicity and power in their writing tools. + +### Why Tibok? + +**Native Performance** +Built in Swift for macOS, Tibok feels fast and responsive. No Electron bloatβ€”just pure native macOS performance. + +**Workspace Organization** +Manage entire folders of markdown files with a native file browser. Create, move, copy, rename, and organize your documents with drag-and-drop simplicity. + +**Git Integration** +Version control built right in. Commit changes, switch branches, push to remote, and view commit historyβ€”all without leaving your editor. Visual diff viewer shows exactly what changed with syntax highlighting. + +**Distraction-Free Writing** +Clean, focused interface lets you concentrate on your writing. Markdown preview updates in real-time as you type. + +**Keyboard-First Design** +Comprehensive keyboard shortcuts for every action. Navigate, edit, and manage files without touching your mouse. + +### Key Features + +**Workspace Management** +- Browse and edit multiple markdown files +- Drag-and-drop file operations +- Multi-select for bulk actions +- Create folders and organize your content +- Native macOS file system integration + +**Git Version Control** +- Commit and push directly from the app +- Branch creation and switching +- Visual commit history browser +- Syntax-highlighted diff viewer +- Stage and commit changes with one click + +**Markdown Editing** +- Live preview as you type +- Syntax highlighting +- Native text editing experience +- Auto-save support + +**Developer-Friendly** +- Built with Swift and SwiftUI +- Lightweight and fast +- Keyboard shortcuts for power users +- Clean, native macOS design + +### Perfect For + +- Developers documenting projects +- Writers managing collections of articles +- Students organizing notes +- Anyone who prefers plain text and version control + +### Privacy First + +Tibok runs entirely on your Mac. No accounts, no tracking. Your documents stay on your machine, under your control. + +--- + +## App Store Keywords +(100 character maximum, comma-separated) + +markdown,editor,git,version control,writing,developer,text editor,documentation,notes,macOS + +--- + +## Changelog + +### Version 1.0.3 (Current Release) + +#### Workspace & File Management +- **Workspace Folder Operations**: Browse and manage entire folders of markdown files with native file browser +- **Drag & Drop File Operations**: Move and copy files between folders with intuitive drag-and-drop +- **Multi-Select Support**: Select multiple files for bulk operations (delete, move, etc.) +- **File Operations**: Create new files and folders, rename, move, copy, and delete with native dialogs +- **Workspace Monitoring**: Real-time file system monitoring detects external changes + +#### Git Integration +- **Branch Management UI**: Create new branches, switch between branches, and view current branch status +- **Commit History Browser**: Browse commit history with author, date, message, and file statistics +- **Visual Diff Viewer**: Syntax-highlighted diff viewer shows line-by-line changes +- **Enhanced Git Panel**: Improved UI for staging, committing, and pushing changes +- **Git Status Indicators**: Real-time status updates showing modified, staged, and untracked files + +#### Keyboard Shortcuts +- **Git Operations**: ⌘G (commit), βŒ˜β‡§P (push), βŒ˜β‡§B (branches), βŒ˜β‡§H (history) +- **File Operations**: ⌘N (new file), βŒ˜β‡§N (new folder), ⌘R (rename), ⌘⌫ (delete) +- **Navigation**: ⌘1 (editor), ⌘2 (preview), ⌘3 (git panel) +- **Complete keyboard-first workflow** for all major operations + +#### User Experience +- **Native macOS Design**: Built entirely with SwiftUI for native look and feel +- **Performance Improvements**: Optimized file operations and git commands +- **Error Handling**: Better error messages and user feedback +- **App Sandbox Compliance**: Full Mac App Store sandboxing support + +#### Developer Features +- **Swift Package Manager**: Full SPM support for dependencies +- **Code Signing**: Automatic signing for App Store distribution +- **Xcode Cloud**: CI/CD integration for automated builds +- **Modular Architecture**: Clean separation of concerns (Models, Views, Services, Extensions) + +--- + +## App Store Metadata Checklist + +When submitting to App Store, ensure you have: + +- [ ] App icon (1024x1024px) +- [ ] Screenshots (macOS - minimum 3 required) + - [ ] Workspace view showing file browser + - [ ] Git integration (commit history or diff viewer) + - [ ] Markdown editing with preview + - [ ] Optional: Branch management UI + - [ ] Optional: Keyboard shortcuts reference +- [ ] Privacy Policy URL (if collecting any data) +- [ ] Support URL +- [ ] Marketing URL (optional) +- [ ] Age rating (likely 4+) +- [ ] Category: Productivity or Developer Tools +- [ ] Pricing: Free or Paid (decide) +- [ ] Export compliance documentation +- [ ] Build uploaded via Xcode Cloud or Transporter + +--- + +## Release Workflow + +### App Store Distribution (via Xcode Cloud) + +#### 1. Prepare Release +```bash +# Update version number in Info.plist +# Update this file (APP_STORE_RELEASE.md) with new changelog + +# Commit version bump +git add tibok/Resources/Info.plist APP_STORE_RELEASE.md +git commit -m "Bump version to X.Y.Z" +git push origin main +``` + +#### 2. Trigger App Store Build +```bash +# Merge to apple-store-distro to trigger Xcode Cloud build +git checkout apple-store-distro +git pull origin apple-store-distro +git merge main +git push origin apple-store-distro +``` + +#### 3. Monitor Build +- Check App Store Connect β†’ Xcode Cloud β†’ Builds +- Wait for build to complete and upload to TestFlight + +#### 4. TestFlight Testing +- Download from TestFlight +- Test all major features +- Verify version number and build number + +#### 5. Submit for Review +- Go to App Store Connect β†’ Tibok β†’ App Store tab +- Add build from TestFlight +- Update "What's New" with changelog highlights +- Submit for review + +--- + +### GitHub Release Distribution (Direct Download) + +For distributing DMG files outside the Mac App Store (e.g., GitHub releases), you MUST complete the full notarization workflow to avoid Gatekeeper warnings. + +#### Complete Notarization Workflow + +**IMPORTANT**: Always run ALL steps in order. Skipping notarization will cause "malware" warnings on user machines. + +```bash +# 1. Build and sign the app bundle +./scripts/build-release-dmg.sh F2PFRMGC9V + +# 2. Create DMG from signed app +./scripts/create-dmg.sh + +# 3. Notarize with Apple (THIS STEP IS CRITICAL - DO NOT SKIP) +xcrun notarytool submit .build/release/Tibok-.dmg \ + --keychain-profile "TIBOK_NOTARIZATION" \ + --wait + +# 4. Staple notarization ticket to DMG +xcrun stapler staple .build/release/Tibok-.dmg + +# 5. Verify notarization +xcrun stapler validate .build/release/Tibok-.dmg + +# 6. Upload to GitHub release +gh release upload v .build/release/Tibok-.dmg +``` + +#### Why Each Step Matters + +1. **Build & Sign**: Signs app with Developer ID certificate (required for notarization) +2. **Create DMG**: Packages signed app into distributable disk image +3. **Notarize**: Apple scans for malware and approves the app (prevents Gatekeeper warnings) +4. **Staple**: Attaches notarization ticket to DMG (works offline) +5. **Verify**: Confirms notarization succeeded +6. **Upload**: Makes notarized DMG available for download + +#### What Happens If You Skip Notarization? + +Users will see this error when trying to open the app: +``` +"Apple could not verify 'tibok' is free of malware that may harm your Mac +or compromise your privacy." +``` + +The app will be blocked by macOS Gatekeeper and won't run. + +#### Troubleshooting Notarization + +**Check notarization status:** +```bash +xcrun notarytool history --keychain-profile "TIBOK_NOTARIZATION" +``` + +**View detailed logs if notarization fails:** +```bash +xcrun notarytool log --keychain-profile "TIBOK_NOTARIZATION" +``` + +**Common issues:** +- App not signed with Developer ID certificate β†’ Re-run step 1 +- Invalid entitlements β†’ Check tibok-dmg.entitlements +- Hardened runtime issues β†’ Ensure --options runtime flag in codesign + +--- + +## Version History + +### 1.0.3 (2025-12-30) +- Initial App Store release +- Workspace management with drag & drop +- Complete git integration +- Keyboard-first workflow + +--- + +## Notes for Future Releases + +### Marketing Copy Updates +When updating promotional text or description: +- Keep promotional text under 170 characters +- Highlight 1-2 key differentiators +- Focus on benefits, not just features +- Test keywords in App Store search + +### Changelog Guidelines +- Group related changes by category +- Lead with user-facing features +- Technical details go last +- Be specific and clear +- Use active voice + +### Screenshot Ideas +- Capture at native macOS resolution +- Use light mode for consistency +- Show real content (sample markdown documents) +- Highlight unique features (git integration, workspace) +- Include captions explaining each screenshot + +--- + +**Ready for App Store submission!** + +Check App Store Connect for build status: https://appstoreconnect.apple.com diff --git a/tibok/claude.md b/tibok/claude.md new file mode 100644 index 0000000..df5c1ab --- /dev/null +++ b/tibok/claude.md @@ -0,0 +1,268 @@ +# Claude Code Instructions for Tibok Development + +This file contains project-specific instructions for Claude Code when working on the Tibok markdown editor project. + +## Project Context + +Tibok is a native macOS markdown editor built with Swift and SwiftUI. Key features: +- Workspace management with file browser +- Git integration (commit, push, branches, history, diffs) +- Real-time markdown preview +- Keyboard-first design with comprehensive shortcuts +- Mac App Store distribution + +## Critical Build & Release Workflows + +### Development Build + +```bash +# Build and run locally +./scripts/build-app.sh +open .build/debug/tibok.app +``` + +### App Store Distribution (via Xcode Cloud) + +For Mac App Store releases, use the Xcode Cloud automated workflow: + +```bash +# 1. Update version in Info.plist +# 2. Commit changes +git add tibok/Resources/Info-AppStore.plist +git commit -m "Bump version to X.Y.Z" +git push origin main + +# 3. Trigger Xcode Cloud build +git checkout apple-store-distro +git pull origin apple-store-distro +git merge main +git push origin apple-store-distro + +# Xcode Cloud will automatically: +# - Build the app +# - Sign with Mac App Store certificate +# - Upload to TestFlight +# - Notify when complete +``` + +Monitor builds at: https://appstoreconnect.apple.com β†’ Xcode Cloud β†’ Builds + +### GitHub Release Distribution (Direct Download DMG) + +**CRITICAL**: For DMG files distributed outside the Mac App Store (e.g., GitHub releases), you MUST complete the full notarization workflow. Skipping notarization causes Gatekeeper to block the app with a "malware" warning. + +#### Complete Notarization Workflow (DO NOT SKIP STEPS) + +```bash +# 1. Build and sign the app bundle +./scripts/build-release-dmg.sh F2PFRMGC9V + +# 2. Create DMG from signed app +./scripts/create-dmg.sh + +# 3. Notarize with Apple (THIS STEP IS CRITICAL) +xcrun notarytool submit .build/release/Tibok-.dmg \ + --keychain-profile "TIBOK_NOTARIZATION" \ + --wait + +# 4. Staple notarization ticket to DMG +xcrun stapler staple .build/release/Tibok-.dmg + +# 5. Verify notarization +xcrun stapler validate .build/release/Tibok-.dmg + +# 6. Upload to GitHub release +gh release upload v .build/release/Tibok-.dmg +``` + +#### Why Each Step Matters + +1. **Build & Sign**: Code signs app with Developer ID certificate (required for notarization) +2. **Create DMG**: Packages signed app into distributable disk image +3. **Notarize**: Apple scans and approves the app, generates notarization ticket +4. **Staple**: Attaches notarization ticket to DMG so it works offline +5. **Verify**: Confirms notarization process completed successfully +6. **Upload**: Distributes notarized DMG to users + +#### What Happens If You Skip Notarization? + +macOS Gatekeeper will show this error when users try to open the app: + +``` +"Apple could not verify 'tibok' is free of malware that may harm your Mac +or compromise your privacy." +``` + +The app will be completely blocked and won't run. Users will need to: +- Right-click β†’ Open (override Gatekeeper) +- Go to System Settings β†’ Privacy & Security β†’ Allow anyway + +This creates a terrible user experience. **Always notarize.** + +#### Notarization Troubleshooting + +Check notarization history: +```bash +xcrun notarytool history --keychain-profile "TIBOK_NOTARIZATION" +``` + +View detailed error logs: +```bash +xcrun notarytool log --keychain-profile "TIBOK_NOTARIZATION" +``` + +Common notarization failures: +- **Not signed with Developer ID**: Re-run step 1 +- **Invalid entitlements**: Check `tibok/Resources/tibok-dmg.entitlements` +- **Missing hardened runtime**: Verify `--options runtime` in codesign command + +## Project Structure + +``` +tibok/ +β”œβ”€β”€ tibok/ # Main app source +β”‚ β”œβ”€β”€ tibokApp.swift # App entry point +β”‚ β”œβ”€β”€ ContentView.swift # Main window layout +β”‚ β”œβ”€β”€ Models/ # Data models (AppState, GitModels, etc.) +β”‚ β”œβ”€β”€ Views/ # SwiftUI views (EditorView, GitPanelView, etc.) +β”‚ β”œβ”€β”€ Services/ # Business logic (GitService, WorkspaceMonitor) +β”‚ β”œβ”€β”€ Extensions/ # Extension methods (KeyboardShortcuts) +β”‚ └── Resources/ # Assets, icons, Info.plist, entitlements +β”œβ”€β”€ scripts/ # Build automation scripts +β”‚ β”œβ”€β”€ build-app.sh # Local development build +β”‚ β”œβ”€β”€ build-release-dmg.sh # Production build with signing +β”‚ β”œβ”€β”€ create-dmg.sh # DMG creation +β”‚ └── notarize-dmg.sh # Notarization wrapper script +β”œβ”€β”€ user_docs/ # End-user documentation +└── tibok.xcodeproj/ # Xcode project (generated by XcodeGen) +``` + +## Key Configuration Files + +### Code Signing & Distribution + +- **Developer ID**: F2PFRMGC9V (Kristina Quinones) +- **Bundle ID**: `com.kquinones.tibok` (DMG distribution) +- **Bundle ID**: `app.tibok.editor` (App Store distribution) +- **Entitlements (DMG)**: `tibok/Resources/tibok-dmg.entitlements` +- **Entitlements (App Store)**: `tibok/Resources/tibok-appstore.entitlements` + +### Important Build Settings + +- **Deployment Target**: macOS 14.0+ +- **Swift Version**: 5.9+ +- **Architectures**: arm64 (Apple Silicon native) +- **Signing**: Developer ID Application (DMG) or Mac App Store (App Store) + +## Development Guidelines + +### Adding New Features + +1. **Code Changes**: Implement feature in appropriate Models/Views/Services +2. **User Documentation**: Update `user_docs/features/*.md` if user-facing +3. **Keyboard Shortcuts**: Update `user_docs/features/keyboard-shortcuts.md` +4. **Changelog**: Update `APP_STORE_RELEASE.md` with feature description +5. **Testing**: Build and test locally before committing + +### Xcode Project Management + +The project uses **XcodeGen** to generate the `.xcodeproj` file from `project.yml`. + +**IMPORTANT**: When adding new Swift files to the project: +1. Create the file in the appropriate directory (Models/Views/Services/Extensions) +2. The file must be **manually registered** in `tibok.xcodeproj/project.pbxproj` +3. **OR** regenerate the Xcode project with: `xcodegen generate --spec project.yml` + +**Why manual registration is needed**: Xcode Cloud builds use the `.xcodeproj` file, not the filesystem. Files that exist on disk but aren't in the project file will cause "Cannot find ... in scope" compilation errors. + +#### Adding Files to Xcode Project Manually + +Each file requires 4 entries in `project.pbxproj`: +1. **PBXFileReference** - File definition with UUID +2. **PBXBuildFile** - Links file to build system +3. **PBXGroup** - Navigator placement (Models/Views/Services/Extensions) +4. **PBXSourcesBuildPhase** - Compilation inclusion + +See recent fix in commit history for example of adding GitModels.swift, GitHistoryView.swift, etc. + +### Git Workflow + +- **Main branch**: `main` - stable releases +- **Development branch**: `development` - active development +- **App Store branch**: `apple-store-distro` - triggers Xcode Cloud builds + +When implementing features: +1. Work on `development` branch +2. Merge to `main` when stable +3. Merge `main` to `apple-store-distro` for App Store releases + +## Common Tasks + +### Run Local Build +```bash +./scripts/build-app.sh && open .build/debug/tibok.app +``` + +### Run Swift Tests +```bash +swift test +``` + +### Check Code Signing +```bash +codesign --verify --deep --strict --verbose=2 .build/release/tibok.app +``` + +### View Git History +```bash +git log --oneline --graph --all -20 +``` + +### Create GitHub Release +```bash +# After notarizing DMG +gh release create v1.0.X \ + --title "Tibok v1.0.X - Release Title" \ + --notes-file RELEASE_NOTES.md \ + .build/release/Tibok-1.0.X.dmg +``` + +## Documentation Files + +- **APP_STORE_RELEASE.md** - Version info, changelog, release workflows +- **APP_STORE_BUILD_GUIDE.md** - Complete guide to App Store builds +- **XCODE_CLOUD_SETUP.md** - Xcode Cloud configuration +- **DEVELOPMENT.md** - General development guidelines +- **.cursorrules** - Cursor IDE specific rules +- **claude.md** (this file) - Claude Code specific instructions + +## References + +- App Store Connect: https://appstoreconnect.apple.com +- GitHub Repository: https://github.com/sturdy-barnacle/md-editor +- Developer Portal: https://developer.apple.com/account + +## Quick Reference: Release Checklist + +### For App Store Release +- [ ] Update version in Info-AppStore.plist +- [ ] Update APP_STORE_RELEASE.md changelog +- [ ] Commit and push to main +- [ ] Merge to apple-store-distro +- [ ] Monitor Xcode Cloud build +- [ ] Test on TestFlight +- [ ] Submit for review in App Store Connect + +### For GitHub Release +- [ ] Update version in Info.plist +- [ ] Run build-release-dmg.sh +- [ ] Create DMG with create-dmg.sh +- [ ] **NOTARIZE with xcrun notarytool** (CRITICAL) +- [ ] **STAPLE with xcrun stapler** (CRITICAL) +- [ ] Verify with xcrun stapler validate +- [ ] Upload to GitHub release +- [ ] Test downloaded DMG on clean Mac + +--- + +**Remember**: When in doubt about release workflows, consult APP_STORE_RELEASE.md for detailed instructions. Always notarize DMG files before public distribution.