Thanks for your interest in ana-cli. External contributions are
welcome — this document covers the basics.
- Go 1.25 or newer.
make.goreleaseronly if you want to runmake release-local.
make build # -> ./bin/ana
make test # go test -race ./...
make cover # enforces 100% coverage on ./internal/...
make lint # gofmt, go vet, staticcheckmake cover runs staticcheck-pinned dev tools. Run make deps once to
install them.
End-to-end tests live in e2e/ and require a live TextQL endpoint
plus a token. They are opt-in; see e2e/README.md.
You do not need them to land most PRs.
This project uses Conventional Commits. Commit subjects drive the release pipeline (release-please → GoReleaser), so get the prefix right:
feat:— new verb, flag, or user-visible behavior.fix:— bug fix.refactor:— internal change, no behavior change.test:— test-only change.docs:— docs, README, CLAUDE.md.chore:/ci:— tooling, pipeline, dependencies.
Scope is optional but helpful (e.g. fix(auth): ...).
- Branch off
main, open the PR againstmain. - One logical change per PR. Split refactors from features.
- CI runs lint, test on linux/macos/windows, a 100% coverage gate on
./internal/..., a build check, andgoreleaser check. Docs-only PRs skip the heavy jobs automatically. - Squash merge is the house style — the PR title becomes the commit subject, so make it conform to Conventional Commits.
Each top-level verb lives in its own package under internal/. The
pattern:
- Declare a narrow
Depsstruct; do not importinternal/transportorinternal/config—cmd/ana/main.gowires those in. - Build a
cli.GroupfromNew(deps)and register subcommands. - Write tests using the fake
Depspattern — seeinternal/feed/feed_test.gofor the convention.
Coverage is gated at 100% on ./internal/..., so every branch needs
a test.
Open a discussion or a draft PR. For security issues, see SECURITY.md.