cmd/push: align WriteTable format and add output flag test

Address Copilot review feedback:
- WriteTable now uses "Pushed:"/"Digest:" labels consistent with the
  registry client's built-in output (pkg/registry/client.go:746-747),
  so the default --output table experience is familiar to existing users
- Add TestPushOutputFlagCompletion to verify the --output flag is
  properly registered and offers json/yaml/table completions
- Document that Pusher.Push and action.Push.Run signature changes are
  intentional breaking changes in the Helm v4 major release

Signed-off-by: Ilya Kiselev <kis-ilya-a@yandex.ru>
pull/32009/head
Ilya Kiselev 1 month ago
parent be039a06be
commit d3083fce1c

@ -80,7 +80,12 @@ func NewPushWithOpts(opts ...PushOpt) *Push {
return p
}
// Run executes 'helm push' against the given chart archive.
// Run executes 'helm push' against the given chart archive and returns the
// structured push result containing the ref and manifest digest.
//
// Note: the return type changed from (string, error) to (*registry.PushResult, error)
// in Helm v4 as an intentional breaking change, enabling structured access to
// push metadata without text parsing.
func (p *Push) Run(chartRef string, remote string) (*registry.PushResult, error) {
c := uploader.ChartUploader{
Out: io.Discard,

@ -19,7 +19,6 @@ package cmd
import (
"fmt"
"io"
"text/tabwriter"
"github.com/spf13/cobra"
@ -58,14 +57,13 @@ type pushWriter struct {
result pushResult
}
// WriteTable writes a minimal human-readable push result to the provided output.
// The registry client prints progress to stderr; this writes the structured
// result (ref + digest) to the command's stdout stream.
// WriteTable writes the push result in human-readable form, using the same
// "Pushed:"/"Digest:" labels as the registry client's built-in output so that
// the default (--output table) experience is consistent and familiar.
func (w *pushWriter) WriteTable(out io.Writer) error {
tw := tabwriter.NewWriter(out, 0, 0, 2, ' ', 0)
fmt.Fprintf(tw, "REF\t%s\n", w.result.Ref)
fmt.Fprintf(tw, "DIGEST\t%s\n", w.result.Digest)
return tw.Flush()
fmt.Fprintf(out, "Pushed: %s\n", w.result.Ref)
fmt.Fprintf(out, "Digest: %s\n", w.result.Digest)
return nil
}
// WriteJSON writes the push result in JSON format

@ -28,6 +28,20 @@ func TestPushFileCompletion(t *testing.T) {
checkFileCompletion(t, "push package.tgz oci://localhost:5000", false)
}
// TestPushOutputFlagCompletion verifies that the --output flag is registered
// on the push command and that its shell completion offers table/json/yaml.
func TestPushOutputFlagCompletion(t *testing.T) {
_, out, err := executeActionCommandC(storageFixture(), "__complete push --output ''")
if err != nil {
t.Fatal(err)
}
for _, want := range []string{"json", "yaml", "table"} {
if !strings.Contains(out, want) {
t.Errorf("output flag completion missing %q, got: %q", want, out)
}
}
}
func TestPushWriterTable(t *testing.T) {
w := &pushWriter{result: pushResult{
Ref: "oci://example.com/charts/mychart:1.0.0",
@ -38,8 +52,8 @@ func TestPushWriterTable(t *testing.T) {
t.Fatal(err)
}
got := buf.String()
if !strings.Contains(got, "REF") || !strings.Contains(got, "DIGEST") {
t.Errorf("table output missing headers, got: %q", got)
if !strings.Contains(got, "Pushed:") || !strings.Contains(got, "Digest:") {
t.Errorf("table output missing Pushed:/Digest: labels, got: %q", got)
}
if !strings.Contains(got, "oci://example.com/charts/mychart:1.0.0") {
t.Errorf("table output missing Ref value, got: %q", got)

@ -70,8 +70,13 @@ func WithPlainHTTP(plainHTTP bool) Option {
}
// Pusher is an interface to support upload to the specified URL.
//
// Note: the Push method signature was updated in Helm v4 to return
// *registry.PushResult alongside the error, enabling callers to obtain
// structured push metadata (ref, digest) without parsing text output.
// This is an intentional breaking change in the v4 major release.
type Pusher interface {
// Push file content by url string, returning the push result and any error
// Push uploads the chart at chartRef to url and returns the push result.
Push(chartRef, url string, options ...Option) (*registry.PushResult, error)
}

Loading…
Cancel
Save