---
name: release-macos
description: Archive, notarize, and release a macOS app — creates GitHub release, uploads zip, updates Homebrew cask.
user-invocable: true
disable-model-invocation: true
argument-hint: "<version>"
---

Run the full macOS app release pipeline for the current project. This skill handles archive, export, notarization, GitHub release, and Homebrew cask update.

## Prerequisites

The project must have:
- An Xcode project (`.xcodeproj`) with a scheme matching the app name
- A `config/exportOptions.plist` for Developer ID signing
- A notarytool keychain profile named `notarytool` (`xcrun notarytool store-credentials`)
- `gh` CLI authenticated for GitHub releases
- A Homebrew tap repo at `../tap/Casks/<app-name>.rb` (for cask update)

## Steps

Given the version argument `$VERSION`:

1. **Detect project settings** — find the `.xcodeproj`, scheme name, and app name from the working directory. Look at the justfile, project.yml, or xcodeproj for these values.

2. **Archive** the app:
```bash
xcodebuild \
  -project $PROJECT \
  -scheme $SCHEME \
  -configuration Release \
  -archivePath build/archive/$APP_NAME-$VERSION.xcarchive \
  archive 2>&1 | xcbeautify
```

3. **Export** the signed .app from the archive:
```bash
xcodebuild -exportArchive \
  -archivePath build/archive/$APP_NAME-$VERSION.xcarchive \
  -exportPath build/export/$APP_NAME-$VERSION \
  -exportOptionsPlist config/exportOptions.plist 2>&1 | xcbeautify
```

4. **Notarize** the app:
```bash
temp_zip=$(mktemp -d)/$APP_NAME.zip
ditto -c -k --sequesterRsrc --keepParent "build/export/$APP_NAME-$VERSION/$APP_NAME.app" "$temp_zip"
xcrun notarytool submit "$temp_zip" --keychain-profile "notarytool" --wait
xcrun stapler staple "build/export/$APP_NAME-$VERSION/$APP_NAME.app"
rm -f "$temp_zip"
```

5. **Create dist zip** (after stapling):
```bash
mkdir -p build/dist
ditto -c -k --sequesterRsrc --keepParent "build/export/$APP_NAME-$VERSION/$APP_NAME.app" "build/dist/$APP_NAME-$VERSION.zip"
```

6. **Create GitHub release** (draft):
```bash
gh release create $VERSION --draft --title "$VERSION" --notes "Release $VERSION"
```
Skip if release already exists.

7. **Upload** the zip to the release:
```bash
gh release upload $VERSION "build/dist/$APP_NAME-$VERSION.zip" --clobber
```

8. **Update Homebrew cask** (if `../tap/Casks/` exists):
```bash
sha256=$(shasum -a 256 "build/dist/$APP_NAME-$VERSION.zip" | cut -d' ' -f1)
cask_file=$(find ../tap/Casks -name "*.rb" | head -1)
sed -i '' -e "s/version \"[^\"]*\"/version \"$VERSION\"/" -e "s/sha256 \"[^\"]*\"/sha256 \"$sha256\"/" "$cask_file"
```

## Important

- Always confirm with the user before starting (this uploads to GitHub and modifies external repos)
- Run each step sequentially — each depends on the previous
- If notarization fails, do NOT proceed to zip/upload
- Show the user the SHA256 and draft release URL when done
