155 lines
4.0 KiB
Markdown
Executable File
155 lines
4.0 KiB
Markdown
Executable File
# Hex Release Process
|
|
|
|
## Overview
|
|
|
|
Releases are triggered by pushing git tags. The system automatically:
|
|
- Builds & signs the app
|
|
- Notarizes with Apple
|
|
- Creates DMG + ZIP artifacts
|
|
- Uploads to S3 for Sparkle updates
|
|
- Creates GitHub release
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Create and push a tag
|
|
git tag v0.2.12
|
|
git push origin v0.2.12
|
|
|
|
# GitHub Actions will automatically:
|
|
# 1. Build Hex v0.2.12
|
|
# 2. Notarize with Apple
|
|
# 3. Upload to S3 (Sparkle)
|
|
# 4. Create GitHub release with DMG + ZIP
|
|
```
|
|
|
|
## Architecture
|
|
|
|
**Tag-based versioning:**
|
|
- Tag `v0.2.12` → builds version `0.2.12`
|
|
- Updates `Info.plist` and `project.pbxproj`
|
|
- Auto-increments build number
|
|
|
|
**Effect Config system:**
|
|
```typescript
|
|
// Reads from environment variables
|
|
BUCKET=hex-updates // Default
|
|
VERSION=v0.2.12 // From git tag
|
|
APPLE_ID=your@email.com // CI only
|
|
APPLE_ID_PASSWORD=xxxx-xxxx // CI only
|
|
AWS_ACCESS_KEY_ID=... // Required
|
|
AWS_SECRET_ACCESS_KEY=... // Required
|
|
```
|
|
|
|
**Local vs CI:**
|
|
- **Local**: Uses keychain profile `AC_PASSWORD`
|
|
- **CI**: Uses `APPLE_ID` / `APPLE_ID_PASSWORD` env vars
|
|
|
|
## Local Testing
|
|
|
|
```bash
|
|
# Setup keychain profile (one-time)
|
|
xcrun notarytool store-credentials "AC_PASSWORD"
|
|
|
|
# Test release locally (doesn't upload)
|
|
cd tools
|
|
VERSION=v0.2.12-test \
|
|
AWS_ACCESS_KEY_ID=... \
|
|
AWS_SECRET_ACCESS_KEY=... \
|
|
bun run release.ts
|
|
```
|
|
|
|
## Required Secrets
|
|
|
|
Set via: `gh secret set SECRET_NAME`
|
|
|
|
### Apple (Notarization)
|
|
```bash
|
|
APPLE_ID # your@email.com
|
|
APPLE_ID_PASSWORD # App-specific password from appleid.apple.com
|
|
TEAM_ID # QC99C9JE59
|
|
```
|
|
|
|
### Code Signing
|
|
```bash
|
|
MACOS_CERTIFICATE # base64 -i cert.p12 | pbcopy
|
|
MACOS_CERTIFICATE_PWD # Certificate password
|
|
```
|
|
|
|
### AWS (S3 / Sparkle)
|
|
```bash
|
|
AWS_ACCESS_KEY_ID
|
|
AWS_SECRET_ACCESS_KEY
|
|
```
|
|
|
|
## Artifacts
|
|
|
|
Each release creates:
|
|
- `Hex-{version}.dmg` - Signed, notarized DMG
|
|
- `Hex-{version}.zip` - For Homebrew cask
|
|
- `hex-latest.dmg` - Always points to latest
|
|
- `appcast.xml` - Sparkle update feed
|
|
|
|
## Homebrew Cask
|
|
|
|
After first release, update `hex.rb`:
|
|
|
|
```bash
|
|
# Get SHA256
|
|
curl -L https://github.com/kitlangton/Hex/releases/download/v0.2.12/Hex-v0.2.12.zip -o Hex.zip
|
|
shasum -a 256 Hex.zip
|
|
|
|
# Update hex.rb with version and SHA
|
|
```
|
|
|
|
Submit to:
|
|
- **Personal tap**: `homebrew-hex` (easier)
|
|
- **Official cask**: PR to `homebrew/homebrew-cask`
|
|
|
|
## Critical Constraints
|
|
|
|
### CFBundleVersion Requirements
|
|
|
|
**NEVER manually edit CFBundleVersion or reuse build numbers.** The release pipeline automatically increments CFBundleVersion with each release to ensure Sparkle can properly generate the appcast feed.
|
|
|
|
- `updates/` directory must only contain DMGs with strictly increasing CFBundleVersion values
|
|
- Duplicate build numbers will block appcast generation and break updates for existing users
|
|
- The release script preserves the last 3 DMGs in `updates/` for delta generation
|
|
- Older versions are automatically moved to `updates/old_updates/`
|
|
|
|
If you accidentally create a release with a duplicate CFBundleVersion:
|
|
1. Delete the problematic DMG from `updates/`
|
|
2. Move any other old DMGs to `updates/old_updates/`
|
|
3. Regenerate appcast: `./bin/generate_appcast --maximum-deltas 3 updates`
|
|
4. Re-upload cleaned artifacts to S3
|
|
|
|
## Troubleshooting
|
|
|
|
### Notarization fails
|
|
- Check Apple ID credentials
|
|
- Verify app-specific password
|
|
- Ensure `TEAM_ID` is correct
|
|
|
|
### S3 upload fails
|
|
- Verify AWS credentials
|
|
- Check bucket permissions
|
|
- Ensure bucket exists
|
|
|
|
### Build fails
|
|
- Check Xcode version (16.2)
|
|
- Verify code signing setup
|
|
- Check certificate validity
|
|
|
|
### Sparkle updates not appearing
|
|
- Verify appcast.xml lists versions in descending CFBundleVersion order
|
|
- Check that CFBundleVersion values are unique and strictly increasing
|
|
- Ensure no duplicate build numbers exist in updates/
|
|
- Test feed URL: https://hex-updates.s3.amazonaws.com/appcast.xml
|
|
|
|
## Files
|
|
|
|
- `tools/release.ts` - Main release script (Effect)
|
|
- `.github/workflows/release.yml` - CI workflow
|
|
- `bin/generate_appcast` - Sparkle appcast generator
|
|
- `hex.rb` - Homebrew cask formula
|