SpeakType releases are fully automated with a single command. The script handles everything: version bumping, building, signing, notarization, and uploading.
Use your judgment, but a release is usually warranted when:
- A user-visible feature or UX improvement lands
- A bugfix affects multiple users or a core flow
- Performance or stability improvements are measurable
1. Code Signing Certificate
Verify you have a Developer ID Application certificate:
security find-identity -v -p codesigning
# Should show: "Developer ID Application: ..."2. App-Specific Password
Get from appleid.apple.com → Security → App-Specific Passwords
Note: The release script will prompt for this on first run and store it in Keychain.
3. GitHub CLI (optional)
brew install gh
gh auth login./scripts/release.shWhat happens:
- ✅ Checks for uncommitted changes - Script fails if you have any uncommitted work
- ✅ Auto-bumps patch version (e.g., 1.0.14 → 1.0.15)
- ✅ Updates version in Xcode project - MARKETING_VERSION and CURRENT_PROJECT_VERSION
- ✅ Updates CHANGELOG with release date
- ✅ Commits changes locally - Creates commit and git tag (not pushed yet!)
- ✅ Builds and signs the app - Release configuration with Developer ID
- ✅ Creates and signs DMG
- ✅ Submits to Apple for notarization (~2-5 minutes)
- ✅ Staples the notarization ticket
- ✅ Prompts: Push to GitHub? - Only after successful build
- ✅ Prompts: Upload release? - Only if you pushed
Total time: ~6-8 minutes
./scripts/release.sh 2.0.0Same workflow, but uses your specified version.
The script prompts you at key decision points:
-
🔼 Push v1.0.15 to GitHub? (y/n)
- Asked AFTER successful build/notarization
- If you say
n, the script exits and tells you how to undo the local commit - Safe to say
nto test the DMG first
-
📦 Upload DMG to GitHub releases? (y/n)
- Only asked if you said
yto push - Uses GitHub CLI to create the release
- You can always upload manually later with:
gh release create v1.0.15 SpeakType-1.0.15.dmg --generate-notes
- Only asked if you said
After the release, verify on a different Mac:
# Download and open the DMG
# Drag SpeakType.app to Applications
# Double-click to open - should NOT show Gatekeeper warning
# Verify signature
codesign -dv --verbose=4 /Applications/SpeakType.app
# Verify notarization
spctl -a -vv /Applications/SpeakType.app
# Should show: accepted, source=Notarized Developer IDError: HTTP status code: 401. Unable to authenticate.
Fix: Regenerate your app-specific password and re-run the keychain setup:
xcrun notarytool store-credentials "AC_PASSWORD" \
--apple-id "mail2048labs@gmail.com" \
--team-id "PCV4UMSRZX" \
--password "NEW_PASSWORD_HERE"Check the submission logs:
xcrun notarytool history --keychain-profile "AC_PASSWORD"
# Get the submission ID, then:
xcrun notarytool log <submission-id> --keychain-profile "AC_PASSWORD"Common issues:
- Missing Hardened Runtime entitlement
- Invalid code signature
- Unsigned frameworks/libraries
See CODESIGNING.md for detailed troubleshooting.
If Xcode build fails:
- Clean build folder:
xcodebuild clean -scheme speaktype - Verify certificate is valid:
security find-identity -v -p codesigning - Check Xcode version:
xcodebuild -version
- DMG files are NOT committed to git - they're large and shouldn't be version-controlled
- GitHub Actions workflow is disabled - all release work happens locally
- Notarization typically takes 2-5 minutes - Apple's servers process the app
- The DMG is stapled - notarization ticket embedded, works offline