.agents/skills/release-codexbar/SKILL.md
Use for releasing signed/notarized macOS apps, especially repos with Sparkle appcasts and Homebrew casks.
CHANGELOG.md is complete, user-facing, deduped, and dated for the release.$release-private if it exists before resolving Peter-owned credential locators.Use $one-password for secret handling. op only in tmux/persistent shell; no broad env, set, export -p, or secret scans.
Known App Store Connect shape:
private_key_p8, key_id, issuer_id~/.profile$release-privateKnown Sparkle key:
$release-privateSPARKLE_PRIVATE_KEY_FILESafe env file pattern:
APP_STORE_CONNECT_API_KEY_P8=<1Password ref from release-private>
APP_STORE_CONNECT_KEY_ID=<1Password ref from release-private>
APP_STORE_CONNECT_ISSUER_ID=<1Password ref from release-private>
SPARKLE_PRIVATE_KEY_FILE=<path from release-private>
Run with op run --account my.1password.com --env-file <file> -- <script>, then delete the temp env file.
Paths:
~/Projects/codexbarScripts/release.shScripts/sign-and-notarize.shScripts/make_appcast.sh, appcast.xmlCodexBar-macos-universal-<version>.zip, CodexBar-macos-universal-<version>.dSYM.zipCodexBar.appversion.envCHANGELOG.md~/Projects/homebrew-tap~/Projects/homebrew-tap/Casks/codexbar.rb~/Projects/homebrew-tap/Formula/codexbar.rb.github/workflows/release-cli.ymlNormal release:
tmux new-session -d -s codexbar-release 'op run --account my.1password.com --env-file /tmp/codexbar-release-op.env -- Scripts/release.sh'
tmux attach -t codexbar-release
If notarization fails with 401 Unauthenticated, rerun using all three App Store Connect fields from the 1Password item above. Mismatched key_id / issuer_id from ~/.profile can cause this.
If widget metadata generation times out, CODEXBAR_WIDGET_METADATA_TIMEOUT_SECONDS=600 is a known-good floor.
CodexBar CLI tarballs are not produced by Scripts/release.sh itself. The GitHub release event triggers .github/workflows/release-cli.yml, which builds and uploads:
CodexBarCLI-v<version>-macos-arm64.tar.gzCodexBarCLI-v<version>-macos-x86_64.tar.gzCodexBarCLI-v<version>-linux-aarch64.tar.gzCodexBarCLI-v<version>-linux-x86_64.tar.gz.sha256 filesIf the workflow fails only in update-homebrew-tap with GitHub API rate limiting, the CLI assets may already be uploaded. Verify assets live, then update Formula/codexbar.rb manually from the tarball checksums.
Release is not done until the published chain checks out:
gh release view v<VERSION> --json tagName,name,isDraft,isPrerelease,url,assets,body
Scripts/check-release-assets.sh v<VERSION>
python3 - <<'PY'
import xml.etree.ElementTree as ET
ns={'sparkle':'http://www.andymatuschak.org/xml-namespaces/sparkle'}
root=ET.parse('appcast.xml').getroot()
item=root.find('channel').find('item')
enc=item.find('enclosure')
print(item.findtext('title'))
print(item.findtext('sparkle:version', namespaces=ns))
print(item.findtext('sparkle:shortVersionString', namespaces=ns))
print(enc.attrib.get('url'))
print(enc.attrib.get('length'))
print(bool(enc.attrib.get('{http://www.andymatuschak.org/xml-namespaces/sparkle}edSignature')))
PY
codesign --verify --deep --strict --verbose=2 CodexBar.app
spctl --assess --type execute --verbose CodexBar.app
For Homebrew:
shasum -a 256 CodexBar-macos-universal-<VERSION>.zip
cd /Users/steipete/Projects/homebrew-tap
python3 .github/scripts/update_formula.py --formula codexbar --tag v<VERSION> --repository steipete/CodexBar --artifact-template 'CodexBarCLI-{tag}-{target}.tar.gz' --target-aliases 'darwin_arm64=macos-arm64,darwin_amd64=macos-x86_64,linux_arm64=linux-aarch64,linux_amd64=linux-x86_64'
brew fetch --cask --force --retry codexbar
brew fetch --formula --force --retry steipete/tap/codexbar
Update the cask when app zip assets exist. Update the formula only when standalone CLI tarballs for that version exist.
Tap audit can be noisy from unrelated formulae; keep evidence specific to the app cask.
Unreleased:
version.env: next MARKETING_VERSION, next BUILD_NUMBERCHANGELOG.md: top ## <next> — Unreleased--ff-only.CodexBar restart:
pkill -x CodexBar || pkill -f CodexBar.app || true
cd "$(git rev-parse --show-toplevel)"
open -n CodexBar.app
/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' CodexBar.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' CodexBar.app/Contents/Info.plist