2025-04-20 Build Info In Go Binaries
I like having assorted build info in my Go binaries and here’s how I do it.
At the core: Go linker flags, specifically -X importpath.name=value
- “Set the value of the string variable in importpath
named name
to value
.”
Other methods exist but this is the right combination of powerful, resilient, and clear for me.
This lets me do this in my code:
var GIT_VERSION string
var GIT_BRANCH string
var BUILT_AT string
And then this at build time (taken from my Makefile
, hence the $$
):
-ldflags "-X 'main.GIT_VERSION=$$(./git-version)' -X 'main.BUILT_AT=$$(date)' -X 'main.GIT_BRANCH=$$(git symbolic-ref --short HEAD)'"`
That gives me:
BUILT_AT
which is just the build timestamp - useful to make sure I’ve not missed restarting a service to pick up changes etc.GIT_BRANCH
which is, unsurprisingly, the name of the branch - useful to see if I’m running on amain
build, or something from a feature branchGIT_VERSION
which is the output of a short script that gives me a slightly more detailed idea of what I built from
git-version
is:
#!/bin/bash
HEAD_HASH=$(git rev-list -1 HEAD)
GITVERSION=$HEAD_HASH
# https://stackoverflow.com/a/2659808
DIRTY=$(git diff-index --quiet HEAD -- || echo '-DIRTY')
GITVERSION+=$DIRTY
echo "$GITVERSION"
which outputs the commit hash as a string, plus a -DIRTY
suffix if there are uncommitted changes - useful to know exactly what I built from, and/or if there was anything funky - e.g.:
$ ./git-version
ace0fba5eace0fba5eace0fba5eace0fba5e-DIRTY
Then I can simply use those as needed, e.g. for dumping information when running with --version
:
$ ./mybin --version
GIT_VERSION: ace0fba5eace0fba5eace0fba5eace0fba5e-DIRTY
GIT_BRANCH: feature/foo
BUILT_AT: Mon 30 Feb 1712 03:13:37 CEST
I don’t write a huge amount of Go, so it wouldn’t surprise me to learn that there are better ways / room for improvement, but this works nicely for me!