/ GoLang

Embed versioning information in golang binary

This article is an extension to my previous artical on Statically compile GOLANG programs. In this article we will link/inject version related information while statically linking the binary. To do so, let's use the code that we produced during restful article which can be found at github.

Add following line at the begning of the main.go just below the imports

  var Version string

and add

  fmt.Printf(`Version: %s`, Version)

as the first line inside func main(). What we did is added an exported uninitialized variable called Version in main package and then printing it as soon as the program starts. We can inject values in such variables during compilation using -ldflags option.

env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -ldflags "-X main.Version=v0.1" -o app

Notice -ldflags "-X main.Version=v0.1", we are telling compiler to link main.Version (which is a string) to v0.1. If you invoke the binary, you'll see

   Version: v0.1
   Listining at 127.0.0.1:8000

How awesome is that! While we are here, why not add more information like branch, commit id and some other stuff. Ahmet Alp Balkan created a tool called govvv just to make our lives easier. You can get the package by

go get -u -v github.com/ahmetb/govvv

govvv by default generates linking arguments for various items. In your package directory, run govvv -flags, when i execute it on my machine I get following

-X main.BuildDate=2018-08-16T08:15:32Z -X main.GitCommit=6757aab -X main.GitBranch=versioned -X main.GitState=dirty -X main.GitSummary=6757aab-dirty

It assumes you have following exported variables in your main package defined:

  • GitCommit holds short commit hash of source tree
  • GitBranch holds current branch name the code is built off
  • GitState shows whether there are uncommitted changes
  • GitSummary holds output of git describe --tags --dirty --always
  • BuildDate holds RFC3339 formatted UTC date (build time)
  • Version holds contents of ./VERSION file, if exists, or the value passed via the -version option

So lets define these variables in our main.go

   // Following variables will be statically linked at the time of compiling

   // GitCommit holds short commit hash of source tree
   var GitCommit string

   // GitBranch holds current branch name the code is built off
   var GitBranch string

   // GitState shows whether there are uncommitted changes
   var GitState string

   // GitSummary holds output of git describe --tags --dirty --always
   var GitSummary string

   // BuildDate holds RFC3339 formatted UTC date (build time)
   var BuildDate string

   // Version holds contents of ./VERSION file, if exists, or the value passed via the -version option
   var Version string

and update fmt.Printf statement in func main()

fmt.Printf(`
   GitCommit: %s
   GitBranch: %s
    GitState: %s
  GitSummary: %s
   BuildDate: %s
     Version: %s
	`, GitCommit, GitBranch, GitState, GitSummary, BuildDate, Version)

We also need to create a file called VERSION with a single line v0.1

Now all we need to do is modify our build command as shown below

env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -ldflags "$(govvv -flags)" -o app

Notice -ldflags "$(govvv -flags)" we are leaving generation of proper flags to govvv.

Go ahead and invoke ./app, I get following output

	GitCommit: 6757aab
	GitBranch: versioned
	GitState: dirty
	GitSummary: 6757aab-dirty
	BuildDate: 2018-08-16T15:20:08Z
	Version: v0.1
	Listining at 127.0.0.1:8000

When I execute it after commit I get following

	GitCommit: 0ca08a7
	GitBranch: versioned
	GitState: clean
	GitSummary: 0ca08a7
	BuildDate: 2018-08-16T15:51:02Z
	Version: v0.1
	Listining at 127.0.0.1:8000

Notice that GitCommit changed from 6757aab to 0ca08a7 and GitState changed from dirty to clean same is also reflected in GitSummary.

Well that's it!

Full source code is available at github

Cheers and Happy coding!

Dave Amit

Dave Amit

Howdy folks! I am Dave Amit, an accidental programmer, father to a lab puppy, hubby to a beautiful wife, addicted to puzzles & a noob blogger. This is my effort to simplify odd codes from the wild.

Read More