vibetunnel/mac/docs/RELEASE-LESSONS.md
Peter Steinberger 83b586f6f6 Improve release scripts based on beta 3 lessons learned
- Always use --account VibeTunnel for Sparkle signing
- Add automatic DMG volume cleanup to prevent resource errors
- Better handling of CHANGELOG.md location (check both mac/ and root)
- Add comprehensive RELEASE-LESSONS.md with all gotchas
- Add signature verification step to release process
- Improve error messages and debugging output
- Pass SPARKLE_ACCOUNT environment variable through scripts
2025-06-23 04:57:35 +02:00

6.1 KiB

VibeTunnel Release Lessons Learned

This document captures important lessons learned from the VibeTunnel release process and common issues that can occur.

Critical Issues and Solutions

1. Sparkle Signing Account Issues

Problem: The sign_update command may use the wrong signing key from your Keychain if you have multiple EdDSA keys configured.

Symptoms:

  • Sparkle update verification fails
  • Error messages about invalid signatures
  • Updates don't appear in the app even though appcast is updated

Solution:

# Always specify the account explicitly
export SPARKLE_ACCOUNT="VibeTunnel"
./scripts/release.sh stable

Prevention: The release script now sets SPARKLE_ACCOUNT environment variable automatically.

2. File Location Confusion

Problem: Files are not always where scripts expect them to be.

Key Locations:

  • Appcast files: Located in project root (/vibetunnel/), NOT in mac/
    • appcast.xml
    • appcast-prerelease.xml
  • CHANGELOG.md: Can be in either:
    • mac/CHANGELOG.md (preferred by release script)
    • Project root /vibetunnel/CHANGELOG.md (common location)
  • Sparkle private key: Usually in mac/private/sparkle_private_key

Solution: The scripts now check multiple locations and provide clear error messages.

3. Stuck DMG Volumes

Problem: "Resource temporarily unavailable" errors when creating DMG.

Symptoms:

  • hdiutil: create failed - Resource temporarily unavailable
  • Multiple VibeTunnel volumes visible in Finder
  • DMG creation fails repeatedly

Solution:

# Manually unmount all VibeTunnel volumes
for volume in /Volumes/VibeTunnel*; do
    hdiutil detach "$volume" -force
done

# Kill any stuck DMG processes
pkill -f "VibeTunnel.*\.dmg"

Prevention: Scripts now clean up volumes automatically before DMG creation.

4. Build Number Already Exists

Problem: Sparkle requires unique build numbers for each release.

Solution:

  1. Check existing build numbers:
    grep -E '<sparkle:version>[0-9]+</sparkle:version>' ../appcast*.xml
    
  2. Update mac/VibeTunnel/version.xcconfig:
    CURRENT_PROJECT_VERSION = <new_unique_number>
    

5. Notarization Failures

Problem: App notarization fails or takes too long.

Common Causes:

  • Missing API credentials
  • Network issues
  • Apple service outages
  • Unsigned frameworks or binaries

Solution:

# Check notarization status
xcrun notarytool history --key-id "$APP_STORE_CONNECT_KEY_ID" \
    --key "$APP_STORE_CONNECT_API_KEY_P8" \
    --issuer-id "$APP_STORE_CONNECT_ISSUER_ID"

# Get detailed log for failed submission
xcrun notarytool log <submission-id> --key-id ...

6. GitHub Release Already Exists

Problem: Tag or release already exists on GitHub.

Solution: The release script now prompts you to:

  1. Delete the existing release and tag
  2. Cancel the release

Prevention: Always pull latest changes before releasing.

Pre-Release Checklist

Before running ./scripts/release.sh:

  1. Environment Setup:

    # Ensure you're on main branch
    git checkout main
    git pull --rebase origin main
    
    # Check for uncommitted changes
    git status
    
    # Set environment variables
    export SPARKLE_ACCOUNT="VibeTunnel"
    export APP_STORE_CONNECT_API_KEY_P8="..."
    export APP_STORE_CONNECT_KEY_ID="..."
    export APP_STORE_CONNECT_ISSUER_ID="..."
    
  2. File Verification:

    • CHANGELOG.md exists and has entry for new version
    • version.xcconfig has unique build number
    • Sparkle private key exists at expected location
    • No stuck DMG volumes in /Volumes/
  3. Clean Build:

    ./scripts/clean.sh
    rm -rf ~/Library/Developer/Xcode/DerivedData/VibeTunnel-*
    

Common Commands

Test Sparkle Signature

# Find sign_update binary
find . -name sign_update -type f

# Test signing with specific account
./path/to/sign_update file.dmg -f private/sparkle_private_key -p --account VibeTunnel

Verify Appcast URLs

# Check that appcast files are accessible
curl -I https://raw.githubusercontent.com/amantus-ai/vibetunnel/main/appcast.xml
curl -I https://raw.githubusercontent.com/amantus-ai/vibetunnel/main/appcast-prerelease.xml

Manual Appcast Generation

# If automatic generation fails
cd mac
export SPARKLE_ACCOUNT="VibeTunnel"
./scripts/generate-appcast.sh

Post-Release Verification

  1. Check GitHub Release:

    • Verify assets are attached
    • Check file sizes match
    • Ensure release notes are formatted correctly
  2. Test Update in App:

    • Install previous version
    • Check for updates
    • Verify update downloads and installs
    • Check signature verification in Console.app
  3. Monitor for Issues:

    • Watch Console.app for Sparkle errors
    • Check GitHub issues for user reports
    • Verify download counts on GitHub

Emergency Fixes

If Update Verification Fails

  1. Regenerate appcast with correct account:

    export SPARKLE_ACCOUNT="VibeTunnel"
    ./scripts/generate-appcast.sh
    git add ../appcast*.xml
    git commit -m "Fix appcast signatures"
    git push
    
  2. Users may need to manually download until appcast propagates

If DMG is Corrupted

  1. Re-download from GitHub
  2. Re-sign and re-notarize:
    ./scripts/sign-and-notarize.sh --sign-and-notarize
    ./scripts/notarize-dmg.sh build/VibeTunnel-*.dmg
    
  3. Upload fixed DMG to GitHub release

Key Learnings

  1. Always use explicit accounts when dealing with signing operations
  2. Clean up resources (volumes, processes) before operations
  3. Verify file locations - don't assume standard paths
  4. Test the full update flow before announcing the release
  5. Keep credentials secure but easily accessible for scripts
  6. Document everything - future you will thank present you

References