- Go 100%
| .claude | ||
| .gemini | ||
| internal | ||
| .gogogo.conf | ||
| .golangci.yml | ||
| go.mod | ||
| go.sum | ||
| LICENSE.txt | ||
| main.go | ||
| README.md | ||
GOGOGO
Release builder for Go modules on Forgejo/Gitea.
Key concept
Publish what can be built by others.
- Build from the sources published on your VCS hosting site.
- Switch off Go workspace mode to have builds that are reproducible by others.
- Build for as many OS/ARCH targets as you want.
- Upload the built artifacts as a release to your VCS hosting site.
- Automatically clean up old pre-releases and assets of older releases.
Installation
go install go.schlittermann.de/heiko/gogogo@latest
Prepare
-
Create a config file next to the module description of your project (usually next to your
go.modfile):gogogo config --default > .gogogo.conf -
Edit
.gogogo.conf. Key settings:
| Field | Description |
|---|---|
build.commands |
Subdirectories of commands to build (empty = module root) |
build.targets |
OS/arch pairs, e.g. linux/amd64 (empty = current platform) |
build.test.skip |
Skip tests before building |
repo.apiurl |
Forgejo/Gitea API URL, e.g. https://git.example.com/api/v1 |
repo.owner |
Repository owner/organization |
repo.name |
Repository name |
repo.token |
API token (PAT) — see secret for syntax |
repo.restrict30x |
Permitted redirect target prefixes (optional) |
env |
Extra environment variables passed to the build |
If repo.token is not set, it falls back to netrc:<host>.
Run go tool dist list for a full list of valid OS/arch targets.
Usage
gogogo [flags] <command> [flags]
Flags:
--version print version and exit
--debug level set API client debug level
--help help for gogogo
Commands:
config show configuration
release build and upload a release
status list existing releases of the configured repository
completion generate shell completion script
gogogo config
gogogo config --default # print the built-in default config
gogogo config --parsed # print the effective config (defaults + .gogogo.conf)
The two flags are mutually exclusive — exactly one must be set.
gogogo release
gogogo release [flags]
--commit commitish what to release (default: auto-detect from HEAD)
(empty) auto-detect: use tag at HEAD if present,
otherwise pre-release from current branch
@ current local branch
+ default branch HEAD
latest latest tag on default branch (via module proxy)
--dry-run print what would happen (commit, targets, upload destination) without building or uploading
--force replace an existing release with the same tag
--local build only, do not upload
--out directory copy built artifacts to this directory (implies release info JSON)
When --commit is omitted, gogogo inspects the current HEAD:
- If HEAD has a semver tag: that tag is used (after verifying it matches the remote).
- If HEAD is untagged: the current branch name is used, producing a pseudo-version pre-release.
- In both cases, HEAD must be reachable from a remote tracking branch (i.e., pushed).
gogogo status
gogogo status [flags]
--json emit machine-readable JSON instead of a table
--limit n cap the number of releases shown (0 = all)
Lists the existing releases of the configured repository (tag, name,
asset count, creation time, and draft/pre flags).
Shell completion
Gogogo provides shell completion for bash, zsh, fish, and powershell.
The --commit flag completes to available git tags, branches, and the
special values @, +, and latest.
# bash
source <(gogogo completion bash)
# zsh
gogogo completion zsh > "${fpath[1]}/_gogogo"
# fish
gogogo completion fish | source
Release workflow
Build flow
When repository configuration (repo.apiurl, repo.owner, repo.name) is
present and git is available, gogogo builds from a git clone:
- Clone — shallow-clone the repository at the requested ref. Prefers cloning from the local repo (after verifying the ref exists on the remote), falling back to a remote clone. For stable releases (semver tags), the tag must be annotated and point to the same commit locally and remotely.
- Verify — compute the module zip hash of the clone (
golang.org/x/mod/zip) and compare it with the hash reported by the Go module proxy. This ensures the clone matches whatgo getwould fetch. - Build — run
go build -trimpathinside the clone. Because the build happens in a git checkout, Go automatically stampsvcs.revisionandvcs.timeinto the binary. - Upload — publish the built binaries as a release on Forgejo/Gitea.
When repository config is unavailable (or --local is set), gogogo falls back
to building from the Go module cache (go get module@version in a temp dir).
This path does not embed VCS metadata.
Official release (from a signed tag)
- Create a signed tag on your default branch.
- Push the tag.
- Run
gogogo release(the tag at HEAD is auto-detected).
Pre-release (from a branch)
gogogo release
If HEAD is untagged, the current branch produces a pseudo-version pre-release automatically. You can also be explicit:
gogogo release --commit <branchname>
The version embedded by the Go toolchain must be a valid semantic version.
Pre-releases (versions with a - prerelease segment) are marked accordingly
and cleaned up automatically once a full release supersedes them.