macos-spm-app-packaging
Scaffold, build, sign, and package SwiftPM macOS apps without Xcode projects.
Best use case
macos-spm-app-packaging is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Scaffold, build, sign, and package SwiftPM macOS apps without Xcode projects.
Teams using macos-spm-app-packaging should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/macos-spm-app-packaging/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How macos-spm-app-packaging Compares
| Feature / Agent | macos-spm-app-packaging | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Scaffold, build, sign, and package SwiftPM macOS apps without Xcode projects.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 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. ## When to Use - When the user needs a SwiftPM-based macOS app without relying on an Xcode project. - When you need packaging, signing, notarization, or appcast guidance for a SwiftPM app. ## 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: ```bash # 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`):** ```bash # 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):** ```bash # 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:** ```bash # 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. ## Limitations - Use this skill only when the task clearly matches the scope described above. - Do not treat the output as a substitute for environment-specific validation, testing, or expert review. - Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
Related Skills
python-packaging
Comprehensive guide to creating, structuring, and distributing Python packages using modern packaging tools, pyproject.toml, and publishing to PyPI.
macos-menubar-tuist-app
Build, refactor, or review SwiftUI macOS menubar apps that use Tuist.
zustand-store-ts
Create Zustand stores following established patterns with proper TypeScript types and middleware.
zoom-automation
Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.
zoho-crm-automation
Automate Zoho CRM tasks via Rube MCP (Composio): create/update records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.
zod-validation-expert
Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.
zipai-optimizer
Ultra-dense token optimizer skill for prompt caching, log pruning, AST-based inspection, and minified JSON payloads.
zeroize-audit
Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C/C++/Rust code handling secrets, keys, passwords, or other sensitive data.
zendesk-automation
Automate Zendesk tasks via Rube MCP (Composio): tickets, users, organizations, replies. Always search tools first for current schemas.
zapier-make-patterns
No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity - these platforms have their own patterns, pitfalls, and breaking points.
youtube-summarizer
Extract transcripts from YouTube videos and generate comprehensive, detailed summaries using intelligent analysis frameworks
youtube-full
Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.