macos-spm-app-packaging

Build, package, and sign SwiftPM-based macOS apps entirely outside Xcode using shell scripts and templates. Includes a minimal SwiftPM project skeleton in assets/templates/bootstrap/ with Package.swift, Sources structure, and version configuration ready to rename and customize Provides six core packaging scripts: package_app.sh for .app bundle assembly, compile_and_run.sh for dev iteration, sign-and-notarize.sh for release signing and Apple notarization, and make_appcast.sh for Sparkle update feeds Covers the full release pipeline from build through code signing, notarization, stapling, and GitHub release publication with validation checkpoints at each stage Includes troubleshooting guidance for common notarization failures (duplicate submissions, entitlements mismatches, hardened runtime issues) and menu bar app support via MENU_BAR_APP flag

INSTALLATION
npx skills add https://github.com/dimillian/skills --skill macos-spm-app-packaging
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$2a

Minimum End-to-End Example

Shortest path from bootstrap to a running app:

# 1. Copy and rename the skeleton

cp -R assets/templates/bootstrap/ ~/Projects/MyApp

cd ~/Projects/MyApp

sed -i '' 's/MyApp/HelloApp/g' Package.swift version.env

# 2. Copy scripts

cp assets/templates/package_app.sh Scripts/

cp assets/templates/compile_and_run.sh Scripts/

chmod +x Scripts/*.sh

# 3. Build and launch

swift build

Scripts/compile_and_run.sh

Validation Checkpoints

Run these after key steps to catch failures early before proceeding to the next stage.

**After packaging (Scripts/package_app.sh):**

# Confirm .app bundle structure is intact

ls -R build/HelloApp.app/Contents

# Check that the binary is present and executable

file build/HelloApp.app/Contents/MacOS/HelloApp

**After signing (Scripts/sign-and-notarize.sh or ad-hoc dev signing):**

# Inspect signature and entitlements

codesign -dv --verbose=4 build/HelloApp.app

# Verify the bundle passes Gatekeeper checks locally

spctl --assess --type execute --verbose build/HelloApp.app

After notarization and stapling:

# Confirm the staple ticket is attached

stapler validate build/HelloApp.app

# Re-run Gatekeeper to confirm notarization is recognised

spctl --assess --type execute --verbose build/HelloApp.app

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.
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card