Versioning your Go Builds

By Vagmi on 20 Sep 2017

I found a rather cool feature of Go that is very useful to version your Go binaries. The go build tool lets you set variables at compile time. The the following program for instance.

1
2
3
4
5
6
7
package main

var Name String

func main() {
        fmt.Println("hello ", Name)
}

You can set the value of the variable name at compile time by using the ldflags parameter.

1
$ go build -ldflags "-X main.Name=TarkaLabs"

The -X flag sets the variable during the build process. This now prints hello TarkaLabs. We can use this to version our shiny micro service. I usually setup a version package where I stick my variables.

1
2
3
4
5
6
7
8
9
10
11
12
package version

import "fmt"

var Commit, Branch, State, TimeStamp string

func PrintVersion() {
	fmt.Printf("Commit : %s\n", Commit)
	fmt.Printf("Branch: %s\n", Branch)
	fmt.Printf("State : %s\n", State)
	fmt.Printf("TimeStamp: %s\n", TimeStamp)
}

I can then setup a Makefile to inject these variables at compile time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
VERSION_PACKAGE=github.com/tarkalabs/muservice/version
COMMIT=`git rev-parse --short -q HEAD`
BRANCH=`git symbolic-ref -q --short HEAD`
STATE=`if [ -n "$(git status --porcelain)" ]; then echo 'dirty'; else echo 'clean'; fi`
TIMESTAMP=`date -u +'%Y-%m-%dT%H:%M:%SZ'`

LDFLAGS=-ldflags "-X ${VERSION_PACKAGE}.Commit=${COMMIT} \
                  -X ${VERSION_PACKAGE}.Branch=${BRANCH} \
                  -X ${VERSION_PACKAGE}.State=${STATE} \
                  -X ${VERSION_PACKAGE}.TimeStamp=${TIMESTAMP}"

default:
	go build ${LDFLAGS}

So this way we can set up these variables as a part of the build pipeline without having to go through weird sed hacks to manipulate code.

comments powered by Disqus