Distributing prebuilt Go binaries on Github with Gox

Containers

Building command-line tools with Go is quite handy as it allows building standalone static binary. This is quite easy to build ready-to-use binaries for distribution.

While working on my Data Portability Kit, I wanted to be able to produce ready-made binaries to make the tools more accessible. Anyone should be able to use the software without deep technical knowledge.

In this article, I will show how I automated the build and distribution of the prebuilt tools for multiple platforms. I rely on Gox, a tool to easily cross-compile multiple version of a binary in parallel. I also used Ghr, a tool to upload multiple binary files as a Github release.

First of all, you need to install Gox and Ghr, with the following Go commands:

go get -u github.com/mitchellh/gox
go get -u github.com/tcnksm/ghr

Building binary for multiple platforms

First of all, you will need to tag your Git repository before the release:

git tag -a v0.0.1 -m "Release description"
git push --tags

You can then use Gox to build the mget tool for Windows, MacOS and Linux, focusing on the 64bits architecture:

(cd cmd/mget/; ~/go/bin/gox -os="linux darwin windows" -arch="amd64" -output="../../dist/mget_{{.OS}}_{{.Arch}}")
(cd dist; gzip *)

You end up with a dist directory containing three gzipped executable files, one for each OS.

Uploading the binary files to Github

You can now upload them, with Ghr. You will need to generate a personal token on Github. You can do so at the following URL: Github Personal Access Token. For a private repository, you need repo scope and for a public repository, you need public_repo scope.

export GITHUB_TOKEN=mytoken
export TAG=v0.0.1
~/go/bin/ghr -t $GITHUB_TOKEN -u processone -r dpk --replace --draft $TAG dist/

It will create a draft release on Github. You can edit the release and describe the release before actually publishing it.

Here is an example release: mget v0.0.1

That’s it! Your users can now enjoy prebuilt release of your tool.


Originally published at blog.process-one.net on January 7, 2019.