Skip to content

Commit

Permalink
Update Versioning to Improve Output (#5000)
Browse files Browse the repository at this point in the history
* Update Versioning to Improve Output

* Always get commit from build info, always get date and version from ldflag

* Just replace broken main output with semver and deprecate short flag as is

---------

Co-authored-by: Katrina Verey <katrina.verey@shopify.com>
  • Loading branch information
Cailyn and KnVerey committed Feb 1, 2023
1 parent 9d8ed39 commit 95edcc0
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 36 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ $(MYGOBIN)/pluginator:
# Build from local source.
$(MYGOBIN)/kustomize: build-kustomize-api
cd kustomize; \
go install .
go install -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')" \
.

kustomize: $(MYGOBIN)/kustomize

Expand Down
4 changes: 2 additions & 2 deletions api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
include ../Makefile-modules.mk

test:
go test -v -timeout 45m -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
go test -v -timeout 45m -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=2023-01-31T23:38:41Z -X sigs.k8s.io/kustomize/api/provenance.version=(test)"

build:
go build -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222" ./...
go build -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")" ./...

generate: $(MYGOBIN)/k8scopy $(MYGOBIN)/stringer
go generate ./...
4 changes: 2 additions & 2 deletions api/krusty/managedbylabel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ const expected = `apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/managed-by: kustomize-v444.333.222
app.kubernetes.io/managed-by: kustomize-(test)
name: myService
spec:
ports:
- port: 7002
`

// This test may failed when running on package tests using the go command because `v444.333.222` is set on makefile.
// This test may fail when running on package tests using the go command because `(test)` is set on makefile.
func TestAddManagedbyLabel(t *testing.T) {
tests := []struct {
kustFile string
Expand Down
58 changes: 37 additions & 21 deletions api/provenance/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,63 @@ package provenance
import (
"fmt"
"runtime"
"runtime/debug"
"strings"
)

// These variables are set at build time using ldflags.
//
//nolint:gochecknoglobals
var (
version = "unknown"
// sha1 from git, output of $(git rev-parse HEAD)
gitCommit = "$Format:%H$"
// During a release, this will be set to the release tag, e.g. "kustomize/v4.5.7"
version = developmentVersion
// build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
buildDate = "1970-01-01T00:00:00Z"
goos = runtime.GOOS
goarch = runtime.GOARCH
buildDate = "unknown"
)

// This default value, (devel), matches
// the value debug.BuildInfo uses for an unset main module version.
const developmentVersion = "(devel)"

// Provenance holds information about the build of an executable.
type Provenance struct {
// Version of the kustomize binary.
Version string `json:"version,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"`
// GitCommit is a git commit
GitCommit string `json:"gitCommit,omitempty"`
GitCommit string `json:"gitCommit,omitempty" yaml:"gitCommit,omitempty"`
// BuildDate is date of the build.
BuildDate string `json:"buildDate,omitempty"`
BuildDate string `json:"buildDate,omitempty" yaml:"buildDate,omitempty"`
// GoOs holds OS name.
GoOs string `json:"goOs,omitempty"`
GoOs string `json:"goOs,omitempty" yaml:"goOs,omitempty"`
// GoArch holds architecture name.
GoArch string `json:"goArch,omitempty"`
GoArch string `json:"goArch,omitempty" yaml:"goArch,omitempty"`
// GoVersion holds Go version.
GoVersion string `json:"goVersion,omitempty" yaml:"goVersion,omitempty"`
}

// GetProvenance returns an instance of Provenance.
func GetProvenance() Provenance {
return Provenance{
version,
gitCommit,
buildDate,
goos,
goarch,
p := Provenance{
BuildDate: buildDate,
Version: version,
GitCommit: "unknown",
GoOs: runtime.GOOS,
GoArch: runtime.GOARCH,
GoVersion: runtime.Version(),
}
info, ok := debug.ReadBuildInfo()
if !ok {
return p
}
}

// Full returns the full provenance stamp.
func (v Provenance) Full() string {
return fmt.Sprintf("%+v", v)
for _, setting := range info.Settings {
// For now, the git commit is the only information of interest.
// We could consider adding other info such as the commit date in the future.
if setting.Key == "vcs.revision" {
p.GitCommit = setting.Value
}
}
return p
}

// Short returns the shortened provenance stamp.
Expand Down
47 changes: 47 additions & 0 deletions api/provenance/provenance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package provenance_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/provenance"
)

const expectedBuildDateFromLdFlag = "2023-01-31T23:38:41Z"
const expectedVersionFromLdFlag = "(test)"

func TestGetProvenance(t *testing.T) {
p := provenance.GetProvenance()
// These are set by ldflags in our Makefile
assert.Equal(t, expectedVersionFromLdFlag, p.Version)
assert.Equal(t, expectedBuildDateFromLdFlag, p.BuildDate)
// This comes from BuildInfo, which is not set during go test: https://github.com/golang/go/issues/33976
assert.Equal(t, "unknown", p.GitCommit)

// These are set properly during go test
assert.NotEmpty(t, p.GoArch)
assert.NotEmpty(t, p.GoOs)
assert.Contains(t, p.GoVersion, "go1.")
}

func TestProvenance_Short(t *testing.T) {
p := provenance.GetProvenance()
// The version not set during go test, so this comes from an ldflag: https://github.com/golang/go/issues/33976
assert.Equal(t, fmt.Sprintf("{%s %s }", expectedVersionFromLdFlag, expectedBuildDateFromLdFlag), p.Short())

p.Version = "kustomize/v4.11.12"
assert.Equal(t, fmt.Sprintf("{kustomize/v4.11.12 %s }", expectedBuildDateFromLdFlag), p.Short())
}

func TestProvenance_Semver(t *testing.T) {
p := provenance.GetProvenance()
// The version not set during go test
assert.Equal(t, "(test)", p.Semver())

p.Version = "kustomize/v4.11.12"
assert.Equal(t, "v4.11.12", p.Semver())
}
1 change: 0 additions & 1 deletion kustomize.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ ADD . /build/
WORKDIR /build/kustomize
RUN CGO_ENABLED=0 GO111MODULE=on go build \
-ldflags="-s -X sigs.k8s.io/kustomize/api/provenance.version=${VERSION} \
-X sigs.k8s.io/kustomize/api/provenance.gitCommit=${COMMIT} \
-X sigs.k8s.io/kustomize/api/provenance.buildDate=${DATE}"

# only copy binary
Expand Down
69 changes: 61 additions & 8 deletions kustomize/commands/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,83 @@
package version

import (
"encoding/json"
"fmt"
"io"
"os"

"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/api/provenance"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

type Options struct {
Short bool
Output string
Writer io.Writer
}

// NewCmdVersion makes a new version command.
func NewCmdVersion(w io.Writer) *cobra.Command {
var short bool

o := NewOptions(w)
versionCmd := cobra.Command{
Use: "version",
Short: "Prints the kustomize version",
Example: `kustomize version`,
Run: func(cmd *cobra.Command, args []string) {
if short {
fmt.Fprintln(w, provenance.GetProvenance().Short())
} else {
fmt.Fprintln(w, provenance.GetProvenance().Full())
RunE: func(cmd *cobra.Command, args []string) error {
if err := o.Validate(args); err != nil {
return err
}
if err := o.Run(); err != nil {
return err
}
return nil
},
}

versionCmd.Flags().BoolVar(&short, "short", false, "short form")
versionCmd.Flags().BoolVar(&o.Short, "short", false, "short form")
_ = versionCmd.Flags().MarkDeprecated("short", "and will be removed in the future.")
versionCmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "One of 'yaml' or 'json'.")
return &versionCmd
}

func NewOptions(w io.Writer) *Options {
if w == nil {
w = io.Writer(os.Stdout)
}
return &Options{Writer: w}
}

func (o *Options) Validate(_ []string) error {
if o.Short {
if o.Output != "" {
return fmt.Errorf("--short and --output are mutually exclusive")
}
}
return nil
}

func (o *Options) Run() error {
switch o.Output {
case "":
if o.Short {
fmt.Fprintln(o.Writer, provenance.GetProvenance().Short())
} else {
fmt.Fprintln(o.Writer, provenance.GetProvenance().Semver())
}
case "yaml":
marshalled, err := yaml.Marshal(provenance.GetProvenance())
if err != nil {
return errors.WrapPrefixf(err, "marshalling provenance to yaml")
}
fmt.Fprintln(o.Writer, string(marshalled))
case "json":
marshalled, err := json.MarshalIndent(provenance.GetProvenance(), "", " ")
if err != nil {
return errors.WrapPrefixf(err, "marshalling provenance to json")
}
fmt.Fprintln(o.Writer, string(marshalled))
}
return nil
}
1 change: 0 additions & 1 deletion releasing/run-goreleaser.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ builds:
ldflags: >
-s
-X sigs.k8s.io/kustomize/api/provenance.version={{.Version}}
-X sigs.k8s.io/kustomize/api/provenance.gitCommit={{.Commit}}
-X sigs.k8s.io/kustomize/api/provenance.buildDate={{.Date}}
goos:
Expand Down

0 comments on commit 95edcc0

Please sign in to comment.