Initially we used to build the binary locally, then push it to the repository.

In addition to being potentially misleading — how can you be sure that the committed binary is representative of the latest changes — this method required to clone the whole repository in order to get the latest binary… not elegant at all.

That approach was good enough considering our needs but it could be automated and that’s what I did.

I remembered some slides by Taichi Nakashima, What I Talk About When I Talk About CLI Tool By Golang, that showcased a nice tool (ghr) which uploads artifacts to the Github release page.

Retrieving the binaries then is dead simple and linked to a release, that’s easy to automatise using CircleCI in the deployment stage.

Here’s how it looks in my circle.yml.

deployment:

release:

branch: master

commands:

— go get github.com/mitchellh/gox

— go get github.com/tcnksm/ghr

— gox -ldflags "-X main.Version $BUILD_VERSION -X main.BuildDate $BUILD_DATE" -output "dist/ncd_{{.OS}}_{{.Arch}}"

— ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME --replace `git describe --tags` dist/

A few details:

gox is a wrapper around go build that simplifies further cross-compilation.

The binaries are stamped with the version and build date passed through -ldflags.

$GITHUB_TOKEN has to be defined in your CircleCI environment (Project Settings > Environment Variables). Read more about Access Tokens on Github.

ghr publishes artifacts to the latest tag, it supposes you’re following a workflow with proper application versioning (ex. semver).

Here’s the result in Github: