Sparkle Auto-Updates Setup Guide
June 14, 2026 · View on GitHub
This document describes the manual setup steps required to enable Sparkle auto-updates for TinyClips.
Prerequisites
- Xcode 16+
- Apple Developer ID certificate
- GitHub repository with Actions enabled
Step 1: Add Sparkle via Swift Package Manager (REQUIRED)
⚠️ IMPORTANT: Sparkle must be added via Xcode's UI. The package reference is NOT included in the repository.
- Open
mac/TinyClips.xcodeprojin Xcode - Go to File → Add Package Dependencies...
- Enter URL:
https://github.com/sparkle-project/Sparkle - Select version rule: Up to Next Major Version from
2.8.1 - Click Add Package
- In the dialog, select
Sparkleframework for theTinyClipstarget - Click Add Package
Verify Sparkle Integration
After adding, ensure:
- The Sparkle framework appears in your project's Frameworks, Libraries, and Embedded Content
- In Project Navigator, you should see Package Dependencies with Sparkle listed
- Build the project to verify no linking errors
Why Manual Addition?
Xcode's project file format is complex and version-specific. Adding SPM packages programmatically can cause project corruption. Adding via Xcode's UI ensures proper integration with your specific Xcode version.
Step 2: Generate Sparkle Keys
Sparkle uses EdDSA (Ed25519) signatures for security. Generate your key pair:
Using Sparkle's generate_keys Tool
-
After adding Sparkle via SPM, find the tools in:
- In Xcode, expand Package Dependencies → Sparkle
- Right-click and Show in Finder
- Navigate to
artifacts/sparkle/Sparkle/bin/
-
Generate keys:
cd /path/to/Sparkle/bin ./generate_keys -
The tool will:
- Generate a new private/public key pair
- Store the private key in your Keychain (Sparkle Private Key)
- Display the public key — copy this for Info.plist
-
Backup your private key (IMPORTANT):
./generate_keys -x ~/Desktop/sparkle_private_key.txtStore this backup securely — you cannot recover it if lost!
Add Public Key to Info.plist
Replace the placeholder SUPublicEDKey value in mac/TinyClips/Info.plist with your actual public key.
Step 3: Configure GitHub Secrets
Add these secrets to your GitHub repository (Settings → Secrets and variables → Actions):
Required Secrets
| Secret Name | Description | How to Get |
|---|---|---|
SPARKLE_PRIVATE_KEY | Full contents of exported private key file | From ./generate_keys -x output |
DEVELOPER_ID_CERTIFICATE_BASE64 | Base64-encoded Developer ID certificate (.p12) | Export from Keychain, then base64 -i certificate.p12 |
DEVELOPER_ID_CERTIFICATE_PASSWORD | Password for the .p12 certificate | Set when exporting |
KEYCHAIN_PASSWORD | Any strong password for temporary keychain | Generate a random password |
APPLE_ID | Your Apple ID email | Your Apple Developer account email |
APP_PASSWORD | App-specific password | Generate at appleid.apple.com → Security → App-Specific Passwords |
APPLE_TEAM_ID | Your Apple Developer Team ID | Find in developer.apple.com → Membership |
Creating the Developer ID Certificate
- Open Keychain Access
- Find your Developer ID Application certificate
- Right-click → Export
- Save as
.p12with a strong password - Convert to base64:
base64 -i DeveloperID.p12 | pbcopy - Paste into GitHub secret
DEVELOPER_ID_CERTIFICATE_BASE64
Creating App-Specific Password
- Go to appleid.apple.com
- Sign in → Security section
- Under App-Specific Passwords, click Generate Password
- Name it "TinyClips Notarization"
- Copy the generated password to
APP_PASSWORDsecret
Step 4: Enable GitHub Pages
- Go to repository Settings → Pages
- Under Source, select:
- Branch:
main - Folder:
/docs
- Branch:
- Click Save
- Wait for deployment (may take a few minutes)
- Verify appcast is accessible at:
https://jamesmontemagno.github.io/tiny-clips/appcast.xml
Step 5: Create a Release
To trigger the workflow and create a release:
# Tag a version
git tag v1.0.0
git push origin v1.0.0
The GitHub Action will:
- Build the app with Release configuration
- Sign with Developer ID certificate
- Notarize with Apple
- Create a signed ZIP
- Generate the appcast.xml with Sparkle tools
- Create a GitHub Release with the artifacts
- Deploy appcast to GitHub Pages
Version Numbering
CFBundleShortVersionString(Marketing Version):1.0.0,1.0.1,1.1.0CFBundleVersion(Build Number): Auto-incremented by CI viagithub.run_number
Sparkle compares versions semantically. Use standard semver format.
Automatic Update Checks (Direct Distribution Only)
Automatic update checking is off by default. Users are prompted to enable it during the first-run onboarding wizard (step 5, "Automatic Updates"). The setting can also be toggled at any time in Settings → About → Automatically check for updates.
How It Works
- The preference is stored in UserDefaults under
autoUpdateEnabled. - When enabled, Sparkle checks the appcast feed periodically and presents its standard update alert when a newer version is found.
- The update alert displays inline release notes (from the appcast's
<description>element) and a link to the GitHub release. - Users can choose to Install, Skip This Version, or Remind Me Later.
- When disabled, Sparkle does not check automatically. Users can still trigger a manual check via the "Check for Updates…" button.
Release Notes in the Appcast
The release workflow automatically injects release notes into each appcast item:
- Source: The
CHANGELOG.mdentry matching the release tag (e.g.,## v1.2.3 - ...). Falls back togit logcommit messages if no entry is found. - Format: Converted to HTML with
<h3>section headings (Added, Improved, Fixed, etc.) and<ul>/<li>bullet lists. - Appcast elements:
<description><![CDATA[...]]></description>— inline HTML shown in Sparkle's update dialog.<sparkle:releaseNotesLink>— links to the GitHub release page as a fallback.
MAS Target
None of this applies to the Mac App Store target. All Sparkle code paths are behind #if !APPSTORE / #if canImport(Sparkle) guards. The onboarding wizard skips the updates step on the MAS build.