Step-by-step guide for publishing a new version.
Update the version string in 3 files (4 occurrences total):
| File | Location | Count |
|---|---|---|
cmd/claude-notifications/main.go |
const version = "X.Y.Z" |
1 |
.claude-plugin/plugin.json |
"version": "X.Y.Z" |
1 |
.claude-plugin/marketplace.json |
"version": "X.Y.Z" |
2 |
Quick check — all occurrences should match:
grep -rn '1\.[0-9]\+\.[0-9]\+' cmd/claude-notifications/main.go .claude-plugin/plugin.json .claude-plugin/marketplace.jsonAdd a new section at the top following Keep a Changelog format:
## [X.Y.Z] - YYYY-MM-DD
### Added
- ...
### Changed
- ...
### Fixed
- ...make test-race
make lintgit add -A
git commit -m "release: vX.Y.Z"
git push origin mainWait for ALL CI checks to pass before tagging:
gh run list --limit 5 # check status
gh run watch <run-id> # wait for a specific runAll three workflows must be green: Ubuntu CI, macOS CI, Windows CI. If any fail — fix, push again, and wait. Do NOT create the tag until CI is green.
git tag vX.Y.Z
git push origin --tagsThe release.yml workflow triggers on tag push and builds binaries for all platforms automatically.
Verify at: https://github.com/777genius/claude-notifications-go/releases
ClaudeNotifier.app is automatically built, signed, and notarized by the release.yml
workflow as a build-notifier job. It runs in parallel with Go binary builds and the
resulting ClaudeNotifier.app.zip is included in the same GitHub Release.
The CI workflow:
- Imports the Apple Developer certificate from GitHub Secrets
- Builds a universal binary (arm64 + x86_64)
- Signs with Developer ID Application + hardened runtime
- Notarizes via
xcrun notarytooland staples the ticket - Uploads
ClaudeNotifier.app.zipas a release asset
| Secret | Description |
|---|---|
APPLE_CERTIFICATE |
Base64-encoded .p12 export of Developer ID Application cert |
APPLE_CERTIFICATE_PASSWORD |
Password for the .p12 file |
APPLE_ID |
Apple ID email for notarization |
APPLE_PASSWORD |
App-specific password for notarization |
APPLE_TEAM_ID |
Apple Developer Team ID |
make build-notifier # ad-hoc or local cert signing
cd swift-notifier && bash scripts/build-app.sh --ci # Developer ID + notarization (needs env vars)The auto-generated release description is minimal. Edit it with a human-readable summary:
gh release edit vX.Y.Z --notes "$(cat <<'NOTES_EOF'
## Bug Fixes
### Title ([#N](link))
Description of what was broken and how it was fixed.
## New Features
### Title ([#N](link))
Description of what was added and why.
---
📦 **[Installation](https://github.com/777genius/claude-notifications-go#installation)** · 🔄 **[Updating](https://github.com/777genius/claude-notifications-go#updating)**
**Full Changelog**: https://github.com/777genius/claude-notifications-go/compare/vPREV...vX.Y.Z
NOTES_EOF
)"Comment on fixed issues and merged PRs with a link to the release:
gh issue comment N --body "Fixed in [vX.Y.Z](https://github.com/777genius/claude-notifications-go/releases/tag/vX.Y.Z)."
gh pr comment N --body "Released in [vX.Y.Z](https://github.com/777genius/claude-notifications-go/releases/tag/vX.Y.Z)."Users don't need to manually download binaries after a plugin update:
- User updates the plugin via
/pluginmenu - This updates
plugin.jsonwith the new version - On the next hook invocation,
bin/hook-wrapper.shcompares the installed binary version withplugin.json - If versions differ, it runs
install.sh --forceto download the matching binary from GitHub Releases - User sees a
[claude-notifications] Updated to vX.Y.Zmessage