Use when releasing a new version of the Vozcribe macOS app via Homebrew. Triggers: "release mac", "publish mac", "update homebrew", "bump mac version"
Build, ad-hoc sign, package, and release Vozcribe macOS app so users can install/upgrade via brew tap ijasiqbal/vozcribe && brew install --cask vozcribe.
gh CLI authenticatedcreate-dmg installed (brew install create-dmg)Ijasiqbal/homebrew-vozcribe push accessAlways check the current cask version first — the Xcode project's MARKETING_VERSION can drift out of sync with the Homebrew cask, and shipping a lower number than what's already published is a downgrade (Homebrew won't update existing installs).
grep '^ version' "$(brew --repository ijasiqbal/vozcribe)/Casks/vozcribe.rb"
The new version must be strictly greater than what's printed. Pick the next increment (e.g. 1.13 → 1.14) unless there's a reason to jump.
cd /Users/ijas/Documents/whisperType/VoxType-Mac
bash build-release.sh <VERSION> # e.g. bash build-release.sh 1.14
The script produces the .app in build/Vozcribe.xcarchive/Products/Applications/Vozcribe.app.
Critical step. The build output is signed with an Apple Development certificate, which doesn't work on other users' Macs ("The application can't be opened" error). Ad-hoc signing makes it work everywhere:
codesign --force --deep --sign - \
build/Vozcribe.xcarchive/Products/Applications/Vozcribe.app
Verify it says Signature=adhoc:
codesign -dvv build/Vozcribe.xcarchive/Products/Applications/Vozcribe.app 2>&1 | grep Signature
The Homebrew cask expects a ZIP containing Vozcribe.app directly (not a DMG inside a ZIP). GitHub Releases also doesn't accept .dmg uploads — only .zip.
(cd /Users/ijas/Documents/whisperType/VoxType-Mac/build/Vozcribe.xcarchive/Products/Applications && \
zip -r /tmp/Vozcribe-<VERSION>.zip Vozcribe.app)
shasum -a 256 /tmp/Vozcribe-<VERSION>.zip
Save the sha256 hash for step 5.
For a new release:
gh release create v<VERSION> \
/tmp/Vozcribe-<VERSION>.zip \
--repo Ijasiqbal/Vozcribe-release \
--title "Vozcribe <VERSION>" \
--notes "<release notes>"
To update an existing release (replace the zip):
gh release delete-asset v<VERSION> Vozcribe-<VERSION>.zip \
--repo Ijasiqbal/Vozcribe-release --yes
gh release upload v<VERSION> /tmp/Vozcribe-<VERSION>.zip \
--repo Ijasiqbal/Vozcribe-release
CASK_PATH="$(brew --repository ijasiqbal/vozcribe)/Casks/vozcribe.rb"
# Show current values so you know exactly what to replace
grep -E '^ (version|sha256)' "$CASK_PATH"
Update version and sha256 in the cask file. Do not remove the preflight block — it strips the quarantine flag so Gatekeeper doesn't block the unsigned app:
preflight do
system_command "/usr/bin/xattr",
args: ["-cr", "#{staged_path}/Vozcribe.app"]
end
Then push:
cd "$(brew --repository ijasiqbal/vozcribe)"
git add Casks/vozcribe.rb
git commit -m "bump vozcribe to <VERSION>"
git push
brew uninstall --cask vozcribe
brew untap ijasiqbal/vozcribe
brew tap ijasiqbal/vozcribe
brew install --cask vozcribe
Check no quarantine flag:
xattr /Applications/Vozcribe.app
# Should show com.apple.provenance only, NOT com.apple.quarantine
Test as fresh user:
bash /Users/ijas/Documents/whisperType/VoxType-Mac/reset-to-fresh-user.sh
open /Applications/Vozcribe.app
Test core flows: sign-in, recording, transcription.
| File | Purpose |
|---|---|
VoxType-Mac/build-release.sh | Archive, sign, package script |
VoxType-Mac/ExportOptions.plist | Xcode export config |
VoxType-Mac/reset-to-fresh-user.sh | Reset app to fresh state for testing |
Cask: Ijasiqbal/homebrew-vozcribe | Homebrew tap repo (Casks/vozcribe.rb) |
Releases: Ijasiqbal/Vozcribe-release | GitHub releases with ZIPs |
brew install downloads the zip — Homebrew adds com.apple.quarantine flagpreflight block runs — xattr -cr removes the quarantine flag.app to /ApplicationsThis workaround bypasses Gatekeeper without needing a $99/yr Apple Developer ID certificate. Homebrew is deprecating this path — unsigned cask support ends Sept 2026. Plan to get a Developer ID before then.
codesign --force --deep --sign - before zipping.Vozcribe.app at the root of the zip, not a DMG file inside a zip. GitHub Releases also doesn't accept .dmg uploads.--cask flag — use brew install --cask vozcribe, not brew install vozcribe.brew install works but nobody else gets the update.reset-to-fresh-user.sh before verifying.MARKETING_VERSION drifts independently of the cask; always run the check in Step 0 before building. Shipping 1.0 when the cask is at 1.13 is a silent no-op for existing users and a downgrade for new ones.