Skip to content

Build and Release

thefourCraft edited this page Jun 21, 2026 · 1 revision

Build & Release

Layout

The Xcode project is at the repository root (Zerm.xcodeproj). It used to live under native-macos/ to coexist with a since-removed Tauri prototype; that nesting is gone.

Prerequisites

  • Xcode 16+ (the project is developed on Xcode 26.x)
  • macOS 14.4+ (Apple Silicon recommended)
  • Native dependency XCFrameworks under $(HOME)/Zerm-Dependencies/ (whisper.cpp, sherpa-onnx, llama)

Build from source

# From the repo root
xcodebuild -project Zerm.xcodeproj -scheme Zerm -configuration Debug \
  CODE_SIGNING_ALLOWED=NO build

Local signing has no provisioning profile, so disable code signing for plain builds.

Makefile (local install)

make install      # build Debug (LOCAL_BUILD), ad-hoc sign, copy to /Applications, reset TCC
make sherpa       # (re)build the sherpa-onnx XCFrameworks

make install ad-hoc signs the app, which changes its signature — so macOS resets TCC and you must re-grant Accessibility and Screen Recording under Zerm → Permissions after each install. User data (SwiftData stores, settings, downloaded models) lives outside the bundle and is preserved.

A LOCAL_BUILD stores API keys in UserDefaults rather than the Keychain so the ad-hoc app can read them.

Project structure notes

  • Pure-Swift files auto-compile via PBXFileSystemSynchronizedRootGroup — adding a .swift file needs no project.pbxproj edit.
  • XCFrameworks do need pbxproj wiring. llama and whisper are dynamic → embedded + signed; sherpa-onnx/onnxruntime are static → linked only. ONNX Runtime is not merged into libsherpa-onnx.a, so both must be linked (the _OrtGetApiBase gotcha).

CI

.github/workflows/ci.yml runs on every push/PR: Swift build (macOS), website lint, and a secret/PII scan. Secret detection is also done by the GitGuardian app check and CodeQL.

The repo's Actions policy is selected + sha_pinning_required: true — every uses: must be pinned to a full commit SHA, and only github-owned/verified/allow-listed actions may run. Unpinned or disallowed actions cause an immediate startup_failure.

Releases & updates

  • Updates use Sparkle 2.x; the appcast is appcast.xml and the feed URL is set in Info.plist (SUFeedURL). Automatic checks are currently disabled (SUEnableAutomaticChecks = false), so existing installs are not auto-updated.
  • Releases are cut as GitHub releases (currently drafts). A publicly installable, auto-updating build needs a Developer ID-signed + notarized DMG and a Sparkle EdDSA signing key for the appcast — these are the outstanding prerequisites for public distribution.
  • Local users update by pulling and rebuilding (make install).

See: Architecture

Clone this wiki locally