Publish Go binaries in Github with CircleCI

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:

Gopher. Driven by automation. #docker, #microservices, #golang. Co-Organizer at @GophersKatowice & @DockerKatowice

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store