Skip to content

Commit

Permalink
Improve Application Versioning (#108)
Browse files Browse the repository at this point in the history
* Improve Application Versioning

This will allow for better bug reports and information the binary running.
This information can be retrieved upon providing the -v or --version
flag

* fixup: fix update-version and use variables to be more consistent
  • Loading branch information
jcscottiii authored and kcajmagic committed Oct 14, 2019
1 parent 8b3c443 commit b3582c2
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 19 deletions.
36 changes: 24 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ DEFAULT: build
GO ?= go
GOFMT ?= $(GO)fmt
APP := talaria
DOCKER_ORG := xmidt
FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))
BINARY := $(FIRST_GOPATH)/bin/$(APP)

PROGVER = $(shell grep 'applicationVersion.*= ' main.go | awk '{print $$3}' | sed -e 's/\"//g')
PROGVER = $(shell git describe --tags `git rev-list --tags --max-count=1` | tail -1 | sed 's/v\(.*\)/\1/')
RPM_VERSION=$(shell echo $(PROGVER) | sed 's/\(.*\)-\(.*\)/\1/')
RPM_RELEASE=$(shell echo $(PROGVER) | sed -n 's/.*-\(.*\)/\1/p' | grep . && (echo "$(echo $(PROGVER) | sed 's/.*-\(.*\)/\1/')") || echo "1")
BUILDTIME = $(shell date -u '+%Y-%m-%d %H:%M:%S')
GITCOMMIT = $(shell git rev-parse --short HEAD)

.PHONY: go-mod-vendor
go-mod-vendor:
Expand All @@ -18,16 +23,16 @@ build: go-mod-vendor

rpm:
mkdir -p ./.ignore/SOURCES
tar -czf ./.ignore/SOURCES/$(APP)-$(PROGVER).tar.gz --transform 's/^\./$(APP)-$(PROGVER)/' --exclude ./.git --exclude ./.ignore --exclude ./conf --exclude ./deploy --exclude ./vendor --exclude ./vendor .
tar -czf ./.ignore/SOURCES/$(APP)-$(RPM_VERSION)-$(RPM_RELEASE).tar.gz --transform 's/^\./$(APP)-$(RPM_VERSION)-$(RPM_RELEASE)/' --exclude ./.git --exclude ./.ignore --exclude ./conf --exclude ./deploy --exclude ./vendor --exclude ./vendor .
cp conf/$(APP).service ./.ignore/SOURCES
cp $(APP).yaml ./.ignore/SOURCES
cp LICENSE ./.ignore/SOURCES
cp NOTICE ./.ignore/SOURCES
cp CHANGELOG.md ./.ignore/SOURCES
rpmbuild --define "_topdir $(CURDIR)/.ignore" \
--define "_version $(PROGVER)" \
--define "_release 1" \
-ba deploy/packaging/$(APP).spec
--define "_version $(RPM_VERSION)" \
--define "_release $(RPM_RELEASE)" \
-ba deploy/packaging/$(APP).spec

.PHONY: version
version:
Expand All @@ -44,28 +49,35 @@ endif
.PHONY: update-version
update-version:
@echo "Update Version $(PROGVER) to $(RUN_ARGS)"
sed -i "s/$(PROGVER)/$(RUN_ARGS)/g" main.go
git tag v$(RUN_ARGS)


.PHONY: install
install: go-mod-vendor
echo $(GO) build -o $(BINARY) $(PROGVER)
go install -ldflags "-X 'main.BuildTime=$(BUILDTIME)' -X main.GitCommit=$(GITCOMMIT) -X main.Version=$(PROGVER)"

