guide-macos-spm-packaging
Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project. Use when you need a from-scratch macOS app layout, SwiftPM targets/resources, a custom .app bundle assembly script, or signing/notarization/appcast steps outside Xcode.
By prisma-labs-dev · 368 installs
npx skills add prisma-labs-dev/apple-skills --skill guide-macos-spm-packaging
Source repository · Upstream listing
Guide Skill — This is an expert workflow/pattern guide, not API reference documentation.
Originally from [Dimillian/Skills](https://github.com/Dimillian/Skills) by Thomas Ricouard. MIT License.
macOS SwiftPM App Packaging (No Xcode)
Overview
Bootstrap a complete SwiftPM macOS app folder, then build, package, and run it without Xcode. Use assets/templates/bootstrap/ for the starter layout and references/packaging.md + references/release.md for packaging and release details.
Two Step Workflow
1) Bootstrap the project folder
Copy assets/templates/bootstrap/ into a new repo.
Rename MyApp in Package.swift , Sources/MyApp/ , and version.env .
Customize APP NAME , BUNDLE ID , and versions.
2) Build, package, and run the bootstrapped app
Copy scripts from assets/templates/ into your repo (for example, Scripts/ ).
Build/tests: swift build and swift test .
Package: Scripts/package app.sh .
Run: Scripts/compile and run.sh (preferred) or Scripts/launch.sh .
Release (optional): Scripts/sign and notarize.sh and Scripts/make appcast.sh .
Tag + GitHub release (optional): create a git tag, upload the zip/appcast to the GitHub release, and publish.
Minimum End to End Example
Shortest path from bootstrap to a running app:
Validation Checkpoints
Run these after key steps to catch failures early before proceeding to the next stage.
After packaging ( Scripts/package app.sh ):
After signing ( Scripts/sign and notarize.sh or ad hoc dev signing):
After notarization and stapling:
Common Notarization Failures
Symptom Likely Cause Recovery
The software asset has already been uploaded Duplicate submission for same version Bump BUILD NUMBER in version.env and repackage.
Package Invalid: Invalid Code Signing Entitlements Entitlements in .entitlements file don't match provisioning Audit entitlements against Apple's allowed set; remove unsupported keys.
The executable does not have the hardened runtime enabled Missing options runtime flag in codesign invocation Edit sign and notarize.sh to add options runtime to all codesign calls.
Notarization hangs / no status email xcrun notarytool network or credential issue Run xcrun notarytool history to check status; re export App Store Connect API key if expired.
stapler validate fails after successful notarization Ticket not yet propagated Wait ~60 s, then re run xcrun stapler staple .
Templates
assets/templates/package app.sh : Build binaries, create the .app bundle, copy resources, sign.
assets/templates/compile and run.sh : Dev loop to kill running app, package, launch.
assets/templates/build icon.sh : Generate .icns from an Icon Composer file (requires Xcode install).
assets/templates/sign and notarize.sh : Notarize, staple, and zip a release build.
assets/templates/make appcast.sh : Generate Sparkle appcast entries for updates.
assets/templates/setup dev signing.sh : Create a stable dev code signing identity.
assets/templates/launch.sh : Simple launcher for a packaged .app.
assets/templates/version.env : Example version file consumed by packaging scripts.
assets/templates/bootstrap/ : Minimal SwiftPM macOS app skeleton (Package.swift, Sources/, version.env).
Notes
Keep entitlements and signing configuration explicit; edit the template scripts instead of reimplementing.
Remove Sparkle steps if you do not use Sparkle for updates.
Sparkle relies on the bundle build number ( CFBundleVersion ), so BUILD NUMBER in version.env must increase for each update.
For menu bar apps, set MENU BAR APP=1 when packaging to emit LSUIElement in Info.plist.