Release Process

chat-cli uses GitHub Actions for continuous integration and GoReleaser for publishing releases. Releases update two repositories:

Continuous integration

Every pull request and push to main runs .github/workflows/ci.yml:

  • make test

  • make lint

  • make cli + integration tests

How to cut a release

Releases are tag-driven, not automatic on every merge to main.

Option B — Manual tag

git checkout main
git pull
make test
git tag v0.5.4
git push origin v0.5.4

Pushing a v* tag triggers the Release workflow.

Version strings

Released binaries embed the tag via GoReleaser ldflags (chat-cli version shows e.g. v0.5.4).

Local builds without ldflags report dev:

make cli
./bin/chat-cli version
# chat-cli dev, darwin/arm64

You do not need to edit cmd/version.go before releasing.

Repository secrets

Configure these in Settings → Secrets and variables → Actions:

Secret

Purpose

GITHUB_TOKEN

Provided automatically; publishes release assets to this repo

HOMEBREW_TAP_DEPLOY_KEY

SSH private key (write deploy key on chat-cli/homebrew-chat-cli)

Without HOMEBREW_TAP_DEPLOY_KEY, GoReleaser still publishes GitHub Release binaries but cannot update the Homebrew tap.

Homebrew tap deploy key (one-time setup)

Generate a dedicated key (no passphrase):

ssh-keygen -t ed25519 -C "goreleaser-homebrew-tap" -f ~/.ssh/chat-cli-homebrew-tap -N ""

Add the public key to the tap repo with write access:

gh repo deploy-key add ~/.ssh/chat-cli-homebrew-tap.pub \
  --repo chat-cli/homebrew-chat-cli \
  --title "GoReleaser release automation" \
  --allow-write

Store the private key as a repository secret:

gh secret set HOMEBREW_TAP_DEPLOY_KEY --repo chat-cli/chat-cli < ~/.ssh/chat-cli-homebrew-tap

Local GoReleaser (optional)

# Snapshot build (no publish)
goreleaser release --snapshot --clean