.PHONY: release-artifacts
release-artifacts: go-mod-vendor
mkdir -p ./.ignore
GOOS=darwin GOARCH=amd64 $(GO) build -o ./.ignore/$(APP)-$(PROGVER).darwin-amd64
GOOS=linux GOARCH=amd64 $(GO) build -o ./.ignore/$(APP)-$(PROGVER).linux-amd64
GOOS=darwin GOARCH=amd64 $(GO) build -ldflags "-X 'main.BuildTime=$(BUILDTIME)' -X main.GitCommit=$(GITCOMMIT) -X main.Version=$(PROGVER)" -o ./.ignore/$(APP)-$(PROGVER).darwin-amd64
GOOS=linux GOARCH=amd64 $(GO) build -ldflags "-X 'main.BuildTime=$(BUILDTIME)' -X main.GitCommit=$(GITCOMMIT) -X main.Version=$(PROGVER)" -o ./.ignore/$(APP)-$(PROGVER).linux-amd64

.PHONY: docker
docker:
docker build -f ./deploy/Dockerfile -t $(APP):$(PROGVER) .
docker build \
--build-arg VERSION=$(PROGVER) \
--build-arg GITCOMMIT=$(GITCOMMIT) \
--build-arg BUILDTIME='$(BUILDTIME)' \
-f ./deploy/Dockerfile -t $(DOCKER_ORG)/$(APP):$(PROGVER) .

# build docker without running modules
.PHONY: local-docker
local-docker:
GOOS=linux GOARCH=amd64 $(GO) build -o $(APP)_linux_amd64
docker build -f ./deploy/Dockerfile.local -t $(APP):local .
docker build \
--build-arg VERSION=$(PROGVER)+local \
--build-arg GITCOMMIT=$(GITCOMMIT) \
--build-arg BUILDTIME='$(BUILDTIME)' \
-f ./deploy/Dockerfile.local -t $(DOCKER_ORG)/$(APP):local .

.PHONY: style
style:
Expand Down
5 changes: 4 additions & 1 deletion deploy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ FROM golang:alpine as builder
MAINTAINER Jack Murdock <[email protected]>

WORKDIR /go/src/github.com/xmidt-org/talaria
ARG VERSION=undefined
ARG GITCOMMIT=undefined
ARG BUILDTIME=undefined

RUN apk update && apk upgrade && \
apk add --no-cache bash git openssh

COPY . .
RUN GO111MODULE=on go build -o talaria_linux_amd64
RUN GO111MODULE=on go build -ldflags "-X 'main.BuildTime=${BUILDTIME}' -X main.GitCommit=${GITCOMMIT} -X main.Version=${VERSION}" -o talaria_linux_amd64

FROM alpine

Expand Down
5 changes: 4 additions & 1 deletion deploy/Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ FROM golang:alpine as builder
MAINTAINER Jack Murdock <[email protected]>

WORKDIR /go/src/github.com/xmidt-org/talaria
ARG VERSION=undefined
ARG GITCOMMIT=undefined
ARG BUILDTIME=undefined

RUN apk add --update git curl

COPY . .

RUN go build -o talaria_linux_amd64
RUN go build -ldflags "-X 'main.BuildTime=${BUILDTIME}' -X main.GitCommit=${GITCOMMIT} -X main.Version=${VERSION}" -o talaria_linux_amd64

FROM alpine

Expand Down
2 changes: 1 addition & 1 deletion deploy/packaging/talaria.spec
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ BuildRequires: golang >= 1.12
The XMiDT routing agent.

%build
GO111MODULE=on go build -o $RPM_SOURCE_DIR/%{name} %{_topdir}/..
GO111MODULE=on go build -ldflags "-X 'main.BuildTime=`date -u '+%Y-%m-%d %H:%M:%S'`' -X main.GitCommit=`git rev-parse --short HEAD` -X main.Version=%{_version}" -o $RPM_SOURCE_DIR/%{name} %{_topdir}/..

%install
echo rm -rf %{buildroot}
Expand Down
49 changes: 45 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ package main

