Skip to content

erwinvaneyk/goversion

Repository files navigation

Goversion

Simplified versioning for Go applications.

The project consists out of two parts:

  1. The version library github.com/erwinvaneyk/goversion for providing version info and corresponding operations.
  2. The optional goversion CLI to simplify generating ldflags and versioning fields.

Installation

To use this library in your Go project, all you need to do is in the context of the project:

go get -u github.com/erwinvaneyk/goversion

To install the optional goversion CLI, use one of the following options:

Using a pre-built release to get the goversion CLI

To download a stable release of goversion, see the Github Releases. For example, to download the latest version run the following:

# Change to get an older version.
VERSION=v0.1.2

# Download goversion
curl -L https://github.com/erwinvaneyk/goversion/releases/download/${VERSION}/goversion_$(echo $VERSION | sed 's/v//')_$(uname)_$(uname -m).tar.gz > goversion.tar.gz
tar -xvf goversion.tar.gz
mv ./goversion /usr/local/bin/goversion

# Check if goversion is working
which goversion && goversion version 

Using Go tools to get the goversion CLI

To pin your project to a specific version of goversion, add the following tools.go file to your (module-enabled) Go project:

// +build tools

//go:generate go install github.com/erwinvaneyk/goversion
package main

import (
	_ "github.com/erwinvaneyk/goversion"
)

The first time, run the following to add goversion as dependency to your project:

go get -u github.com/erwinvaneyk/goversion/cmd/goversion

Finally, to install the binary on your path run the go generator on this file:

go generate -tags=tools ./tools.go

Note: ensure that you have added your GOBIN directory to your PATH.

Build the goversion CLI from source

To build and install the CLI from source, clone the repo and run make:

git clone git@github.com:erwinvaneyk/goversion.git
cd goversion

# Builds goversion and stores it in the ./bin directory.
make goversion

# Build and add goversion to your PATH.
# Note: ensure that you have added your `GOBIN` directory to your `PATH`.
make install

Usage

There are two ways to make use of goversion in your project. Both assume that you have added the package to your module or GOPATH. If you haven't:

go get github.com/erwinvaneyk/goversion

Using the imported package.

To use goversion, import and use the package somewhere in your application.
For example:

package main

import (
	"fmt"

	"github.com/erwinvaneyk/goversion"
)

func main() {
	fmt.Println(goversion.Get())
}
# With goversion:
go run $(goversion ldflags --version v1.0.1) ./simple

# Or, manually:
go run -ldflags ' \
		-X "github.com/erwinvaneyk/goversion.version=v1.0.1" \
		-X "github.com/erwinvaneyk/goversion.gitCommit=$(git rev-parse HEAD)" \
		-X "github.com/erwinvaneyk/goversion.buildDate=$(date)"' \
	    ./simple

Using generated fields

Using the package does require a long package name to be added, and is not that extensible. So, if you have goversion installed, you could also generate the ldflag fields in your main package:

goversion generate -o /path/to/your/main/package/version.gen.go

Or use the go tooling for the generation process, add the following:

//go:generate goversion generate -o version.gen.go
package main

// ...

And run

go generate

Both options will generate a file with the versioninfo fields in the main package:

// Generated by goversion
package main

import github.com/erwinvaneyk/goversion

// The following variables should be filled with goversion ldflags 
var (
	version   string
	gitCommit string
	buildDate string
	goVersion string
)

func init() {
	goversion.Set(goversion.Info{
		Version:   version,
		GitCommit: gitCommit,
		BuildDate: buildDate,
		GoVersion: goVersion,
	})
}

Using the generated code, you can now set the ldflags using the shorter main instead of the full package name:

# With goversion:
go run $(goversion ldflags --pkg main --version v1.0.4) ./generated 

# Or, manually:
go run -ldflags ' \
    		-X "main.version=v1.0.3" \
    		-X "main.gitCommit=$(git rev-parse HEAD)" \
    		-X "main.buildDate=$(date)"' \
    		./generated

See the examples for complete, functioning examples.

Using Cobra

This project contains a default command to include into your Cobra based CLI. Just add the following line to the setup of your root command:

import (
	goversionext "github.com/erwinvaneyk/goversion/pkg/extensions"
)

func init() {
    // ...
	cmd.AddCommand(goversionext.NewCobraCmd())
    // ...
}

Reproducible Builds

To make your builds, checksums, and signatures reproducible, you will need to make the following modifications when generating the ldflags:

  • Manually set the --build-date to a specific date and time at which the build should be done.