docs/RELEASING.md
SwiftPM-only; package/sign/notarize manually (no Xcode project). Sparkle feed is served from GitHub Releases. Checklist below merges Trimmy’s release flow with CodexBar specifics.
Must read first: open the master macOS release guide at ~/Projects/agent-scripts/docs/RELEASING-MAC.md alongside this file and reconcile any differences in favor of CodexBar specifics before starting a release.
swiftformat, swiftlint, swift, sign_update, generate_keys, generate_appcast, gh, python3, zip, curl, plus APP_STORE_CONNECT_*. SPARKLE_PRIVATE_KEY_FILE is only needed when overriding the default Keychain Sparkle key./Applications/Xcode.app (for ictool/iconutil and SDKs).Developer ID Application: Peter Steinberger (Y5PE65HELJ).APP_STORE_CONNECT_API_KEY_P8, APP_STORE_CONNECT_KEY_ID, APP_STORE_CONNECT_ISSUER_ID..mac-release.env; CodexBar still uses the older shared AGCY key, so the manifest includes the local Dropbox fallback path. SPARKLE_PRIVATE_KEY_FILE overrides it.source ~/.profile) before running Scripts/release.sh.Scripts/mac-release resolves MAC_RELEASE_TOOL, sibling ../agent-scripts, or ~/Projects/agent-scripts../Scripts/build_icon.sh Icon.icon CodexBar
Uses Xcode’s ictool + transparent padding + iconset → Icon.icns.
./Scripts/sign-and-notarize.sh
What it does:
swift build -c release --arch arm64 and swift build -c release --arch x86_64CodexBar.app with Info.plist and Icon.icnsCodexBar-macos-universal-<version>.zipGotchas fixed:
--timestamp and --deep when signing the app to avoid invalid signature errors.unzip — it can add AppleDouble ._* files that break the sealed signature and trigger “app is damaged”. Use Finder or ditto -x -k CodexBar-<ver>.zip /Applications. If Gatekeeper complains, delete the app bundle, re-extract with ditto, then spctl -a -t exec to verify.find CodexBar.app -name '._*' should return nothing; then spctl --assess --type execute --verbose CodexBar.app and codesign --verify --deep --strict --verbose CodexBar.app should both pass on the packaged bundle.After notarization, or let Scripts/release.sh do this:
./Scripts/make_appcast.sh CodexBar-macos-universal-0.1.0.zip \
https://raw.githubusercontent.com/steipete/CodexBar/main/appcast.xml
Generates HTML release notes from CHANGELOG.md (via Scripts/changelog-to-html.sh) and embeds them into the appcast entry.
Uploads not handled automatically—commit/publish appcast + zip to the feed location (GitHub Releases/raw URL).
./Scripts/release.sh
CodexBar ships a Homebrew Cask in ../homebrew-tap. When installed via Homebrew, CodexBar disables Sparkle and the app
must be updated via brew.
After publishing the GitHub release, .github/workflows/release-cli.yml builds the CLI tarballs, uploads CodexBarCLI-v<version>-{macos-arm64,macos-x86_64,linux-aarch64,linux-x86_64}.tar.gz plus checksums, then dispatches the Homebrew tap update for both the CLI formula and app cask. If the final dispatch is rate-limited, the tarballs and app zip may still be present; rerun or manually update the tap formula/cask from the published assets.
~/Projects/agent-scripts/docs/RELEASING-MAC.md; resolve any conflicts toward CodexBar’s specifics.swiftformat, swiftlint, swift test (zero warnings/errors)./Scripts/build_icon.sh if icon changed./Scripts/sign-and-notarize.shScripts/release.sh or Scripts/make_appcast.sh; use SPARKLE_PRIVATE_KEY_FILE only if overriding Keychain signing.
Scripts/check-release-assets.sh <tag> to confirm the app zip, dSYM zip, CLI tarballs, and CLI checksums are present on GitHub../Scripts/make_appcast.sh CodexBar-macos-universal-<ver>.zip https://raw.githubusercontent.com/steipete/CodexBar/main/appcast.xmlSPARKLE_CHANNEL=beta to tag the entry../Scripts/verify_appcast.sh <ver>../homebrew-tap/Casks/codexbar.rb (app zip url + sha256) and ../homebrew-tap/Formula/codexbar.rb (CLI tarball urls + sha256), then verify:
gh run watch <release-cli-run-id> --exit-statusScripts/check-release-assets.sh v<version>brew uninstall --cask codexbar || truebrew untap steipete/tap || true; brew tap steipete/tapbrew install --cask steipete/tap/codexbar && open -a CodexBarCodexBar <version>, notes as Markdown list (no stray blank lines)CodexBar-macos-universal-<ver>.zip, unzip via ditto, run, and verify signature (spctl -a -t exec -vv CodexBar.app + stapler validate)appcast.xml points to the new zip/version and renders the HTML release notes (not escaped tags)sparkle:edSignature is present for the enclosure in appcast (generated by generate_appcast with the ed25519 key)- per line, blank line between sections); visually confirm bullets render correctly after publishing/Applications/CodexBar.app to test Sparkle delta/full update to the new releasefind CodexBar.app -name '._*' is empty, spctl --assess --type execute --verbose CodexBar.app and codesign --verify --deep --strict --verbose CodexBar.app succeed/Applications/CodexBar.app, quit first, replace, relaunch, and test updatebuild_icon.sh (ictool) to ensure transparent padding.Contents/Frameworks and rpath added; codesign deep.ditto -x -k, removing any ._* files, then re-verify with spctl.curl -I <enclosure-url>.