mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-04 11:05:53 +00:00
258 lines
No EOL
7.9 KiB
Markdown
258 lines
No EOL
7.9 KiB
Markdown
# VibeTunnel Release Process
|
|
|
|
This guide explains how to create and publish releases for VibeTunnel, a macOS menu bar application using Sparkle 2.x for automatic updates.
|
|
|
|
## 🎯 Release Process Overview
|
|
|
|
VibeTunnel uses an automated release process that handles all the complexity of:
|
|
- Building and code signing
|
|
- Notarization with Apple
|
|
- Creating DMG disk images
|
|
- Publishing to GitHub
|
|
- Updating Sparkle appcast files
|
|
|
|
## 🚀 Creating a Release
|
|
|
|
### Step 1: Pre-flight Check
|
|
```bash
|
|
./scripts/preflight-check.sh
|
|
```
|
|
This validates your environment is ready for release.
|
|
|
|
### Step 2: Create/Update CHANGELOG.md
|
|
Before creating any release, ensure the CHANGELOG.md file exists and contains a proper section for the version being released. If this is your first release, create a CHANGELOG.md file in the project root:
|
|
|
|
```markdown
|
|
# Changelog
|
|
|
|
All notable changes to VibeTunnel will be documented in this file.
|
|
|
|
## [1.1.0] - 2025-06-10
|
|
|
|
### 🎨 UI Improvements
|
|
- **Enhanced feature** - Description of the improvement
|
|
...
|
|
```
|
|
|
|
**CRITICAL**: The appcast generation relies on the local CHANGELOG.md file, NOT the GitHub release description. The changelog must be added to CHANGELOG.md BEFORE running the release script.
|
|
|
|
### Step 3: Create the Release
|
|
```bash
|
|
# For stable releases:
|
|
./scripts/release.sh stable
|
|
|
|
# For pre-releases (beta, alpha, rc):
|
|
./scripts/release.sh beta 1 # Creates version-beta.1
|
|
./scripts/release.sh alpha 2 # Creates version-alpha.2
|
|
./scripts/release.sh rc 1 # Creates version-rc.1
|
|
```
|
|
|
|
**IMPORTANT**: The release script does NOT automatically increment build numbers. You must manually update the build number in VibeTunnel.xcodeproj before running the script, or it will fail the pre-flight check.
|
|
|
|
The script will:
|
|
1. Validate build number is unique and incrementing
|
|
2. Build, sign, and notarize the app
|
|
3. Create a DMG
|
|
4. Publish to GitHub
|
|
5. Update the appcast files with EdDSA signatures
|
|
6. Commit and push all changes
|
|
|
|
### Step 4: Verify Success
|
|
- Check the GitHub releases page
|
|
- Verify the appcast was updated correctly with proper changelog content
|
|
- Test updating from a previous version
|
|
- **Important**: Verify that the Sparkle update dialog shows the formatted changelog, not HTML tags
|
|
|
|
## ⚠️ Critical Requirements
|
|
|
|
### 1. Build Numbers MUST Increment
|
|
Sparkle uses build numbers (CFBundleVersion) to determine updates, NOT version strings!
|
|
|
|
| Version | Build | Result |
|
|
|---------|-------|--------|
|
|
| 1.0.0-beta.1 | 100 | ✅ |
|
|
| 1.0.0-beta.2 | 101 | ✅ |
|
|
| 1.0.0-beta.3 | 99 | ❌ Build went backwards |
|
|
| 1.0.0 | 101 | ❌ Duplicate build number |
|
|
|
|
### 2. Required Environment Variables
|
|
```bash
|
|
export APP_STORE_CONNECT_KEY_ID="YOUR_KEY_ID"
|
|
export APP_STORE_CONNECT_ISSUER_ID="YOUR_ISSUER_ID"
|
|
export APP_STORE_CONNECT_API_KEY_P8="-----BEGIN PRIVATE KEY-----
|
|
YOUR_PRIVATE_KEY_CONTENT
|
|
-----END PRIVATE KEY-----"
|
|
```
|
|
|
|
### 3. Prerequisites
|
|
- Xcode 16.4+ installed
|
|
- GitHub CLI authenticated: `gh auth status`
|
|
- Apple Developer ID certificate in Keychain
|
|
- Sparkle tools in `~/.local/bin/` (sign_update, generate_appcast)
|
|
|
|
## 🔐 Sparkle Configuration
|
|
|
|
### Sparkle Requirements for Non-Sandboxed Apps
|
|
|
|
VibeTunnel is not sandboxed, which simplifies Sparkle configuration:
|
|
|
|
#### 1. Entitlements (VibeTunnel.entitlements)
|
|
```xml
|
|
<!-- App is NOT sandboxed -->
|
|
<key>com.apple.security.app-sandbox</key>
|
|
<false/>
|
|
|
|
<!-- Required for code injection/library validation -->
|
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
|
<true/>
|
|
<key>com.apple.security.cs.disable-library-validation</key>
|
|
<true/>
|
|
```
|
|
|
|
#### 2. Info.plist Configuration
|
|
```swift
|
|
"SUEnableInstallerLauncherService": false, // Not needed for non-sandboxed apps
|
|
"SUEnableDownloaderService": false, // Not needed for non-sandboxed apps
|
|
```
|
|
|
|
#### 3. Code Signing Requirements
|
|
|
|
The notarization script handles all signing correctly:
|
|
1. **Do NOT use --deep flag** when signing the app
|
|
2. Sign the app with hardened runtime and entitlements
|
|
|
|
The `notarize-app.sh` script should sign the app:
|
|
```bash
|
|
# Sign the app WITHOUT --deep flag
|
|
codesign --force --sign "Developer ID Application" --entitlements VibeTunnel.entitlements --options runtime VibeTunnel.app
|
|
```
|
|
|
|
### Common Sparkle Errors and Solutions
|
|
|
|
| Error | Cause | Solution |
|
|
|-------|-------|----------|
|
|
| "You're up to date!" when update exists | Build number not incrementing | Check build numbers in appcast are correct |
|
|
| "Update installation failed" | Signing or permission issues | Verify app signature and entitlements |
|
|
| "Cannot verify update signature" | EdDSA key mismatch | Ensure sparkle-public-ed-key.txt matches private key |
|
|
|
|
## 📋 Update Channels
|
|
|
|
VibeTunnel supports two update channels:
|
|
|
|
1. **Stable Channel** (`appcast.xml`)
|
|
- Production releases only
|
|
- Default for all users
|
|
|
|
2. **Pre-release Channel** (`appcast-prerelease.xml`)
|
|
- Includes beta, alpha, and RC versions
|
|
- Users opt-in via Settings
|
|
|
|
## 🐛 Common Issues and Solutions
|
|
|
|
### Appcast Shows HTML Tags Instead of Formatted Text
|
|
**Problem**: Sparkle update dialog shows escaped HTML like `<h2>` instead of formatted text.
|
|
|
|
**Root Cause**: The generate-appcast.sh script is escaping HTML content from GitHub release descriptions.
|
|
|
|
**Solution**:
|
|
1. Ensure CHANGELOG.md has the proper section for the release version BEFORE running release script
|
|
2. The appcast should use local CHANGELOG.md, not GitHub release body
|
|
3. If the appcast is wrong, manually fix the generate-appcast.sh script to use local changelog content
|
|
|
|
### Build Numbers Not Incrementing
|
|
**Problem**: Sparkle doesn't detect new version as an update.
|
|
|
|
**Solution**: Always increment the build number in the Xcode project before releasing.
|
|
|
|
## 🛠️ Manual Process (If Needed)
|
|
|
|
If the automated script fails, here's the manual process:
|
|
|
|
### 1. Update Build Number
|
|
Edit the project build settings in Xcode:
|
|
- Open VibeTunnel.xcodeproj
|
|
- Select the project
|
|
- Update CURRENT_PROJECT_VERSION (build number)
|
|
|
|
### 2. Clean and Build
|
|
```bash
|
|
rm -rf build DerivedData .build
|
|
./scripts/build.sh --configuration Release
|
|
```
|
|
|
|
### 3. Sign and Notarize
|
|
```bash
|
|
./scripts/notarize-app.sh build/Build/Products/Release/VibeTunnel.app
|
|
```
|
|
|
|
### 4. Create DMG
|
|
```bash
|
|
./scripts/create-dmg.sh
|
|
```
|
|
|
|
### 5. Sign DMG for Sparkle
|
|
```bash
|
|
export PATH="$HOME/.local/bin:$PATH"
|
|
sign_update build/VibeTunnel-X.X.X.dmg
|
|
# Copy the sparkle:edSignature value
|
|
```
|
|
|
|
### 6. Create GitHub Release
|
|
```bash
|
|
gh release create "v1.0.0-beta.1" \
|
|
--title "VibeTunnel 1.0.0-beta.1" \
|
|
--notes "Beta release 1" \
|
|
--prerelease \
|
|
build/VibeTunnel-1.0.0-beta.1.dmg
|
|
```
|
|
|
|
### 7. Update Appcast
|
|
```bash
|
|
./scripts/update-appcast.sh
|
|
git add appcast*.xml
|
|
git commit -m "Update appcast for v1.0.0-beta.1"
|
|
git push
|
|
```
|
|
|
|
## 🔍 Troubleshooting
|
|
|
|
### Debug Sparkle Updates
|
|
```bash
|
|
# Monitor VibeTunnel logs
|
|
log stream --predicate 'process == "VibeTunnel"' --level debug
|
|
|
|
# Check XPC errors
|
|
log stream --predicate 'process == "VibeTunnel"' | grep -i -E "(sparkle|xpc|installer)"
|
|
|
|
# Verify XPC services
|
|
codesign -dvv "VibeTunnel.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
|
|
```
|
|
|
|
### Verify Signing and Notarization
|
|
```bash
|
|
# Check app signature
|
|
./scripts/verify-app.sh build/VibeTunnel-1.0.0.dmg
|
|
|
|
# Verify XPC bundle IDs (should be org.sparkle-project.*)
|
|
/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" \
|
|
"VibeTunnel.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc/Contents/Info.plist"
|
|
```
|
|
|
|
### Appcast Issues
|
|
```bash
|
|
# Verify appcast has correct build numbers
|
|
./scripts/verify-appcast.sh
|
|
|
|
# Check if build number is "1" (common bug)
|
|
grep '<sparkle:version>' appcast-prerelease.xml
|
|
```
|
|
|
|
## 📚 Important Links
|
|
|
|
- [Sparkle Sandboxing Guide](https://sparkle-project.org/documentation/sandboxing/)
|
|
- [Sparkle Code Signing](https://sparkle-project.org/documentation/sandboxing/#code-signing)
|
|
- [Apple Notarization](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution)
|
|
|
|
---
|
|
|
|
**Remember**: Always use the automated release script, ensure build numbers increment, and test updates before announcing! |