Skip to content

Commit

Permalink
Comply with semantic versioning. Include build metadata in `argo vers…
Browse files Browse the repository at this point in the history
…ion` (resolves argoproj#594)
  • Loading branch information
jessesuen committed Dec 19, 2017
1 parent bb5ac7d commit c20c0f9
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 51 deletions.
41 changes: 22 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ CURRENT_DIR=$(shell pwd)
DIST_DIR=${CURRENT_DIR}/dist

VERSION=$(shell cat ${CURRENT_DIR}/VERSION)
REVISION=$(shell git rev-parse HEAD)
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
TAG=$(shell if [ -z "`git status --porcelain`" ]; then git describe --exact-match --tags HEAD 2>/dev/null; fi)
TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi)
BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
GIT_COMMIT=$(shell git rev-parse HEAD)
GIT_TAG=$(shell if [ -z "`git status --porcelain`" ]; then git describe --exact-match --tags HEAD 2>/dev/null; fi)
GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi)

BUILDER_IMAGE=argo-builder
# NOTE: the volume mount of ${DIST_DIR}/pkg below is optional and serves only
Expand All @@ -16,22 +16,25 @@ BUILDER_CMD=docker run --rm \
-v ${DIST_DIR}/pkg:/root/go/pkg \
-w /root/go/src/${PACKAGE} ${BUILDER_IMAGE}

LDFLAGS = \
-X ${PACKAGE}.version=${VERSION} \
-X ${PACKAGE}.buildDate=${BUILD_DATE} \
-X ${PACKAGE}.gitCommit=${GIT_COMMIT} \
-X ${PACKAGE}.gitTreeState=${GIT_TREE_STATE}

# docker image publishing options
DOCKER_PUSH=false
ifeq (${IMAGE_TAG},)
ifneq (${TAG},)
IMAGE_TAG=${TAG}
else
IMAGE_TAG=${VERSION}
IMAGE_TAG=latest
ifneq (${GIT_TAG},)
IMAGE_TAG=${GIT_TAG}
LDFLAGS += -X ${PACKAGE}.gitTag=${GIT_TAG}
endif
ifneq (${IMAGE_NAMESPACE},)
LDFLAGS += -X ${PACKAGE}/cmd/argo/commands.imageNamespace=${IMAGE_NAMESPACE}
endif
ifneq (${IMAGE_TAG},)
LDFLAGS += -X ${PACKAGE}/cmd/argo/commands.imageTag=${IMAGE_TAG}
endif

LDFLAGS = -ldflags "-X ${PACKAGE}.Version=${VERSION} \
-X ${PACKAGE}.Revision=${REVISION} \
-X ${PACKAGE}.Branch=${BRANCH} \
-X ${PACKAGE}.Tag=${TAG} \
-X ${PACKAGE}.ImageNamespace=${IMAGE_NAMESPACE} \
-X ${PACKAGE}.ImageTag=${IMAGE_TAG}"

ifeq (${DOCKER_PUSH},true)
ifndef IMAGE_NAMESPACE
Expand All @@ -52,7 +55,7 @@ builder:
docker build -t ${BUILDER_IMAGE} -f Dockerfile-builder .

cli:
go build -v -i ${LDFLAGS} -o ${DIST_DIR}/argo ./cmd/argo
go build -v -i -ldflags '${LDFLAGS}' -o ${DIST_DIR}/argo ./cmd/argo

cli-linux: builder
${BUILDER_CMD} make cli IMAGE_TAG=$(IMAGE_TAG)
Expand All @@ -63,7 +66,7 @@ cli-darwin: builder
mv ${DIST_DIR}/argo ${DIST_DIR}/argo-darwin-amd64

controller:
go build -v -i ${LDFLAGS} -o ${DIST_DIR}/workflow-controller ./cmd/workflow-controller
go build -v -i -ldflags '${LDFLAGS}' -o ${DIST_DIR}/workflow-controller ./cmd/workflow-controller

controller-linux: builder
${BUILDER_CMD} make controller
Expand All @@ -73,7 +76,7 @@ controller-image: controller-linux
if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)workflow-controller:$(IMAGE_TAG) ; fi

