We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
A common use-case for build-time variables is to inject the Git version information in the binary. There are several approaches on how to do this, but this one is the one I found the most useful one.
Let's start with creating a sample project using Go modules:
$ mkdir example-go-build-time-variables
$ cd example-go-build-time-variables
$ go mod init github.com/pieterclaerhout/example-go-build-time-variables
go: creating new go.mod: module github.com/pieterclaerhout/example-go-build-time-variables
As we want to play with the Git revision and branch info, let's also initialize it as a Git repository:
$ echo "# example-go-build-time-variables" >> README.md
$ git init
Initialized empty Git repository in ~/example-go-build-time-variables/.git/
$ git add .
$ git commit -m "first commit"
[master (root-commit) 47c55c2] first commit
2 files changed, 4 insertions(+)
create mode 100644 README.md
create mode 100644 go.mod
Let's start with creating the most simple app we can think of by adding a main.go
file with the following contents:
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello stranger!")
}
Let's also create a package called version
in which the version information is going to be stored:
version/version.go
package version
// GitRevision will be injected with the current git commit hash
var GitRevision string
// GitBranch will be injected with the current git branch name
var GitBranch string
I prefer to create a non-related package just containing this information. This makes it easy to access the version information from anywhere.
We can then update the main.go
file to use this information:
main.go
package main
import (
"fmt"
"github.com/pieterclaerhout/example-go-build-time-variables/version"
)
func main() {
fmt.Println("Git Revision:", version.GitRevision)
fmt.Println("Git Branch:", version.GitBranch)
}
If we build and run it, you'll get the following output:
$ go build -o example-go-build-time-variables .
$ ./example-go-build-time-variables
Git Revision:
Git Branch:
That's the expected behaviour as we didn't inject the version information yet.
To inject the information, you need to specify the -ldflags
option during the go build
process. You can test it manually by changing the build command to:
$ go build -o example-go-build-time-variables -ldflags "-X github.com/pieterclaerhout/example-go-build-time-variables/version.GitRevision=revision -X github.com/pieterclaerhout/example-go-build-time-variables/version.GitBranch=branch" .
$ ./example-go-build-time-variables
Git Revision: revision
Git Branch: branch
Now, the only thing we need to do is to get the proper Git revision and branch name. The revision can be found with the following command:
$ git rev-parse --short HEAD
47c55c2
The branch name is obtained by the following command:
$ git rev-parse --abbrev-ref HEAD | tr -d '\040\011\012\015\n'
master
To make it easier, I usually combine everything in a simple Makefile
which looks as follows:
APPNAME := example-go-build-time-variables
PACKAGE := github.com/pieterclaerhout/example-go-build-time-variables/version
REVISION := $(shell git rev-parse --short HEAD)
BRANCH := $(shell git rev-parse --abbrev-ref HEAD | tr -d '\040\011\012\015\n')
build:
go build -ldflags "-X $(PACKAGE).GitRevision=$(REVISION) -X $(PACKAGE).GitBranch=$(BRANCH)" -o $(APPNAME)
run: build
./$(APPNAME)
You can then simply run either make build
to create the build or make run
to build and run the application:
make run
go build -ldflags "-X github.com/pieterclaerhout/example-go-build-time-variables/version.GitRevision=47c55c2 -X github.com/pieterclaerhout/example-go-build-time-variables/version.GitBranch=master" -o example-go-build-time-variables
./example-go-build-time-variables server
Git Revision: 47c55c2
Git Branch: master
The complete source code for this example can be found here.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.