name: release description: > Release workflow for Mori macOS workspace terminal and MoriRemote iOS app. Create releases with semantic versioned tags, update changelog, and trigger automated CI/CD builds. Use when the user asks to "release", "create a release", "tag a version", "update changelog", "prepare release", "cut a release", "publish to TestFlight", or discusses versioning and release artifacts.
Release
macOS Release
Tag Format
Use semantic versioning with v prefix: v0.1.0, v1.0.0, v1.2.3-rc.1.
Release Flow
- Update
CHANGELOG.md(see below) - Commit:
๐ docs: update CHANGELOG for vX.Y.Z - Tag:
git tag vX.Y.Z - Push:
git push origin main --tags - CI triggers
.github/workflows/release.ymlโ builds, signs, notarizes, and publishes the GitHub Release - CI updates
vaayne/homebrew-tapwith the newmoricask version and SHA-256
Required Secrets
APPLE_CERTIFICATE_P12APPLE_CERTIFICATE_PASSWORDAPPLE_IDAPPLE_TEAM_IDAPPLE_APP_PASSWORDAPPLE_DEVELOPER_NAMEHOMEBREW_TAP_TOKENโ personal access token with write access tovaayne/homebrew-tapSPARKLE_PRIVATE_KEYโ EdDSA key for Sparkle appcast signing
Homebrew Tap
Homebrew does not automatically update a third-party tap from GitHub Releases. Mori's release workflow is responsible for updating vaayne/homebrew-tap.
The tap update flow:
- Read the uploaded ZIP asset digest from the just-created GitHub Release
- Rewrite
Casks/mori.rbinvaayne/homebrew-tap - Commit and push the cask update to the tap's default branch
The generated cask installs Mori.app, depends on tmux, and exposes the embedded mori CLI via a binary stanza.
Artifacts
- macOS app ZIP:
Mori-X.Y.Z-macos-arm64.zip(signed and notarized) - macOS app DMG:
Mori-X.Y.Z-macos-arm64.dmg(signed and notarized) - GitHub Release: Auto-created by
release.ymlworkflow on tag push - Homebrew tap:
vaayne/homebrew-tapupdated automatically after a successful release
iOS Release (MoriRemote โ TestFlight)
Version Rule
For MoriRemote TestFlight uploads, keep the App Store Connect marketing version fixed at 0.3.5 unless the user explicitly asks to change it. New TestFlight uploads must reuse version 0.3.5 and only increment the build number.
Tag Format
Use semantic versioning with ios-v prefix: ios-v0.1.0, ios-v1.0.0.
Release Flow
Option A: Manual dispatch (recommended for testing)
gh workflow run release-ios.yml -R vaayne/mori \
--ref <branch> \
-f version=0.3.5 \
-f build_number=N
Option B: Tag-based
- Keep the TestFlight marketing version at
0.3.5unless explicitly told otherwise - Tag:
git tag ios-vX.Y.Z - Push:
git push origin ios-vX.Y.Z - CI triggers
.github/workflows/release-ios.ymlโ archives, exports IPA, uploads to TestFlight
Required Secrets
IOS_CERTIFICATE_P12โ Apple Distribution certificate (base64-encoded .p12)IOS_CERTIFICATE_PASSWORDโ password for the .p12APPLE_IDโ Apple ID email (shared with macOS)APPLE_APP_PASSWORDโ app-specific password (shared with macOS)APPLE_TEAM_IDโ team ID (shared with macOS)
App Store Connect
- App Name: MoriRemote
- Bundle ID:
com.vaayne.mori-remote - Apple ID: 6761400903
- SKU:
mori-remote
After Upload
- Go to App Store Connect โ MoriRemote โ TestFlight
- Wait for Apple's processing (5โ15 minutes)
- Add testers under Internal Testing group
- Testers receive a TestFlight invite on their device
Artifacts
- IPA: uploaded to GitHub Actions as artifact (90-day retention)
- TestFlight: uploaded automatically via
xcrun altool
Update Changelog
The changelog lives at CHANGELOG.md in the repo root. It follows Keep a Changelog format.
Gather changes since last tag:
git log $(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)..HEAD --oneline
gh pr list --state merged --base main --search "merged:>=$(git log -1 --format=%aI $(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD))"
Apply to CHANGELOG.md:
- Rename
[Unreleased]to[X.Y.Z] - YYYY-MM-DD - Add fresh
[Unreleased]section above - Categorize:
โจ Features,๐ Bug Fixes,โป๏ธ Refactoring,๐ Documentation,๐ฆ Dependencies - Link PRs:
([#123](https://github.com/vaayne/mori/pull/123)) - Append:
**Full Changelog**: [vPREV...vX.Y.Z](https://github.com/vaayne/mori/compare/vPREV...vX.Y.Z)