executor:
go build -v -i ${LDFLAGS} -o ${DIST_DIR}/argoexec ./cmd/argoexec
go build -v -i -ldflags '${LDFLAGS}' -o ${DIST_DIR}/argoexec ./cmd/argoexec

executor-linux: builder
${BUILDER_CMD} make executor
Expand Down
18 changes: 15 additions & 3 deletions cmd/argo/commands/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,27 @@ import (

const clusterAdmin = "cluster-admin"

var (
// These values may be overridden by the link flags during build
// (e.g. imageTag will use the official release tag on tagged builds)
imageNamespace = "argoproj"
imageTag = "latest"

// These are the default image names which `argo install` uses during install
DefaultControllerImage = imageNamespace + "/workflow-controller:" + imageTag
DefaultExecutorImage = imageNamespace + "/argoexec:" + imageTag
DefaultUiImage = imageNamespace + "/argoui:" + imageTag
)

func init() {
RootCmd.AddCommand(installCmd)
installCmd.Flags().StringVar(&installArgs.ControllerName, "controller-name", common.DefaultControllerDeploymentName, "name of controller deployment")
installCmd.Flags().StringVar(&installArgs.UIName, "ui-name", common.DefaultUiDeploymentName, "name of ui deployment")
installCmd.Flags().StringVar(&installArgs.Namespace, "install-namespace", common.DefaultControllerNamespace, "install into a specific Namespace")
installCmd.Flags().StringVar(&installArgs.ConfigMap, "configmap", common.DefaultConfigMapName(common.DefaultControllerDeploymentName), "install controller using preconfigured configmap")
installCmd.Flags().StringVar(&installArgs.ControllerImage, "controller-image", common.DefaultControllerImage, "use a specified controller image")
installCmd.Flags().StringVar(&installArgs.UIImage, "ui-image", common.DefaultUiImage, "use a specified ui image")
installCmd.Flags().StringVar(&installArgs.ExecutorImage, "executor-image", common.DefaultExecutorImage, "use a specified executor image")
installCmd.Flags().StringVar(&installArgs.ControllerImage, "controller-image", DefaultControllerImage, "use a specified controller image")
installCmd.Flags().StringVar(&installArgs.UIImage, "ui-image", DefaultUiImage, "use a specified ui image")
installCmd.Flags().StringVar(&installArgs.ExecutorImage, "executor-image", DefaultExecutorImage, "use a specified executor image")
installCmd.Flags().StringVar(&installArgs.ServiceAccount, "service-account", "", "use a specified service account for the workflow-controller deployment")
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/argoexec/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func initExecutor() *executor.WorkflowExecutor {
Namespace: namespace,
}
yamlBytes, _ := yaml.Marshal(&wfExecutor.Template)
log.Infof("Executor (version: %s) initialized with template:\n%s", argo.FullVersion, string(yamlBytes))
log.Infof("Executor (version: %s) initialized with template:\n%s", argo.GetVersion(), string(yamlBytes))
return &wfExecutor
}

Expand Down
20 changes: 18 additions & 2 deletions util/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,29 @@ import (

// NewVersionCmd returns a new `version` command to be used as a sub-command to root
func NewVersionCmd(cliName string) *cobra.Command {
return &cobra.Command{
var short bool
versionCmd := cobra.Command{
Use: "version",
Short: fmt.Sprintf("Print version information"),
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("%s version %s\n", cliName, argo.FullVersion)
version := argo.GetVersion()
fmt.Printf("%s: %s\n", cliName, version)
if short {
return
}
fmt.Printf(" BuildDate: %s\n", version.BuildDate)
fmt.Printf(" GitCommit: %s\n", version.GitCommit)
fmt.Printf(" GitTreeState: %s\n", version.GitTreeState)
if version.GitTag != "" {
fmt.Printf(" GitTag: %s\n", version.GitTag)
}
fmt.Printf(" GoVersion: %s\n", version.GoVersion)
fmt.Printf(" Compiler: %s\n", version.Compiler)
fmt.Printf(" Platform: %s\n", version.Platform)
},
}
versionCmd.Flags().BoolVar(&short, "short", false, "print just the version number")
return &versionCmd
}

// MustIsDir returns whether or not the given filePath is a directory. Exits if path does not exist
Expand Down
74 changes: 55 additions & 19 deletions version.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,64 @@
package argo

import "fmt"
import (
"fmt"
"runtime"
)

// Version information set by link flags during build
// Version information set by link flags during build. We fall back to these sane
// default values when we build outside the Makefile context (e.g. go build or go test).
var (
Version = "unknown"
Revision = "unknown"
Branch = "unknown"
Tag = ""
BuildDate = "unknown"
FullVersion = "unknown"
ImageNamespace = ""
ImageTag = Version
version = "0.0.0" // value from VERSION file
buildDate = "1970-01-01T00:00:00Z" // output from `date -u +'%Y-%m-%dT%H:%M:%SZ'`
gitCommit = "" // output from `git rev-parse HEAD`
gitTag = "" // output from `git describe --exact-match --tags HEAD` (if clean tree state)
gitTreeState = "" // determined from `git status --porcelain`. either 'clean' or 'dirty'
)

func init() {
if ImageNamespace == "" {
ImageNamespace = "argoproj"
}
if Tag != "" {
// if a git tag was set, use that as our version
FullVersion = Tag
ImageTag = Tag
// Version contains Argo version information
type Version struct {
Version string
BuildDate string
GitCommit string
GitTag string
GitTreeState string
GoVersion string
Compiler string
Platform string
}

func (v Version) String() string {
return v.Version
}

// GetVersion returns the version information
func GetVersion() Version {
var versionStr string
if gitCommit != "" && gitTag != "" && gitTreeState == "clean" {
// if we have a clean tree state and the current commit is tagged,
// this is an official release.
versionStr = gitTag
} else {
FullVersion = fmt.Sprintf("v%s-%s", Version, Revision[0:7])
// otherwise formulate a version string based on as much metadata
// information we have available.
versionStr = "v" + version
if len(gitCommit) >= 7 {
versionStr += "+" + gitCommit[0:7]
if gitTreeState != "clean" {
versionStr += ".dirty"
}
} else {
versionStr += "+unknown"
}
}
return Version{
Version: versionStr,
BuildDate: buildDate,
GitCommit: gitCommit,
GitTag: gitTag,
GitTreeState: gitTreeState,
GoVersion: runtime.Version(),
Compiler: runtime.Compiler,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
}
}
7 changes: 0 additions & 7 deletions workflow/common/common.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
package common

import (
"github.com/argoproj/argo"
wfv1 "github.com/argoproj/argo/api/workflow/v1alpha1"
)

var (
DefaultControllerImage = argo.ImageNamespace + "/workflow-controller:" + argo.ImageTag
DefaultExecutorImage = argo.ImageNamespace + "/argoexec:" + argo.ImageTag
DefaultUiImage = argo.ImageNamespace + "/argoui:" + argo.ImageTag
)

const (
// DefaultControllerDeploymentName is the default deployment name of the workflow controller
DefaultControllerDeploymentName = "workflow-controller"
Expand Down
2 changes: 2 additions & 0 deletions workflow/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
goruntime "runtime"
"time"

"github.com/argoproj/argo"
wfv1 "github.com/argoproj/argo/api/workflow/v1alpha1"
"github.com/argoproj/argo/errors"
workflowclient "github.com/argoproj/argo/workflow/client"
Expand Down Expand Up @@ -98,6 +99,7 @@ func (wfc *WorkflowController) Run(ctx context.Context) {
defer wfc.wfQueue.ShutDown()
defer wfc.podQueue.ShutDown()

log.Infof("Workflow Controller (version: %s) starting", argo.GetVersion())
log.Info("Watch Workflow controller config map updates")
_, err := wfc.watchControllerConfigMap(ctx)
if err != nil {
Expand Down

0 comments on commit c20c0f9

Please sign in to comment.