No description
Find a file
2026-05-02 09:04:19 +02:00
.claude ai: release skill: push 2026-04-30 11:17:34 +02:00
.gemini ai: add .gemini 2026-05-02 09:04:19 +02:00
internal fix: anchor clone-vs-proxy verification to the same commit 2026-05-02 08:47:05 +02:00
.gogogo.conf build: only linux 2026-04-30 14:25:21 +02:00
.golangci.yml lint: new config 2026-04-14 22:12:55 +02:00
go.mod feat: add upload progress bar for terminal output 2026-04-30 11:12:12 +02:00
go.sum feat: add upload progress bar for terminal output 2026-04-30 11:12:12 +02:00
LICENSE.txt new: first PoC 2024-10-02 00:04:36 +02:00
main.go feat: cobra CLI with shell completion for --commit 2026-04-13 20:45:04 +02:00
README.md feat: add --dry-run flag to release command (closes #24) 2026-05-02 00:17:02 +02:00

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

  1. Create a config file next to the module description of your project (usually next to your go.mod file):

    gogogo config --default > .gogogo.conf
    
  2. 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:

  1. 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.
  2. 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 what go get would fetch.
  3. Build — run go build -trimpath inside the clone. Because the build happens in a git checkout, Go automatically stamps vcs.revision and vcs.time into the binary.
  4. 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)

  1. Create a signed tag on your default branch.
  2. Push the tag.
  3. 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.