Skill

Package macOS Apps Without Xcode

Skill for bootstrapping, packaging, signing, and notarizing a SwiftPM macOS app without Xcode, with troubleshooting tables.

Works with github

81
Spark score
out of 100
Updated today
Version 15.7.0

Add to Favorites

Why it matters

Automate the process of building, packaging, signing, and notarizing macOS applications using Swift Package Manager, entirely without the need for Xcode.

Outcomes

What it gets done

01

Bootstrap a SwiftPM macOS app project structure.

02

Build and package the application into a distributable format.

03

Sign and notarize the application for macOS Gatekeeper.

04

Generate appcast files for automated updates.

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-macos-spm-app-packaging | bash

Overview

macOS SwiftPM App Packaging (No Xcode)

A skill for bootstrapping, building, packaging, signing, and notarizing a SwiftPM macOS app without an Xcode project, with validation checkpoints after each stage and a notarization-failure troubleshooting table. Use for SwiftPM-based macOS apps needing packaging, signing, notarization, or appcast setup without Xcode. Edit the bundled template scripts rather than reimplementing signing logic from scratch.

What it does

macOS SwiftPM App Packaging bootstraps a complete SwiftPM macOS app folder, then builds, packages, and runs it entirely without an Xcode project - using a bundled bootstrap template for the starter layout and reference docs for packaging and release detail.

The workflow has two steps. Bootstrapping copies the assets/templates/bootstrap/ skeleton into a new repo and renames the placeholder app name across Package.swift, Sources/MyApp/, and version.env, customizing APP_NAME, BUNDLE_ID, and version fields. Build/package/run copies packaging scripts into the repo, then runs swift build/swift test, packages with Scripts/package_app.sh, runs with Scripts/compile_and_run.sh (preferred dev loop) or Scripts/launch.sh, and optionally signs/notarizes with Scripts/sign-and-notarize.sh and generates a Sparkle appcast with Scripts/make_appcast.sh before tagging a GitHub release.

cp -R assets/templates/bootstrap/ ~/Projects/MyApp
cd ~/Projects/MyApp
sed -i '' 's/MyApp/HelloApp/g' Package.swift version.env
cp assets/templates/package_app.sh Scripts/
cp assets/templates/compile_and_run.sh Scripts/
chmod +x Scripts/*.sh
swift build
Scripts/compile_and_run.sh

It defines validation checkpoints after each key stage: after packaging, confirm the .app bundle structure with ls -R and verify the binary is executable with file; after signing, inspect the signature and entitlements with codesign -dv --verbose=4 and check Gatekeeper acceptance with spctl --assess; after notarization and stapling, confirm the staple ticket with stapler validate and re-run the Gatekeeper check. A troubleshooting table covers five common notarization failures with cause and recovery: duplicate-version upload errors (bump BUILD_NUMBER and repackage), invalid code-signing entitlements (audit against Apple's allowed entitlement set), missing hardened runtime (add --options runtime to codesign calls), stalled notarization with no status email (check xcrun notarytool history, re-export an expired API key), and stapler validate failing right after successful notarization (wait ~60s for ticket propagation, then re-staple).

Nine bundled templates cover the full lifecycle: package_app.sh (build, bundle, copy resources, sign), compile_and_run.sh (kill-package-launch dev loop), build_icon.sh (generate .icns from an Icon Composer file, requires an Xcode install), sign-and-notarize.sh (notarize, staple, zip a release build), make_appcast.sh (generate Sparkle update entries), setup_dev_signing.sh (create a stable dev code-signing identity), launch.sh (simple launcher), version.env (version file consumed by the scripts), and the bootstrap/ skeleton itself. It notes that Sparkle updates depend on CFBundleVersion, so BUILD_NUMBER must increase per release, and that setting MENU_BAR_APP=1 during packaging emits LSUIElement in Info.plist for menu bar apps.

When to use - and when NOT to

Use this skill when a user needs a SwiftPM-based macOS app without relying on an Xcode project, or needs packaging, signing, notarization, or appcast guidance for a SwiftPM app.

Edit the template scripts directly rather than reimplementing signing/entitlements logic from scratch, and remove the Sparkle appcast step entirely if the app doesn't use Sparkle for updates. It is not a substitute for environment-specific validation, testing, or expert review - stop and ask for clarification if required inputs, permissions, or success criteria are missing.

Inputs and outputs

Inputs: an app name/bundle ID for bootstrapping, or an existing SwiftPM macOS app to package, sign, notarize, and release.

Outputs: a bootstrapped SwiftPM app repo, a built and validated .app bundle, a signed and notarized release zip, and optionally a Sparkle appcast entry and tagged GitHub release.

Integrations

Uses Swift Package Manager (swift build, swift test), Apple's codesign, spctl, xcrun notarytool, and stapler tools, and optionally Sparkle for auto-update appcasts; produces GitHub releases as the distribution target.

Who it's for

macOS developers who want to build, package, sign, and notarize a Swift app entirely from the command line without an Xcode project.

FAQ

Common questions

Discussion

Questions & comments ยท 0

Sign In Sign in to leave a comment.