From 886f1e551d6100a984044c9b097269815cefbb0f Mon Sep 17 00:00:00 2001 From: Nicholas Colbert Date: Fri, 15 Jul 2022 15:44:32 -0700 Subject: [PATCH] add release tag for install and history add release tag for update adding tests added more tests Signed-off-by: Nicholas Colbert --- cmd/helm/history.go | 11 +++- cmd/helm/history_test.go | 59 ++++++++++++++----- cmd/helm/install.go | 1 + cmd/helm/testdata/output/history-limit.txt | 2 +- .../testdata/output/history-release-tag.json | 1 + .../testdata/output/history-release-tag.txt | 5 ++ .../testdata/output/history-release-tag.yaml | 14 +++++ cmd/helm/testdata/output/history.json | 2 +- cmd/helm/testdata/output/history.txt | 2 +- cmd/helm/testdata/output/history.yaml | 2 + cmd/helm/upgrade.go | 2 + pkg/action/install.go | 3 + pkg/action/rollback.go | 1 + pkg/action/upgrade.go | 3 + pkg/release/info.go | 2 + pkg/release/mock.go | 12 ++-- pkg/release/release.go | 5 ++ 17 files changed, 103 insertions(+), 24 deletions(-) create mode 100644 cmd/helm/testdata/output/history-release-tag.json create mode 100644 cmd/helm/testdata/output/history-release-tag.txt create mode 100644 cmd/helm/testdata/output/history-release-tag.yaml diff --git a/cmd/helm/history.go b/cmd/helm/history.go index ee6f391e4..ad1e6769f 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -90,6 +90,7 @@ type releaseInfo struct { Chart string `json:"chart"` AppVersion string `json:"app_version"` Description string `json:"description"` + ReleaseTag string `json:"release_tag"` } type releaseHistory []releaseInfo @@ -104,9 +105,13 @@ func (r releaseHistory) WriteYAML(out io.Writer) error { func (r releaseHistory) WriteTable(out io.Writer) error { tbl := uitable.New() - tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "DESCRIPTION") + tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "DESCRIPTION", "RELEASE TAG") for _, item := range r { - tbl.AddRow(item.Revision, item.Updated.Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, item.Description) + if item.ReleaseTag != "" { + tbl.AddRow(item.Revision, item.Updated.Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, item.Description, item.ReleaseTag) + } else { + tbl.AddRow(item.Revision, item.Updated.Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, item.Description) + } } return output.EncodeTable(out, tbl) } @@ -141,6 +146,7 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) { v := r.Version d := r.Info.Description a := formatAppVersion(r.Chart) + t := r.Info.ReleaseTag rInfo := releaseInfo{ Revision: v, @@ -148,6 +154,7 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) { Chart: c, AppVersion: a, Description: d, + ReleaseTag: t, } if !r.Info.LastDeployed.IsZero() { rInfo.Updated = r.Info.LastDeployed diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index 07f2d85df..fb69ee8a2 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -23,12 +23,17 @@ import ( "helm.sh/helm/v3/pkg/release" ) +const ( + noTag string = "" +) + func TestHistoryCmd(t *testing.T) { - mk := func(name string, vers int, status release.Status) *release.Release { + mk := func(name, releaseTag string, vers int, status release.Status) *release.Release { return release.Mock(&release.MockReleaseOptions{ - Name: name, - Version: vers, - Status: status, + Name: name, + Version: vers, + Status: status, + ReleaseTag: releaseTag, }) } @@ -36,36 +41,62 @@ func TestHistoryCmd(t *testing.T) { name: "get history for release", cmd: "history angry-bird", rels: []*release.Release{ - mk("angry-bird", 4, release.StatusDeployed), - mk("angry-bird", 3, release.StatusSuperseded), - mk("angry-bird", 2, release.StatusSuperseded), - mk("angry-bird", 1, release.StatusSuperseded), + mk("angry-bird", noTag, 4, release.StatusDeployed), + mk("angry-bird", noTag, 3, release.StatusSuperseded), + mk("angry-bird", noTag, 2, release.StatusSuperseded), + mk("angry-bird", noTag, 1, release.StatusSuperseded), }, golden: "output/history.txt", }, { name: "get history with max limit set", cmd: "history angry-bird --max 2", rels: []*release.Release{ - mk("angry-bird", 4, release.StatusDeployed), - mk("angry-bird", 3, release.StatusSuperseded), + mk("angry-bird", noTag, 4, release.StatusDeployed), + mk("angry-bird", noTag, 3, release.StatusSuperseded), }, golden: "output/history-limit.txt", }, { name: "get history with yaml output format", cmd: "history angry-bird --output yaml", rels: []*release.Release{ - mk("angry-bird", 4, release.StatusDeployed), - mk("angry-bird", 3, release.StatusSuperseded), + mk("angry-bird", noTag, 4, release.StatusDeployed), + mk("angry-bird", noTag, 3, release.StatusSuperseded), }, golden: "output/history.yaml", }, { name: "get history with json output format", cmd: "history angry-bird --output json", rels: []*release.Release{ - mk("angry-bird", 4, release.StatusDeployed), - mk("angry-bird", 3, release.StatusSuperseded), + mk("angry-bird", noTag, 4, release.StatusDeployed), + mk("angry-bird", noTag, 3, release.StatusSuperseded), }, golden: "output/history.json", + }, { + name: "get history for release with release tag", + cmd: "history angry-bird", + rels: []*release.Release{ + mk("angry-bird", "tag-4", 4, release.StatusDeployed), + mk("angry-bird", "tag-3", 3, release.StatusSuperseded), + mk("angry-bird", "tag-2", 2, release.StatusSuperseded), + mk("angry-bird", "tag-1", 1, release.StatusSuperseded), + }, + golden: "output/history-release-tag.txt", + }, { + name: "get history with yaml output format", + cmd: "history angry-bird --output yaml", + rels: []*release.Release{ + mk("angry-bird", "tag-4", 4, release.StatusDeployed), + mk("angry-bird", "tag-3", 3, release.StatusSuperseded), + }, + golden: "output/history-release-tag.yaml", + }, { + name: "get history with yaml output format", + cmd: "history angry-bird --output json", + rels: []*release.Release{ + mk("angry-bird", "tag-4", 4, release.StatusDeployed), + mk("angry-bird", "tag-3", 3, release.StatusSuperseded), + }, + golden: "output/history-release-tag.json", }} runTestCmd(t, tests) } diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 0e63ab3a5..a2153f9a2 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -155,6 +155,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used") f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present") f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") + f.StringVar(&client.ReleaseTag, "release-tag", "", "if set, a tag can be added to the name of the release") addValueOptionsFlags(f, valueOpts) addChartPathOptionsFlags(f, &client.ChartPathOptions) diff --git a/cmd/helm/testdata/output/history-limit.txt b/cmd/helm/testdata/output/history-limit.txt index aee0fadb2..db348903f 100644 --- a/cmd/helm/testdata/output/history-limit.txt +++ b/cmd/helm/testdata/output/history-limit.txt @@ -1,3 +1,3 @@ -REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION RELEASE TAG 3 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock 4 Fri Sep 2 22:04:05 1977 deployed foo-0.1.0-beta.1 1.0 Release mock diff --git a/cmd/helm/testdata/output/history-release-tag.json b/cmd/helm/testdata/output/history-release-tag.json new file mode 100644 index 000000000..59f43ee58 --- /dev/null +++ b/cmd/helm/testdata/output/history-release-tag.json @@ -0,0 +1 @@ +[{"revision":3,"updated":"1977-09-02T22:04:05Z","status":"superseded","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock","release_tag":"tag-3"},{"revision":4,"updated":"1977-09-02T22:04:05Z","status":"deployed","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock","release_tag":"tag-4"}] diff --git a/cmd/helm/testdata/output/history-release-tag.txt b/cmd/helm/testdata/output/history-release-tag.txt new file mode 100644 index 000000000..3745113c4 --- /dev/null +++ b/cmd/helm/testdata/output/history-release-tag.txt @@ -0,0 +1,5 @@ +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION RELEASE TAG +1 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock tag-1 +2 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock tag-2 +3 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock tag-3 +4 Fri Sep 2 22:04:05 1977 deployed foo-0.1.0-beta.1 1.0 Release mock tag-4 diff --git a/cmd/helm/testdata/output/history-release-tag.yaml b/cmd/helm/testdata/output/history-release-tag.yaml new file mode 100644 index 000000000..474602ea4 --- /dev/null +++ b/cmd/helm/testdata/output/history-release-tag.yaml @@ -0,0 +1,14 @@ +- app_version: "1.0" + chart: foo-0.1.0-beta.1 + description: Release mock + release_tag: tag-3 + revision: 3 + status: superseded + updated: "1977-09-02T22:04:05Z" +- app_version: "1.0" + chart: foo-0.1.0-beta.1 + description: Release mock + release_tag: tag-4 + revision: 4 + status: deployed + updated: "1977-09-02T22:04:05Z" diff --git a/cmd/helm/testdata/output/history.json b/cmd/helm/testdata/output/history.json index 35311d3ce..0c670906c 100644 --- a/cmd/helm/testdata/output/history.json +++ b/cmd/helm/testdata/output/history.json @@ -1 +1 @@ -[{"revision":3,"updated":"1977-09-02T22:04:05Z","status":"superseded","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"},{"revision":4,"updated":"1977-09-02T22:04:05Z","status":"deployed","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"}] +[{"revision":3,"updated":"1977-09-02T22:04:05Z","status":"superseded","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock","release_tag":""},{"revision":4,"updated":"1977-09-02T22:04:05Z","status":"deployed","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock","release_tag":""}] diff --git a/cmd/helm/testdata/output/history.txt b/cmd/helm/testdata/output/history.txt index 2a5d69c11..5d75b0626 100644 --- a/cmd/helm/testdata/output/history.txt +++ b/cmd/helm/testdata/output/history.txt @@ -1,4 +1,4 @@ -REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION RELEASE TAG 1 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock 2 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock 3 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock diff --git a/cmd/helm/testdata/output/history.yaml b/cmd/helm/testdata/output/history.yaml index b7ae03be7..928dee04b 100644 --- a/cmd/helm/testdata/output/history.yaml +++ b/cmd/helm/testdata/output/history.yaml @@ -1,12 +1,14 @@ - app_version: "1.0" chart: foo-0.1.0-beta.1 description: Release mock + release_tag: "" revision: 3 status: superseded updated: "1977-09-02T22:04:05Z" - app_version: "1.0" chart: foo-0.1.0-beta.1 description: Release mock + release_tag: "" revision: 4 status: deployed updated: "1977-09-02T22:04:05Z" diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index b856073c1..047fcfc01 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -117,6 +117,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { instClient.SubNotes = client.SubNotes instClient.Description = client.Description instClient.DependencyUpdate = client.DependencyUpdate + instClient.ReleaseTag = client.ReleaseTag rel, err := runInstall(args, instClient, valueOpts, out) if err != nil { @@ -230,6 +231,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") f.StringVar(&client.Description, "description", "", "add a custom description") f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart") + f.StringVar(&client.ReleaseTag, "release-tag", "", "if set, a tag can be added to the name of the release") addChartPathOptionsFlags(f, &client.ChartPathOptions) addValueOptionsFlags(f, valueOpts) bindOutputFlag(cmd, &outfmt) diff --git a/pkg/action/install.go b/pkg/action/install.go index cd202ccab..968ce6fa5 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -102,6 +102,8 @@ type Install struct { PostRenderer postrender.PostRenderer // Lock to control raceconditions when the process receives a SIGTERM Lock sync.Mutex + // Used to tag a release // --release-tag + ReleaseTag string } // ChartPathOptions captures common options used for controlling chart paths @@ -405,6 +407,7 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t rel.SetStatus(release.StatusDeployed, "Install complete") } + rel.SetReleaseTag(i.ReleaseTag) // This is a tricky case. The release has been created, but the result // cannot be recorded. The truest thing to tell the user is that the // release was created. However, the user will not be able to do anything diff --git a/pkg/action/rollback.go b/pkg/action/rollback.go index dda8c700b..b410ae4d3 100644 --- a/pkg/action/rollback.go +++ b/pkg/action/rollback.go @@ -131,6 +131,7 @@ func (r *Rollback) prepareRollback(name string) (*release.Release, *release.Rele // Because we lose the reference to previous version elsewhere, we set the // message here, and only override it later if we experience failure. Description: fmt.Sprintf("Rollback to %d", previousVersion), + ReleaseTag: previousRelease.Info.ReleaseTag, }, Version: currentRelease.Version + 1, Manifest: previousRelease.Manifest, diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 690397d4a..150abffb9 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -103,6 +103,8 @@ type Upgrade struct { DependencyUpdate bool // Lock to control raceconditions when the process receives a SIGTERM Lock sync.Mutex + // Used to tag a release // --release-tag + ReleaseTag string } type resultMessage struct { @@ -247,6 +249,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin LastDeployed: Timestamper(), Status: release.StatusPendingUpgrade, Description: "Preparing upgrade", // This should be overwritten later. + ReleaseTag: u.ReleaseTag, // update release tag }, Version: revision, Manifest: manifestDoc.String(), diff --git a/pkg/release/info.go b/pkg/release/info.go index 0cb2bab64..3101a0815 100644 --- a/pkg/release/info.go +++ b/pkg/release/info.go @@ -33,4 +33,6 @@ type Info struct { Status Status `json:"status,omitempty"` // Contains the rendered templates/NOTES.txt if available Notes string `json:"notes,omitempty"` + // ReleaseTag is a optional tag that can be added to the release + ReleaseTag string `json:"release_tag,omitempty"` } diff --git a/pkg/release/mock.go b/pkg/release/mock.go index a28e1dc16..7007beca0 100644 --- a/pkg/release/mock.go +++ b/pkg/release/mock.go @@ -41,11 +41,12 @@ metadata: // MockReleaseOptions allows for user-configurable options on mock release objects. type MockReleaseOptions struct { - Name string - Version int - Chart *chart.Chart - Status Status - Namespace string + Name string + Version int + Chart *chart.Chart + Status Status + Namespace string + ReleaseTag string } // Mock creates a mock release object based on options set by MockReleaseOptions. This function should typically not be used outside of testing. @@ -92,6 +93,7 @@ func Mock(opts *MockReleaseOptions) *Release { Status: scode, Description: "Release mock", Notes: "Some mock release notes!", + ReleaseTag: opts.ReleaseTag, } return &Release{ diff --git a/pkg/release/release.go b/pkg/release/release.go index b90612873..ba764ea2f 100644 --- a/pkg/release/release.go +++ b/pkg/release/release.go @@ -47,3 +47,8 @@ func (r *Release) SetStatus(status Status, msg string) { r.Info.Status = status r.Info.Description = msg } + +// SetReleaseTag is a helper for setting the tag on a release. +func (r *Release) SetReleaseTag(rt string) { + r.Info.ReleaseTag = rt +}