general: appstore build stuff

This commit is contained in:
Michael Freno
2026-01-13 11:31:34 -05:00
parent b7393568af
commit e379c4e3e4
18 changed files with 784 additions and 19 deletions

214
DISTRIBUTION.md Normal file
View File

@@ -0,0 +1,214 @@
# Gaze Distribution Guide
This guide explains how to build and distribute Gaze for both the Mac App Store and direct distribution with auto-updates.
## Distribution Methods
Gaze supports two distribution methods:
1. **Self-Distribution** (Direct Download) - Includes Sparkle for automatic updates
2. **Mac App Store** - Uses Apple's update mechanism, no Sparkle
## Quick Start
### Switching Between Distributions
Use the `switch_to` script to configure the project for each distribution method:
```bash
# For self-distribution with Sparkle auto-updates
./switch_to self
# For Mac App Store submission
./switch_to appstore
# Check current configuration
./switch_to status
```
### What Gets Changed
The `switch_to` script automatically manages:
**Self-Distribution Mode:**
- ✅ Adds Sparkle keys to `Info.plist` (SUPublicEDKey, SUFeedURL, etc.)
- ✅ Adds Sparkle entitlements for XPC services
- ✅ Removes `APPSTORE` compiler flag
- ✅ Enables UpdateManager with Sparkle framework
**App Store Mode:**
- ✅ Removes all Sparkle keys from `Info.plist`
- ✅ Removes Sparkle entitlements
- ✅ Adds `-D APPSTORE` compiler flag
- ✅ Disables Sparkle code at compile time
## Building for Self-Distribution
```bash
# 1. Switch to self-distribution mode
./switch_to self
```
The script will:
- Prompt for version bump (major/minor/patch)
- Build and code sign with Developer ID
- Notarize the app with Apple
- Create a signed DMG
- Generate Sparkle appcast with EdDSA signature
- (Optional) Upload to S3 if credentials are configured
## Building for Mac App Store
```bash
# 1. Switch to App Store mode
./switch_to appstore
# 2. Add Run Script Phase in Xcode (one-time setup)
# See section below
# 3. Archive and distribute via Xcode
# Product → Archive
# Window → Organizer → Distribute App → App Store Connect
```
### Required: Run Script Phase
For App Store builds, you **must** add this Run Script phase in Xcode:
1. Open Gaze.xcodeproj in Xcode
2. Select the Gaze target → Build Phases
3. Click + → New Run Script Phase
4. Name it: "Remove Sparkle for App Store"
5. Place it **after** "Embed Frameworks"
6. Add this script:
```bash
#!/bin/bash
if [[ "${OTHER_SWIFT_FLAGS}" == *"APPSTORE"* ]]; then
echo "Removing Sparkle framework for App Store build..."
rm -rf "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework"
echo "Sparkle framework removed successfully"
fi
```
This ensures Sparkle.framework is removed from the app bundle before submission.
## Configuration Files
Configuration backups are stored in `.distribution_configs/`:
- `.distribution_configs/appstore/` - App Store configuration
- `.distribution_configs/self/` - Self-distribution configuration
These backups are created automatically and used when switching between modes.
## Validation
Before submitting to App Store Connect, verify your configuration:
```bash
./switch_to status
```
Expected output for App Store:
```
Info.plist: App Store (no Sparkle keys)
Entitlements: App Store (no Sparkle exceptions)
Build Settings: App Store (has APPSTORE flag)
```
Expected output for Self-Distribution:
```
Info.plist: Self-Distribution (has Sparkle keys)
Entitlements: Self-Distribution (has Sparkle exceptions)
Build Settings: Self-Distribution (no APPSTORE flag)
```
## Troubleshooting
### App Store Validation Fails
**Error: "App sandbox not enabled" with Sparkle executables**
- Solution: Make sure you ran `./switch_to appstore` and added the Run Script phase
**Error: "Bad Bundle Executable" or "CFBundlePackageType"**
- Solution: These are now fixed in the Info.plist
**Error: Still seeing Sparkle in the build**
- Solution: Clean build folder (⌘⇧K) and rebuild
### Self-Distribution Issues
**Sparkle updates not working**
- Verify: `./switch_to status` shows "Self-Distribution" mode
- Check: Info.plist contains SUPublicEDKey and SUFeedURL
- Verify: Appcast is accessible at the SUFeedURL
**Code signing issues**
- Check `.env` file has correct credentials
- Verify Developer ID certificate: `security find-identity -v -p codesigning`
## Environment Variables
For self-distribution, create a `.env` file with:
```bash
# Required for code signing
DEVELOPER_ID_APPLICATION="Developer ID Application: Your Name (TEAM_ID)"
APPLE_TEAM_ID="XXXXXXXXXX"
# Required for notarization
NOTARY_KEYCHAIN_PROFILE="notary-profile"
# Optional for S3 upload
AWS_ACCESS_KEY_ID="your-key"
AWS_SECRET_ACCESS_KEY="your-secret"
AWS_BUCKET_NAME="your-bucket"
AWS_REGION="us-east-1"
```
Setup notarization profile (one-time):
```bash
xcrun notarytool store-credentials "notary-profile" \
--apple-id "your@email.com" \
--team-id "TEAM_ID"
```
## Version Management
The `self_distribute` script handles version bumping:
- **Major** (X.0.0) - Breaking changes
- **Minor** (x.X.0) - New features
- **Patch** (x.x.X) - Bug fixes
- **Custom** - Any version string
- **Keep** - Increment build number only
Git tags are created automatically for new versions.
## Testing
### Test Self-Distribution Build
```bash
./switch_to self
# Test the DMG on a clean macOS system
```
### Test App Store Build
```bash
./switch_to appstore
# Archive in Xcode
# Use TestFlight for testing before release
```
## Best Practices
1. **Always use `switch_to`** - Don't manually edit configuration files
2. **Check status before building** - Use `./switch_to status`
3. **Clean builds** - Run Clean Build Folder when switching modes
4. **Test thoroughly** - Test both distribution methods separately
5. **Commit before switching** - Use git to track configuration changes
## Support
For issues or questions:
- GitHub Issues: https://github.com/mikefreno/Gaze/issues
- Check AGENTS.md for development guidelines