govvv — Versioning for Go binaries

Ahmet Alp Balkan
2 min readAug 11, 2016

--

Go is getting increasingly popular when it comes to writing microservices and commmand-line tools. It easily lets you compile a complicated application into a single binary, it can cross-compile from any OS to any other OS the Go compiler supports.

Go compiler has this nice LDFLAGS trick to assign values to the variables in the program at the compile time. So if you have a Version variable in your program you can compile it as:

$ go build -ldflags "-X main.Version=2.0.0"

This trick is really popular that pretty much everybody distributing Go binaries are using it to embed app version, git commit number etc. to the binaries. Learn more about it here and here.

Problem is, you will easily end up with the following command:

$ go build -ldflags "-X main.BuildDate=`date -u --rfc-3339=seconds | sed -e 's/ /T/'` \
-X main.GitCommit=`git rev-parse --short HEAD` \
-X main.GitBranch=`git symbolic-ref -q --short HEAD` \
-X main.State=`if [ -n "$(git status --porcelain)" ]; then echo 'dirty'; fi` \
-X main.Version=`<./VERSION`"

and find yourself creating a Makefile for it. Ugh…

Enter govvv

I wrote this go build wrapper that handles all this jazz for you. It’s called govvv. Check it out on GitHub.

Ytop ou just call govvv build instead of go build without an -ldflags argument and it handles it all for you:

Stop worrying and call “govvv build”

govvv is a very-opinionated take on Go binary versioning problem. It offers you various variables, some of them are:

  • main.BuildDate
  • main.GitCommit+main.GitState (e.g. 85f5a13-dirty)
  • main.GitBranch (e.g. master)
  • main.Version if there is a ./VERSION file in your repo

Read the documentation to learn more.

Just add a VERSION file to your repo and govvv will handle the rest.

Why govvv?

Well, mostly because repeating the same go build -ldflags … over and over again sucks. govvv gives you a predefined set of variables that will be provided to your program at compile-time.

govvv honors your existing -ldflags and works well with them.

govvv itself is compiled with govvv. What’s more to say?

Why not govvv?

govvv will be yet another external depdency to your project. It is not a package you import, but it is a tool like go lint that you go get in your build jobs.

I know, it sucks, and you should decide whether it is better than copypasting the same Makefile around. You can download a binary release or just vendor the code into your build environment to build it offline.

Originally published at ahmetalpbalkan.com.

--

--