Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Versioning to Improve Output #5000

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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