diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a3c60a3..7e41182 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -37,7 +37,8 @@ jobs: uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser - version: '~> v2' + version: v2.11.1 args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 957d169..744e3c4 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,6 +15,7 @@ builds: goos: - linux - darwin + - windows goarch: - amd64 - arm64 @@ -30,6 +31,10 @@ archives: - claudecm formats: - tar.gz + format_overrides: + - goos: windows + formats: + - zip name_template: >- {{ .ProjectName }}_ {{- .Version }}_ @@ -42,6 +47,47 @@ archives: checksum: name_template: checksums.txt +brews: + - name: claudecm + ids: + - claudecm + repository: + owner: a2d2-dev + name: homebrew-tap + branch: main + token: "{{ .Env.TAP_GITHUB_TOKEN }}" + commit_author: + name: a2d2-dev release bot + email: release-bot@a2d2.dev + commit_msg_template: "brew: update claudecm to {{ .Tag }}" + homepage: "https://github.com/a2d2-dev/claudecm" + description: "One-command switch between Claude Code and Codex CLI configurations." + license: MIT + skip_upload: auto + install: | + bin.install "claudecm" + test: | + system "#{bin}/claudecm", "version" + system "#{bin}/claudecm", "--help" + +scoops: + - name: claudecm + ids: + - claudecm + repository: + owner: a2d2-dev + name: homebrew-tap + branch: main + token: "{{ .Env.TAP_GITHUB_TOKEN }}" + commit_author: + name: a2d2-dev release bot + email: release-bot@a2d2.dev + commit_msg_template: "scoop: update claudecm to {{ .Tag }}" + homepage: "https://github.com/a2d2-dev/claudecm" + description: "One-command switch between Claude Code and Codex CLI configurations." + license: MIT + skip_upload: auto + snapshot: version_template: "{{ incpatch .Version }}-next" diff --git a/README.md b/README.md index be625ca..e37e184 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,28 @@ claudecm does **not** sync your configuration to the cloud, is **not** a proxy o ## Install +Package-manager installs are available from the next tagged release onward. + +macOS with Homebrew: + +```bash +brew tap a2d2-dev/tap +brew install claudecm +claudecm version +claudecm --help +``` + +Windows with Scoop: + +```powershell +scoop bucket add a2d2-dev https://github.com/a2d2-dev/homebrew-tap +scoop install claudecm +claudecm version +claudecm --help +``` + +From source: + ```bash go install github.com/a2d2-dev/claudecm@latest ``` diff --git a/docs/plan/release-runbook.md b/docs/plan/release-runbook.md index d9bdf73..f987b4e 100644 --- a/docs/plan/release-runbook.md +++ b/docs/plan/release-runbook.md @@ -11,6 +11,7 @@ This runbook is for the release engineer who owns the actual `v1.0.0` tag. Do no - Run `go build ./...`, `go vet ./...`, and `go test ./...`. - Run `bash scripts/release-smoke.sh` and confirm `claudecm version` prints the stamped version, commit, and build date. - Run `goreleaser check` if GoReleaser is installed. +- Confirm the `TAP_GITHUB_TOKEN` repository secret is present and has write access to `a2d2-dev/homebrew-tap`. - Review release notes for v1.0 scope boundaries: local-first profile switching for Claude Code and Codex CLI; plaintext `0600` local storage; no cloud, MCP, GUI, Gemini, or encryption-at-rest claims. ## Tag And Publish @@ -20,8 +21,29 @@ This runbook is for the release engineer who owns the actual `v1.0.0` tag. Do no 3. Push the tag: `git push origin v1.0.0`. 4. Watch the `Release` GitHub Actions workflow. 5. Confirm the workflow runs tests, the release smoke script, GoReleaser validation/build, checksum generation, and GitHub Release publication. -6. Verify the published release has archives for linux/darwin x amd64/arm64, `checksums.txt`, `LICENSE`, and `README.md`. -7. Download one artifact and run `claudecm version` as a package-manager smoke test. +6. Verify the published release has archives for linux/darwin/windows x amd64/arm64, `checksums.txt`, `LICENSE`, and `README.md`. +7. Verify `a2d2-dev/homebrew-tap` received the Homebrew formula update for `claudecm`. The formula should point at GitHub Release artifact URLs for the tag, use checksums from `checksums.txt`, declare the MIT license, and install only the `claudecm` binary. +8. Verify `a2d2-dev/homebrew-tap` received the Scoop manifest update for `claudecm`. The manifest should point at the Windows amd64/arm64 GitHub Release zip artifacts, use checksums from `checksums.txt`, declare the MIT license, and expose only the `claudecm.exe` binary. +9. Run the Homebrew install smoke on macOS: + + ```bash + brew tap a2d2-dev/tap + brew install claudecm + claudecm version + claudecm --help + ``` + +10. When a prior version exists, run `brew upgrade claudecm` and confirm `claudecm version` reports the new tag. +11. Run the Scoop install smoke on Windows: + + ```powershell + scoop bucket add a2d2-dev https://github.com/a2d2-dev/homebrew-tap + scoop install claudecm + claudecm version + claudecm --help + ``` + +12. When a prior version exists, run `scoop update claudecm` and confirm `claudecm version` reports the new tag. ## Rollback Or Retry @@ -33,3 +55,9 @@ If the workflow fails before publishing a usable release: 4. Fix the issue on `main` through the normal PR process. 5. Re-run the preflight checklist. 6. Recreate and push the tag: `git tag v1.0.0 && git push origin v1.0.0`. + +If a bad Homebrew formula or Scoop manifest was published after a usable GitHub Release: + +1. Revert the bad package-manager commit in `a2d2-dev/homebrew-tap`. +2. Communicate the known-good version and advise users to `brew update && brew install claudecm` or `scoop update && scoop install claudecm` after the revert lands. +3. Fix the release configuration on `main` through the normal PR process before publishing another tag.