The Ops Community ⚙️

Cover image for Publish Go Packages with Goreleaser
Damilare Ogunmola
Damilare Ogunmola

Posted on

Publish Go Packages with Goreleaser

Goreleaser is awesome. It's a simple tool that allows you to release your go packages. Recently, my team and I used it with a company wide CLI tool that we built.

In this tutorial, we'll use goreleaser to automate the release of a simple go package.

Installation

On macOS, to install goreleaser, we can install using:

go install github.com/goreleaser/goreleaser@latest

Enter fullscreen mode Exit fullscreen mode

Or we use the popular homebrew package manager for macOS and Linux with:

brew install goreleaser/tap/goreleaser
Enter fullscreen mode Exit fullscreen mode

On Ubuntu Linux, we can use apt:

echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install goreleaser
Enter fullscreen mode Exit fullscreen mode

More options can be found here.

Create Package

Create a new folder to house our project. Then initialize the modules with

go mod init main 
Enter fullscreen mode Exit fullscreen mode

Next, we create a file called main.go. In main.go, copy and paste the following code:

package main

func main() {
  println("This is a tutorial about Goreleaser!")
}
Enter fullscreen mode Exit fullscreen mode

Initialize Goreleaser

The next step is to setup goreleaser. To do this, we run:

goreleaser init
Enter fullscreen mode Exit fullscreen mode

This command creates .goreleaser.yaml file in our directory. We'll take a closer look at this file.

Update .goreleaser.yaml

I have added a few more fields to the generated .goreleaser.yaml file. We'll go through the important parts.

release:
  github:
    owner: justdamilare
    name: mytool

before:
  hooks:
    - go mod tidy
    - go generate ./...

builds:
  - env:
      - GO_VERSION=1.19
    goos:
      - linux
      - windows
      - darwin

# replaces architecture naming in the archive name
archives:
  - replacements:
      darwin: Darwin
      linux: Linux
      windows: Windows
      386: i386
      amd64: x86_64

    format_overrides:
      - goos: windows
        format: zip

checksum:
  name_template: 'checksums.txt'

snapshot:
  name_template: "{{ incpatch .Version }}-next"

changelog:
  sort: asc
  filters:
    exclude:
      - '^docs:'
      - '^test:'

# upload binaries to gcloud bucket called `mytool`
blobs:
  - provider: gs
    bucket: mytool
    folder: "{{ .Version }}"

# generate homebrew-tap  
brews:
  - name: justdamilare
    tap:
      owner: mytool
      name: homebrew-tap
    folder: Formula
    homepage: https://github.com/justdamilare/mytool
    description: A simple go project
    # use custom download strategy in case the Github repository is private
    download_strategy: GitHubPrivateRepositoryReleaseDownloadStrategy
    custom_require: "../custom_download_strategy"
    test: |
      system "#{bin}/mytool"
    install: |
      bin.install "mytool"
Enter fullscreen mode Exit fullscreen mode

It should be noted that if homebrew-tap and blobs are not needed, the sections can be removed. If homebrew-tap is needed, a Githib repo called homebrew-tap should be created also.

Release Package

Finally, we can release our packages. To do that, we need to create a tag for our release on Git. For example, to create a tag for version 0.1.0, we can run:

git tag v0.1.0
Enter fullscreen mode Exit fullscreen mode

and

git push origin v0.1.0
Enter fullscreen mode Exit fullscreen mode

Then in the directory with main.go, run:

goreleaser release
Enter fullscreen mode Exit fullscreen mode

Goreleaser will build all the binaries. These binaries will be uploaded automatically to Github using the local GitHub credentials. The builds will also be located in a /dist folder in the home directory. If the brew publish method is included, a generated *.rb file will also be in the /dist folder. In case Goreleaser does not copy the generated Formula to the homebrew-tap repo automatically, it can be copied manually. You can see checkout how to publish the build to a private homebrew-tap here

Summary

  • Install goreleaser
  • Create go package
  • Initialize Goreleaser with goreleaser init
  • Update .goreleaser.yaml
  • Release build by creating a tag with git tag vX.X.X and then run goreleaser release

Top comments (0)