import (
"fmt"
"io"
_ "net/http/pprof"
"os"
"os/signal"
"runtime"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
Expand All @@ -39,10 +41,15 @@ import (
)

const (
applicationName = "talaria"
release = "Developer"
defaultVnodeCount int = 211
applicationVersion = "0.1.3"
applicationName = "talaria"
release = "Developer"
defaultVnodeCount int = 211
)

var (
GitCommit = "undefined"
Version = "undefined"
BuildTime = "undefined"
)

func newDeviceManager(logger log.Logger, r xmetrics.Registry, v *viper.Viper) (device.Manager, error) {
Expand Down Expand Up @@ -83,6 +90,18 @@ func talaria(arguments []string) int {
logger, metricsRegistry, webPA, err = server.Initialize(applicationName, arguments, f, v, Metrics, device.Metrics, rehasher.Metrics, service.Metrics)
)

if parseErr, done := printVersion(f, arguments); done {
// if we're done, we're exiting no matter what
if parseErr != nil {
friendlyError := fmt.Sprintf("failed to parse arguments. detailed error: %s", parseErr)
logging.Error(logger).Log(
logging.ErrorKey(),
friendlyError)
os.Exit(1)
}
os.Exit(0)
}

if err != nil {
logger.Log(level.Key(), level.ErrorValue(), logging.MessageKey(), "Unable to initialize Viper environment", logging.ErrorKey(), err)
return 1
Expand Down Expand Up @@ -181,6 +200,28 @@ func talaria(arguments []string) int {
return 0
}

func printVersion(f *pflag.FlagSet, arguments []string) (error, bool) {
printVer := f.BoolP("version", "v", false, "displays the version number")
if err := f.Parse(arguments); err != nil {
return err, true
}

if *printVer {
printVersionInfo(os.Stdout)
return nil, true
}
return nil, false
}

func printVersionInfo(writer io.Writer) {
fmt.Fprintf(writer, "%s:\n", applicationName)
fmt.Fprintf(writer, " version: \t%s\n", Version)
fmt.Fprintf(writer, " go version: \t%s\n", runtime.Version())
fmt.Fprintf(writer, " built time: \t%s\n", BuildTime)
fmt.Fprintf(writer, " git commit: \t%s\n", GitCommit)
fmt.Fprintf(writer, " os/arch: \t%s/%s\n", runtime.GOOS, runtime.GOARCH)
}

func main() {
os.Exit(
func() int {
Expand Down
96 changes: 96 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* Copyright 2017 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package main

import (
"bytes"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestPrintVersionInfo(t *testing.T) {
testCases := []struct {
name string
expectedOutput []string
overrideValues func()
lineCount int
}{
{
"default",
[]string{
"talaria:",
"version: \tundefined",
"go version: \tgo",
"built time: \tundefined",
"git commit: \tundefined",
"os/arch: \t",
},
func() {},
6,
},
{
"set values",
[]string{
"talaria:",
"version: \t1.0.0\n",
"go version: \tgo",
"built time: \tsome time\n",
"git commit: \tgit sha\n",
"os/arch: \t",
},
func() {
Version = "1.0.0"
BuildTime = "some time"
GitCommit = "git sha"
},
6,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
resetGlobals()
tc.overrideValues()
buf := &bytes.Buffer{}
printVersionInfo(buf)
count := 0
for {
line, err := buf.ReadString(byte('\n'))
if err != nil {
break
}
assert.Contains(t, line, tc.expectedOutput[count])
if strings.Contains(line, "\t") {
keyAndValue := strings.Split(line, "\t")
// The value after the tab should have more than 2 characters
// 1) the first character of the value and the new line
assert.True(t, len(keyAndValue[1]) > 2)
}
count++
}
assert.Equal(t, tc.lineCount, count)
resetGlobals()
})
}
}

func resetGlobals() {
Version = "undefined"
BuildTime = "undefined"
GitCommit = "undefined"
}

0 comments on commit b3582c2

Please sign in to comment.