Skip to content

Getting Started

Work In Progress

gover is in active development. The RFC is the architectural source of truth. Not production-ready for general use yet.

What is gover

Composable release pipeline for Go projects. Each step is a subcommand. Each subcommand is replaceable.

bash
go install github.com/thumbrise/gover@latest

What's your project?

Library — bump version, tag, generate release notes:

bash
gover bump                                        # → v1.2.3
gover release v1.2.3 --write --push               # tag + publish-state
gover notes v1.2.3 | gh release create v1.2.3 -F -  # release notes → GitHub

CLI tool — same as library, plus cross-compile:

bash
gover build                                       # multi-platform, tar.gz/zip, checksums

gover notes v1.2.3 | gh release create v1.2.3 dist/* -F -

Multi-module (multiple go.mod in one repo) — same as above, plus dev-state sync:

bash
gover                                             # go.work + replaces + go version sync

One command. After this: go.work is correct, replace directives are in place, Go version is aligned, IDE works, go test ./... covers all modules. Run it again — nothing changes. Idempotent.

Why not GoReleaser / semantic-release

ProblemGoReleasersemantic-releasegover
Build without publishing--skip=publish (partial)Not possible--write (staging worktree)
Prepare/publish separationPro only (paid)Not possible--write / --push / --abort
"Will there be a release?" (machine-readable)NoNo (--dry-run = text only)gover bump → stdout or empty
Multi-module Go (go.mod × N)Pro only (paid)Breaks (tags main = dev-state)Built-in (prefix tags, replace strip)
Replace any step with your own toolNo (monolithic pipeline)Plugin system (Node.js)Yes (stdin/stdout, pipe anything)
Config format.goreleaser.yml (500+ options).releaserc.js (JS + plugins).gover/release.toml (open, portable)

Not competition — different architecture. gover handles governance (tags, publish-state, model). GoReleaser handles distribution (Docker, Homebrew, Snap). They can work together.

Pre-publish staging — Go's missing npm pack

Go Module Proxy caches forever. Push a tag with broken go.mod — permanent. No undo. No npm unpublish. No cargo yank.

gover release --write creates a staging worktree with publish-state. Check before you push. --push ships. --abort rolls back.

bash
gover release v1.2.3 --write        # staging worktree, tags local only
cd .gover/staging && go build ./...  # verify publish-state builds
gover release --push                 # ship — or --abort to roll back

What you get for multi-module projects

Multiple go.mod files? go.work keeps breaking? Expand this.

Monorepo or multi-module project?

MonorepoMulti-module project
WhatStorage strategyArchitecture strategy
StructureMany independent projects, one Git repoOne product, many Go modules
Example15 microservices in one repoCore library + OTEL/gRPC/Redis extensions
ReleaseEach project has its own versionAll modules share one version
ToolBazel, Nx, Turborepogover

What gover does over raw go.work

go.work is a mechanism. gover is the policy layer on top.

  • Filtered discoverygo work use -r . picks up vendor/, testdata/, broken test fixtures. gover doesn't. Verified go.work footguns cataloged in the RFC.
  • Replace management — unconditional replace directives for all internal modules. go mod tidy resolves locally. No manual bookkeeping.
  • Go version sync — root's go directive propagated to all sub-modules. No silent drift.
  • Acyclic validation — cyclic dependencies caught at dev-time, not at release-time.

Two states of go.mod

Every sub-module's go.mod exists in exactly two states. gover formally separates them.

Dev-state (main branch)Publish-state (behind tag)
replacereplace example.com/root => ../Removed
requirerequire example.com/root v0.0.0require example.com/root v1.2.3
Who seesDevelopersUsers (go get)

Main branch is the kitchenreplace directives, go.work, version placeholders. All committed. All managed by gover. Users never see this.

The tag points to a detached commit — clean go.mod, no replaces, pinned versions. What go get @v1.2.3 downloads. The commit is not on any branch. Main never leaves dev-state.

What's Next

  • Reference — architectural source of truth: problem statement, evidence base, disputed points, full decision log
  • Devlog — design decisions, dead ends, lessons learned

Apache 2.0 · Built in public · Contributions welcome