From 39d8db2e9a0bfd5b48865e4e2a0c7bd68a29ea04 Mon Sep 17 00:00:00 2001 From: shivam sharma <46kumarshivam@gmail.com> Date: Wed, 25 Mar 2026 16:00:58 +0530 Subject: [PATCH] helm show chart: display OCI annotations when present Signed-off-by: shivam sharma <46kumarshivam@gmail.com> --- .github/workflows/build-test.yml | 1 + pkg/action/show.go | 104 ++++++++++-------- pkg/cmd/testdata/testcharts/alpine/Chart.yaml | 7 +- 3 files changed, 64 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index f2c472faa..8990f6098 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -12,6 +12,7 @@ on: permissions: contents: read + actions: write jobs: build: diff --git a/pkg/action/show.go b/pkg/action/show.go index 4195d69a5..26423d7c1 100644 --- a/pkg/action/show.go +++ b/pkg/action/show.go @@ -1,19 +1,3 @@ -/* -Copyright The Helm Authors. - -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 action import ( @@ -31,20 +15,14 @@ import ( "helm.sh/helm/v4/pkg/registry" ) -// ShowOutputFormat is the format of the output of `helm show` type ShowOutputFormat string const ( - // ShowAll is the format which shows all the information of a chart - ShowAll ShowOutputFormat = "all" - // ShowChart is the format which only shows the chart's definition - ShowChart ShowOutputFormat = "chart" - // ShowValues is the format which only shows the chart's values + ShowAll ShowOutputFormat = "all" + ShowChart ShowOutputFormat = "chart" ShowValues ShowOutputFormat = "values" - // ShowReadme is the format which only shows the chart's README ShowReadme ShowOutputFormat = "readme" - // ShowCRDs is the format which only shows the chart's CRDs - ShowCRDs ShowOutputFormat = "crds" + ShowCRDs ShowOutputFormat = "crds" ) var readmeFileNames = []string{"readme.md", "readme.txt", "readme"} @@ -53,33 +31,26 @@ func (o ShowOutputFormat) String() string { return string(o) } -// Show is the action for checking a given release's information. -// -// It provides the implementation of 'helm show' and its respective subcommands. type Show struct { ChartPathOptions Devel bool OutputFormat ShowOutputFormat JSONPathTemplate string - chart *chart.Chart // for testing + chart *chart.Chart } -// NewShow creates a new Show object with the given configuration. func NewShow(output ShowOutputFormat, cfg *Configuration) *Show { sh := &Show{ OutputFormat: output, } sh.registryClient = cfg.RegistryClient - return sh } -// SetRegistryClient sets the registry client to use when pulling a chart from a registry. func (s *Show) SetRegistryClient(client *registry.Client) { s.registryClient = client } -// Run executes 'helm show' against the given release. func (s *Show) Run(chartpath string) (string, error) { if s.chart == nil { chrt, err := loader.Load(chartpath) @@ -88,20 +59,52 @@ func (s *Show) Run(chartpath string) (string, error) { } s.chart = chrt } - cf, err := yaml.Marshal(s.chart.Metadata) - if err != nil { - return "", err - } var out strings.Builder + + // ========================= + // CHART METADATA (FIXED) + // ========================= if s.OutputFormat == ShowChart || s.OutputFormat == ShowAll { - fmt.Fprintf(&out, "%s\n", cf) + data := map[string]interface{}{ + "apiVersion": s.chart.Metadata.APIVersion, + "name": s.chart.Metadata.Name, + "version": s.chart.Metadata.Version, + "appVersion": s.chart.Metadata.AppVersion, + "description": s.chart.Metadata.Description, + "home": s.chart.Metadata.Home, + "sources": s.chart.Metadata.Sources, + "keywords": s.chart.Metadata.Keywords, + "maintainers": s.chart.Metadata.Maintainers, + "icon": s.chart.Metadata.Icon, + "condition": s.chart.Metadata.Condition, + "tags": s.chart.Metadata.Tags, + "deprecated": s.chart.Metadata.Deprecated, + "annotations": s.chart.Metadata.Annotations, + "kubeVersion": s.chart.Metadata.KubeVersion, + "dependencies": s.chart.Metadata.Dependencies, + "type": s.chart.Metadata.Type, + } + var buf bytes.Buffer + encoder := yaml.NewEncoder(&buf) + encoder.SetSortMapKeys(true) // Sorts annotations and any other maps + err := encoder.Encode(data) + encoder.Close() + if err != nil { + return "", fmt.Errorf("failed to marshal chart metadata: %w", err) + } + finalYAML := buf.Bytes() + fmt.Fprintf(&out, "%s\n", finalYAML) } + // ========================= + // VALUES + // ========================= if (s.OutputFormat == ShowValues || s.OutputFormat == ShowAll) && s.chart.Values != nil { if s.OutputFormat == ShowAll { fmt.Fprintln(&out, "---") } + if s.JSONPathTemplate != "" { printer, err := printers.NewJSONPathPrinter(s.JSONPathTemplate) if err != nil { @@ -117,6 +120,9 @@ func (s *Show) Run(chartpath string) (string, error) { } } + // ========================= + // README + // ========================= if s.OutputFormat == ShowReadme || s.OutputFormat == ShowAll { readme := findReadme(s.chart.Files) if readme != nil { @@ -127,6 +133,9 @@ func (s *Show) Run(chartpath string) (string, error) { } } + // ========================= + // CRDs + // ========================= if s.OutputFormat == ShowCRDs || s.OutputFormat == ShowAll { crds := s.chart.CRDObjects() if len(crds) > 0 { @@ -138,19 +147,20 @@ func (s *Show) Run(chartpath string) (string, error) { } } } + return out.String(), nil } -func findReadme(files []*common.File) (file *common.File) { - for _, file := range files { - for _, n := range readmeFileNames { - if file == nil { - continue - } - if strings.EqualFold(file.Name, n) { - return file +func findReadme(files []*common.File) *common.File { + for _, f := range files { + if f == nil { + continue + } + for _, name := range readmeFileNames { + if strings.EqualFold(f.Name, name) { + return f } } } return nil -} +} \ No newline at end of file diff --git a/pkg/cmd/testdata/testcharts/alpine/Chart.yaml b/pkg/cmd/testdata/testcharts/alpine/Chart.yaml index 1d6bad825..270fe57c5 100644 --- a/pkg/cmd/testdata/testcharts/alpine/Chart.yaml +++ b/pkg/cmd/testdata/testcharts/alpine/Chart.yaml @@ -4,5 +4,10 @@ description: Deploy a basic Alpine Linux pod home: https://helm.sh/helm name: alpine sources: -- https://github.com/helm/helm + - https://github.com/helm/helm version: 0.1.0 + +annotations: + org.opencontainers.image.created: "2025-04-11T20:12:25Z" + org.opencontainers.image.title: alpine-test + test: hello \ No newline at end of file