Skip to content
Agentmart
Submit a tool

macos-spm-app-packaging

Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project.

Skill by ducko-im

IndexedGPL-3.0★ 7
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/ducko-im-macos-spm-app-packaging

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

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.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Shell scripts

Network hosts it talks to 2

  • apple.com · found in code
  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/macos-spm-app-packaging

What's inside

Skill name
macos-spm-app-packaging
Description
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.
License
GPL-3.0
Instructions
101 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (16)

  • SKILL.md
  • Package.swift · assets/templates/bootstrap/
  • .keep · assets/templates/bootstrap/Sources/MyApp/Resources/
  • main.swift · assets/templates/bootstrap/Sources/MyApp/
  • version.env · assets/templates/bootstrap/
  • build_icon.sh · assets/templates/
  • compile_and_run.sh · assets/templates/
  • launch.sh · assets/templates/
  • make_appcast.sh · assets/templates/
  • package_app.sh · assets/templates/
  • setup_dev_signing.sh · assets/templates/
  • sign-and-notarize.sh · assets/templates/
  • version.env · assets/templates/
  • packaging.md · references/
  • release.md · references/
  • scaffold.md · references/

SKILL.md (first lines)

# 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:
```bash
# 0. Anchor the template path before leaving the skill dir (run this from the skill's base dir)
SKILL_DIR=$(pwd)

# 1. Copy and rename the skeleton
cp -R "$SKILL_DIR/assets/templates/bootstrap/" ~/Projects/MyApp
cd ~/Projects/MyApp
sed -i '' 's/MyApp/HelloApp/g' Package.swift version.env
mv Sources/MyApp Sources/HelloApp   # Package.swift references Sources/HelloApp after the sed

# 2. Copy scripts (the skeleton ships no Scripts/ dir, so create it first)
mkdir -p Scripts
cp "$SKILL_DIR/assets/templates/package_app.sh" Scripts/
cp "$SKILL_DIR/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 HelloApp.app/Contents

# Check that the binary is present and executable
file 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 HelloApp.app

# Verify the bundle passes Gatekeeper checks locally
spctl --assess --type execute --verbose HelloApp.app
```

**After notarization and stapling:**
```bash
# Confirm the staple ticket is attached
stapler validate HelloApp.app

# Re-run Gatekeeper to confirm notarization is recognised
spctl --assess --type execute --verbose 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` | A `codesign` invocation is missing the `--options runtime` flag | Ensure every `codesign` call passes `--options runtime` (the shipped `sign-and-notarize.sh` already does — check any custom signing steps). |
| Notarization status `Invalid` although the app bundle itself signed cleanly | An executable in a non-code folder such as `Contents/Resources` (a helper or CLI copied there) was never signed with the Developer ID. It keeps the linker's ad-hoc signature, or none at all on an x86_64 slice, because signing the bundle seals it as a resource without re-signing it | Sign every such Mach-O with the same Developer ID `codesign` arguments before signing the bundle, then confirm `codesign -dv` on it shows your Team ID. `xcrun notarytool log <submission-id>` (with the same credentials as `submit`) names the rejected file. |
| 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.
- Ducko ships arm64 only; its CI packages the release configuration. The general-purpose templates retain their multi-architecture options for other projects.
- 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.

From ducko-im/ducko, GPL-3.0.

More from ducko-im/ducko

Signals

Stars
7
Forks
0
Open issues
4
Last commit (this folder)
Sep 18, 2026 (1 month ago)
Last release
Oct 23, 2026 (5 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
GPL-3.0
Website
ducko.im
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from ducko-im

Cite this page

macos-spm-app-packaging skill. Agent Mart. https://agentmart.dev/skills/ducko-im-macos-spm-app-packaging (last updated 2026-10-24)