This document provides comprehensive guidance for managing CodeLooper releases, including the advanced beta/pre-release system adapted from VibeMeter's release process.
- Release System Overview
- Quick Start
- Release Types
- Version Management
- Release Process
- Dual-Channel Update System
- Scripts Reference
- Verification
- Troubleshooting
- Advanced Topics
CodeLooper uses a sophisticated dual-channel release system that supports:
- Stable releases: Production-ready builds for general users
- Pre-release builds: Beta, alpha, and RC builds for testing
- Automated version bumping: Semantic versioning with pre-release support
- Dual appcast feeds: Separate update channels for stable and pre-release users
- Build validation: Comprehensive pre-flight and verification checks
- GitHub integration: Automated release creation and asset management
- ✅ IS_PRERELEASE_BUILD system: Build-time flag determines update channel behavior
- ✅ Automatic channel detection: Apps automatically default to appropriate update channel
- ✅ User override capability: Users can manually switch between stable/pre-release channels
- ✅ Comprehensive validation: Multi-layer verification ensures release quality
- ✅ GitHub automation: Complete CI/CD-ready release pipeline
# 1. Bump version
./scripts/version.sh --patch
# 2. Create stable release
./scripts/release.sh stable# 1. Create beta version
./scripts/version.sh --prerelease beta
# 2. Create beta release
./scripts/release.sh beta 1# Run comprehensive system verification
./scripts/verify-prerelease-system.sh- Purpose: Production-ready builds for general users
- Update Channel: Stable appcast only (
appcast.xml) - IS_PRERELEASE_BUILD:
NO - Example:
2.1.0
./scripts/release.sh stable- Purpose: Feature-complete builds for testing
- Update Channel: Pre-release appcast (
appcast-prerelease.xml) - IS_PRERELEASE_BUILD:
YES - Example:
2.1.0-beta.1
./scripts/release.sh beta 1
./scripts/release.sh beta 2- Purpose: Early development builds with new features
- Update Channel: Pre-release appcast (
appcast-prerelease.xml) - IS_PRERELEASE_BUILD:
YES - Example:
2.1.0-alpha.1
./scripts/release.sh alpha 1
./scripts/release.sh alpha 2- Purpose: Final testing before stable release
- Update Channel: Pre-release appcast (
appcast-prerelease.xml) - IS_PRERELEASE_BUILD:
YES - Example:
2.1.0-rc.1
./scripts/release.sh rc 1
./scripts/release.sh rc 2CodeLooper follows semantic versioning (MAJOR.MINOR.PATCH):
- MAJOR: Breaking changes or significant feature additions
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
# Automatic semantic version bumping
./scripts/version.sh --major # 1.2.3 → 2.0.0
./scripts/version.sh --minor # 1.2.3 → 1.3.0
./scripts/version.sh --patch # 1.2.3 → 1.2.4
# Pre-release versions
./scripts/version.sh --prerelease beta # 1.2.3 → 1.2.3-beta.1
./scripts/version.sh --prerelease alpha # 1.2.3 → 1.2.3-alpha.1
./scripts/version.sh --prerelease rc # 1.2.3 → 1.2.3-rc.1
# Build number only
./scripts/version.sh --build # Increment build number only
# Set specific version
./scripts/version.sh --set "2.0.0"
# Show current version
./scripts/version.sh --currentThe release process follows these automated steps:
-
Pre-flight Check (
preflight-check.sh)- Git repository validation
- Required tools verification
- Code signing certificates
- Build number uniqueness
-
Project Generation (
generate-xcproj.sh)- Tuist project regeneration
- Automatic commit of changes
-
Application Building
- Clean build with appropriate flags
IS_PRERELEASE_BUILDenvironment variable
-
Code Signing & Notarization
- Developer ID signing
- Apple notarization process
-
DMG Creation
- Distribution package creation
- Asset signing
-
GitHub Release
- Release creation with proper metadata
- Asset upload and tagging
-
Appcast Update
- Dual-channel feed generation
- EdDSA signature creation
# 1. Create new beta version
./scripts/version.sh --prerelease beta
# Output: Updated to 2.1.0-beta.1 (build 45)
# 2. Commit version change
git add Project.swift
git commit -m "Bump version to 2.1.0-beta.1 (45)"
# 3. Create beta release
./scripts/release.sh beta 1
# Output: Complete release pipeline execution
# 4. Verify release
./scripts/verify-app.sh path/to/CodeLooper.app
./scripts/verify-appcast.sh┌─────────────────┐ ┌──────────────────────┐
│ Stable Users │────▶│ appcast.xml │
│ │ │ (stable only) │
└─────────────────┘ └──────────────────────┘
┌─────────────────┐ ┌──────────────────────┐
│ Pre-release │────▶│ appcast-prerelease │
│ Users │ │ .xml (all releases) │
└─────────────────┘ └──────────────────────┘
The UpdateChannel.swift system automatically detects the appropriate channel:
- Build-time flag check:
IS_PRERELEASE_BUILDin Info.plist - Version string analysis: Keywords like "beta", "alpha", "rc"
- Default fallback: Stable channel for production builds
Users can manually switch update channels in the app settings, allowing:
- Beta users to switch back to stable releases
- Stable users to opt into pre-release updates
| Script | Purpose | Usage |
|---|---|---|
release.sh |
Main release automation | ./scripts/release.sh <type> [number] |
version.sh |
Version management | ./scripts/version.sh [options] |
preflight-check.sh |
Pre-release validation | ./scripts/preflight-check.sh |
generate-appcast.sh |
Dual appcast generation | ./scripts/generate-appcast.sh |
| Script | Purpose | Usage |
|---|---|---|
verify-app.sh |
App bundle verification | ./scripts/verify-app.sh <app-path> |
verify-appcast.sh |
Appcast validation | ./scripts/verify-appcast.sh |
verify-prerelease-system.sh |
End-to-end system check | ./scripts/verify-prerelease-system.sh |
| Script | Purpose | Status |
|---|---|---|
update-appcast.sh |
Simple appcast update | generate-appcast.sh |
release-local.sh |
Local release testing | release.sh |
Before any release, run the comprehensive verification:
# System verification
./scripts/verify-prerelease-system.sh
# Pre-flight checks
./scripts/preflight-check.sh
# App verification (after build)
./scripts/verify-app.sh build/CodeLooper.app
# Appcast verification
./scripts/verify-appcast.sh- All verification scripts pass
- Build numbers are unique
- Code signing certificates valid
- Appcast files are valid XML
- Download URLs are accessible
- Pre-release flag correctly set
- GitHub releases created properly
# Error: Build number already exists
# Solution: Increment build number manually
./scripts/version.sh --build# Error: Code signing failed
# Check certificates
security find-identity -v -p codesigning
# Set environment variables for notarization
export APPLE_ID="your-apple-id@example.com"
export APPLE_PASSWORD="app-specific-password"# Error: Cannot generate signatures
# Install Sparkle tools
brew install sparkle
# Set private key path
export SPARKLE_PRIVATE_KEY_PATH="$HOME/.sparkle_private_key"# Error: GitHub API authentication failed
# Login to GitHub CLI
gh auth login
# Verify authentication
gh auth statusEnable debug output for troubleshooting:
# Enable verbose output
export DEBUG=1
# Run with debug information
./scripts/release.sh beta 1Override default settings with environment variables:
# Custom GitHub repository
export GITHUB_REPO="custom-repo"
export GITHUB_USERNAME="custom-user"
# Custom signing configuration
export DEVELOPMENT_TEAM="YOUR_TEAM_ID"
export CODE_SIGN_IDENTITY="Apple Distribution"
# Custom Sparkle configuration
export SPARKLE_PRIVATE_KEY_PATH="/path/to/private/key"
export KEYCHAIN_KEY_NAME="Custom-Sparkle-Key"Example GitHub Actions workflow:
name: Release
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release type'
required: true
type: choice
options: ['stable', 'beta', 'alpha', 'rc']
release_number:
description: 'Release number (for pre-releases)'
required: false
jobs:
release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup environment
run: |
echo "APPLE_ID=${{ secrets.APPLE_ID }}" >> $GITHUB_ENV
echo "APPLE_PASSWORD=${{ secrets.APPLE_PASSWORD }}" >> $GITHUB_ENV
- name: Run release
run: |
./scripts/release.sh ${{ inputs.release_type }} ${{ inputs.release_number }}While GitHub serves the default appcast files, you can host them elsewhere:
- Update
UpdateChannel.swiftappcast URLs - Configure your hosting service
- Update
generate-appcast.shupload destination
If migrating from a single-channel system:
- Run the verification system:
./scripts/verify-prerelease-system.sh - Generate initial dual appcasts:
./scripts/generate-appcast.sh - Update app to use
UpdateChannel.swift - Test both channels thoroughly
For questions or issues with the release system:
- Check the verification scripts output
- Review the troubleshooting section
- Consult the individual script documentation
- File an issue on the GitHub repository
This release system was adapted from VibeMeter's advanced release management process and customized for CodeLooper's specific needs.