Application auto build versioning
Use ldflags
to set variables in main
package:
With file main.go
:
package main
import "fmt"
var (
version string
build string
)
func main() {
fmt.Println("version=", version)
fmt.Println("build=", build)
}
Then run:
go run \
-ldflags "-X main.version=1.0.0 -X main.build=12082019" \
main.go
Build:
go build -o mybinary \
-ldflags "-X main.version=1.0.0 -X 'main.build=$(date)'" \
main.go
Use ldflags
to set variable in a non-main
package:
With file config.go
:
package config
import "fmt"
var (
Version string
)
func LogVersion() {
fmt.Println("version=", Version)
}
You will also need file main.go
:
package main
import (
"fmt"
"github.com/user/repo/config"
}
func main() {
config.LogVersion()
}
Build your binary first:
go build -o mybinary main.go
Find the full path of variable name you want to set:
go tool nm <path_to_binary> | grep Version
Run and build the binary again but with the ldflags
:
go run \
-ldflags "-X github.com/user/repo/config.Version=1.0.0" \
main.go --version
go build -o mybinary \
-ldflags "-X github.com/user/repo/config.Version=1.0.0" \
main.go
Inspired by https://github.com/golang/go/wiki/GcToolchainTricks#including-build-information-in-the-executable
Also if you are using goreleaser
then read this https://goreleaser.com/environment/#using-the-mainversion :
Default wise GoReleaser sets three ldflags:
main.version: Current Git tag
main.commit: Current git commit SHA
main.date: Date according RFC3339
If you want to see this in action: https://github.com/hoto/fuzzy-repo-finder/blob/master/pkg/config/config.go
The Go linker (go tool link) has an option to set the value of an uninitialised string variable:
-X importpath.name=value Set the value of the string variable in importpath named name to
value. Note that before Go 1.5 this option took two separate arguments. Now it takes one argument split on the first = sign.
As part of your build process, you could set a version string variable using this. You can pass this through the go
tool using -ldflags
. For example, given the following source file:
package main
import "fmt"
var xyz string
func main() {
fmt.Println(xyz)
}
Then:
$ go run -ldflags "-X main.xyz=abc" main.go
abc
In order to set main.minversion
to the build date and time when building:
go build -ldflags "-X main.minversion=`date -u +.%Y%m%d.%H%M%S`" service.go
If you compile without initializing main.minversion
in this way, it will contain the empty string.