go-release

star 0

Release engineering for Go projects — GoReleaser v2 with version ldflags into an internal/version package, SBOMs and multi-arch container images, tag-triggered GitHub Actions releases, CI running build/vet/test -race/govulncheck with SHA-pinned actions, and Dependabot coverage for gomod, tools, npm, and Actions. Use when setting up releases or GoReleaser for a Go project, writing GitHub Actions CI or release workflows for a Go repository, stamping version metadata into a Go binary at build time, or adding Dependabot coverage to a Go repo.

bitwise-media-group By bitwise-media-group schedule Updated 6/10/2026

name: go-release description: Release engineering for Go projects — GoReleaser v2 with version ldflags into an internal/version package, SBOMs and multi-arch container images, tag-triggered GitHub Actions releases, CI running build/vet/test -race/govulncheck with SHA-pinned actions, and Dependabot coverage for gomod, tools, npm, and Actions. Use when setting up releases or GoReleaser for a Go project, writing GitHub Actions CI or release workflows for a Go repository, stamping version metadata into a Go binary at build time, or adding Dependabot coverage to a Go repo. license: MIT

Go release engineering

Tag-driven releases: pushing a vX.Y.Z tag builds cross-platform archives, checksums, SBOMs, and multi-arch container images via GoReleaser. CI gates every push; Dependabot keeps everything — including the action pins — fresh. This layers on the layout and Makefile from the go-project skill.

1. Stamp version metadata into internal/version

// Package version exposes build metadata stamped into the binary at link time.
// Keep these as vars (not consts) so -ldflags "-X ..." can rewrite them; an
// unbuilt or `go run` binary reports the defaults.
package version

var (
    Version   = "dev"     // semver release tag, e.g. v1.2.3
    Commit    = "none"    // short git SHA
    BuildDate = "unknown" // RFC3339 UTC build timestamp
)

Both make build and GoReleaser inject the same vars at the same import path:

-ldflags "-s -w -X <module>/internal/version.Version={{ .Version }} ..."

Expose the metadata through --version output or a GET /version endpoint.

2. GoReleaser config

Copy templates/goreleaser.yaml to .goreleaser.yaml and replace the myapp / OWNER/REPO placeholders. What it encodes:

  • Static, reproducible binaries: CGO_ENABLED=0, -trimpath, -s -w, for linux + darwin × amd64 + arm64.
  • tar.gz archives shipping the LICENSE, a checksums.txt, and an SBOM per archive — generated by the syft pinned in tools/go.mod and invoked via go tool, so nothing needs to be on PATH.
  • A changelog that excludes docs: / test: / chore: / ci: conventional-commit prefixes.
  • dockers_v2 multi-arch images (buildx) pushed to GHCR with OCI annotations.

Validate locally with make snapshot (goreleaser release --snapshot --clean) — full build, no publish.

3. CI workflow

Copy templates/ci.yaml to .github/workflows/ci.yaml. Every push and pull request runs go build, go vet, go test -race, and govulncheck. Conventions:

  • The Go version comes from go.mod (go-version-file), never hard-coded in the workflow.
  • Every action is pinned to a full commit SHA with the tag in a trailing comment — a moved tag can never change what runs. Dependabot keeps the pins fresh.
  • permissions: contents: read — the default token does nothing else.

4. Release workflow

Copy templates/release.yaml to .github/workflows/release.yaml. It triggers on v* tags, checks out with fetch-depth: 0 (GoReleaser needs full history for the changelog), sets up QEMU + buildx for multi-arch images, logs into GHCR with the built-in GITHUB_TOKEN, and runs goreleaser release --clean — SBOMs come from the pinned syft via go tool, so there is no separate syft install step. Cutting a release is exactly: push a semver tag.

5. Dependabot

Copy templates/dependabot.yaml to .github/dependabot.yaml: daily checks with a 7-day cooldown, minor + patch bumps grouped into one PR per ecosystem (majors arrive as individual PRs). tools/go.mod gets its own gomod entry — Dependabot does not descend into nested modules — so developer-tool bumps never ride along with application dependency PRs, and the github-actions entry keeps the workflow SHA pins fresh. For the rationale behind each knob and the full ecosystem matrix (docker, docker-compose, uv, …), see reference.md.

Install via CLI
npx skills add https://github.com/bitwise-media-group/skills --skill go-release
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
bitwise-media-group
bitwise-media-group Explore all skills →