Go

Automated GitHub Releases with GoReleaser

Published 2025-11-02.
Time to read: 1 minutes.

This page is part of the golang collection.

GoReleaser is a powerful tool designed specifically for Go projects to automate the release process, including building binaries for various platforms and creating GitHub Releases.

Key points

Create a .goreleaser.yaml file in your project root, which defines how your project should be built and released. The contents of the file include specifications of build targets, archives, and other GitHub release settings.

Create a personal access GitHub token with repository scope on GitHub and set the GITHUB_TOKEN environment variable to hold the token:

Shell
export GITHUB_TOKEN="YOUR_GITHUB_TOKEN"

The following command invokes GoReleaser such that it builds your application, creates a release on GitHub, and uploads the generated binaries.

Shell
$ goreleaser release --rm-dist

GitHub Release System

Claude did this for me:

I've set up the GitHub release system for your project.
Here's what was created:

  Files Created

  1. .github/workflows/release.yml - GitHub Actions workflow that:
    - Triggers on version tags (v*)
    - Uses GoReleaser to build all commands for multiple platforms
    - Automatically creates GitHub releases with binaries
  2. .goreleaser.yml - GoReleaser configuration that:
    - Builds all 6 commands (git-commitAll, git-evars, git-exec,
      git-replicate, git-treeconfig, git-update)
    - Targets Linux, macOS, and Windows on amd64 and arm64 architectures
    - Creates tar.gz archives (zip for Windows)
    - Generates checksums and changelog
    - Includes README and LICENSE in releases
  3. RELEASING.md - Comprehensive release documentation covering:
    - Step-by-step release process
    - Version numbering guidelines (semantic versioning)
    - Automated release workflow details
    - Troubleshooting guide
    - Rollback procedures
  4. scripts/release.sh - Interactive release script that:
    - Validates version format
    - Checks for clean working directory
    - Runs tests before release
    - Creates and pushes tags
    - Provides colored output and confirmation prompts
  5. README.md - Updated with:
    - Pre-built binaries installation instructions
    - Creating Releases section in Development
    - Links to release documentation

  How to Create a Release

  Simply run:
  ./scripts/release.sh 1.0.0

  Or manually push a tag:
  git tag -a v1.0.0 -m "Release v1.0.0"
  git push origin v1.0.0

  The GitHub Actions workflow will automatically build binaries for all
  platforms and publish a release!

This was a useful starting point for a release script. Here is the current version.

When vibe coding, ask for the following if release capability is required in a Go program.

RELEASE.md
# Key Points for Setting up Release Capability in a Go Program

## GoReleaser Configuration (.goreleaser.yml)

1. Use modern syntax - version: 2 with formats: (plural), not deprecated format: or format_overrides

```yaml
archives:
- id: project-archive
formats:
- tar.gz
- zip
```

2. Before hooks - Run tests and tidy before building:

```yaml
before:
hooks:
- go mod tidy
- go test ./...
```

3. Version injection - Use ldflags to embed version and strip symbols:

```yaml
ldflags:
- -s -w
- -X github.com/user/project/internal/common.Version={{.Version}}
```

Note: -s -w strips symbols and debug info to reduce binary size

4. Cross-platform builds - Configure GOOS/GOARCH for linux, darwin, windows with amd64/arm64

## Makefile

1. Install directory determination - Use hierarchical fallback:

```makefile
GOBIN ?= $(shell go env GOBIN)
ifeq ($(GOBIN),)
GOPATH ?= $(shell go env GOPATH)
ifeq ($(GOPATH),)
INSTALL_DIR := $(HOME)/go/bin
else
INSTALL_DIR := $(GOPATH)/bin
endif
else
INSTALL_DIR := $(GOBIN)
endif
```

2. Install target - Use go install and display actual path:

```makefile
install:
@echo "Installing $(BINARY_NAME) to $(INSTALL_DIR)..."
@$(GOINSTALL) $(LDFLAGS) ./cmd/jc
@echo "$$PATH" | grep -q "$(INSTALL_DIR)" || echo "Warning: $(INSTALL_DIR) is not in your PATH."
```

3. Quiet release target - Filter goreleaser output to reduce noise:

```makefile
release:
@goreleaser release --snapshot --clean 2>&1 | grep -E "(error|failed|succeeded)" || true
```

4. Use @ prefix on commands to suppress echo

## Version Management

- Use git tags for releases, or VERSION file for development
- Snapshot builds use {{ incpatch .Version }}-next pattern

## References

Here are some working implementations that demonstrate the required style:

- https://github.com/mslinn/git_lfs_scripts_go
- https://github.com/mslinn/dl
- https://github.com/mslinn/nugem
- https://github.com/mslinn/git_tree_go
* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.