I’m writing most of my own tools in go. Sometime ago I found a tool called goreleaser which automates the release process of software written in go.

goreleaser is pretty well documented, therefore this is just a quick overview how I use it. It will do the following things for you:

  • Generate a changelog with the latest commit since the last release.
  • Build artifacts for different architectures (Linux/Mac/Windows).
  • Create a GitHub/GitLab release and attach changelog and artifacts.

Initial setup

  1. Install goreleaser on your machine. (Check out the official docs here) I went with the go install github.com/goreleaser/goreleaser@latest method.

  2. Run goreleaser init to get a default .goreleaser.yml which is used to configure goreleaser.

  3. Adjust the configuration.

before:
  hooks:
    - go mod tidy
builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin
archives:
  - replacements:
      darwin: Darwin
      linux: Linux
      windows: Windows
      amd64: x86_64
checksum:
  name_template: 'checksums.txt'
snapshot:
  name_template: "{{ .Tag }}-next"
changelog:
  sort: asc
  filters:
    exclude:
      - '^docs:'
      - '^test:'

I used this configuration to release go-jump.

Release via CI

To simplify the release process even more you can run gorelease on GitHub Actions or GitLab CI. This is an example for GitHub Actions. Store it as .github/workflows/release.yaml in your repository root.

name: goreleaser

on:
  push:
    tags:
      - '*'

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Set up Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.16
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v2
        with:
          version: latest
          args: release --rm-dist
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Then create a new git tag and push it:

git tag -a v0.1.0 -m "My release"
git push origin v0.1.0

Conclusion

I really like how easy gorelease is to use and it removes a repetitive task from my release process. The documentation is perfect and the defaults are sane (the example above are more or less exactly the defaults!). So I’m going to add goreleaser to all of my projects!