pull/32391/merge
Mukul Negi 3 days ago committed by GitHub
commit 69562c69af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -45,6 +45,9 @@ func testTimestamper() time.Time { return time.Unix(242085845, 0).UTC() }
func init() {
action.Timestamper = testTimestamper
// Timestamps are rendered in local time; pin the local zone to UTC so
// golden-file output does not depend on the machine's timezone.
time.Local = time.UTC
}
func runTestCmd(t *testing.T, tests []cmdTestCase) {

@ -194,7 +194,7 @@ func (r releaseHistory) WriteTable(out io.Writer) error {
tbl := uitable.New()
tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "DESCRIPTION")
for _, item := range r {
tbl.AddRow(item.Revision, item.Updated.Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, item.Description)
tbl.AddRow(item.Revision, item.Updated.Local().Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, item.Description)
}
return output.EncodeTable(out, tbl)
}
@ -218,7 +218,7 @@ func (r releaseHistoryWithRollback) WriteTable(out io.Writer) error {
if item.RollbackRevision > 0 {
rollback = strconv.Itoa(item.RollbackRevision)
}
tbl.AddRow(item.Revision, item.Updated.Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, rollback, item.Description)
tbl.AddRow(item.Revision, item.Updated.Local().Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, rollback, item.Description)
}
return output.EncodeTable(out, tbl)
}

@ -17,8 +17,10 @@ limitations under the License.
package cmd
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"testing"
"time"
@ -30,6 +32,31 @@ import (
release "helm.sh/helm/v4/pkg/release/v1"
)
// Regression test for #31902: table timestamps must be rendered in the
// local timezone (which Go derives from TZ) rather than the zone the
// release happened to be stored with.
func TestHistoryTableUsesLocalTime(t *testing.T) {
originalLocal := time.Local
time.Local = time.FixedZone("UTC+2", 2*60*60)
defer func() { time.Local = originalLocal }()
h := releaseHistory{{
Revision: 1,
Updated: time.Date(2026, 3, 4, 14, 38, 52, 0, time.UTC),
Status: "deployed",
Chart: "foo-0.1.0",
AppVersion: "1.0",
Description: "Install complete",
}}
var buf bytes.Buffer
require.NoError(t, h.WriteTable(&buf))
if !strings.Contains(buf.String(), "Wed Mar 4 16:38:52 2026") {
t.Fatalf("expected timestamp rendered in local zone (UTC+2), got:\n%s", buf.String())
}
}
func TestHistoryCmd(t *testing.T) {
mk := func(name string, vers int, status common.Status) *release.Release {
return release.Mock(&release.MockReleaseOptions{

@ -171,9 +171,9 @@ func newReleaseListWriter(releases []*release.Release, timeFormat string, noHead
t := "-"
if tspb := r.Info.LastDeployed; !tspb.IsZero() {
if timeFormat != "" {
t = tspb.Format(timeFormat)
t = tspb.Local().Format(timeFormat)
} else {
t = tspb.String()
t = tspb.Local().String()
}
}
element.Updated = t

@ -17,6 +17,7 @@ limitations under the License.
package cmd
import (
"strings"
"testing"
"time"
@ -28,6 +29,34 @@ import (
release "helm.sh/helm/v4/pkg/release/v1"
)
// Regression test for #31902: the UPDATED column must be rendered in the
// local timezone (derived from TZ) for both the --time-format path and the
// default String() path.
func TestListWriterUsesLocalTime(t *testing.T) {
originalLocal := time.Local
time.Local = time.FixedZone("UTC+2", 2*60*60)
defer func() { time.Local = originalLocal }()
releases := []*release.Release{{
Name: "tz-release",
Version: 1,
Namespace: "default",
Info: &release.Info{
LastDeployed: time.Date(2026, 3, 4, 14, 38, 52, 0, time.UTC),
Status: common.StatusDeployed,
},
Chart: &chart.Chart{Metadata: &chart.Metadata{Name: "test-chart", Version: "1.0.0", AppVersion: "0.0.1"}},
}}
writer := newReleaseListWriter(releases, "2006-01-02 15:04:05", false, false)
assert.Equal(t, "2026-03-04 16:38:52", writer.releases[0].Updated)
writer = newReleaseListWriter(releases, "", false, false)
if got := writer.releases[0].Updated; !strings.Contains(got, "16:38:52") || !strings.Contains(got, "+0200") {
t.Fatalf("expected default-format timestamp in local zone (UTC+2), got %q", got)
}
}
func TestListCmd(t *testing.T) {
defaultNamespace := "default"

@ -147,7 +147,7 @@ func (s statusPrinter) WriteTable(out io.Writer) error {
rel := s.getV1Release()
_, _ = fmt.Fprintf(out, "NAME: %s\n", rel.Name)
if !rel.Info.LastDeployed.IsZero() {
_, _ = fmt.Fprintf(out, "LAST DEPLOYED: %s\n", rel.Info.LastDeployed.Format(time.ANSIC))
_, _ = fmt.Fprintf(out, "LAST DEPLOYED: %s\n", rel.Info.LastDeployed.Local().Format(time.ANSIC))
}
_, _ = fmt.Fprintf(out, "NAMESPACE: %s\n", coloroutput.ColorizeNamespace(rel.Namespace, s.noColor))
_, _ = fmt.Fprintf(out, "STATUS: %s\n", coloroutput.ColorizeStatus(rel.Info.Status, s.noColor))
@ -197,8 +197,8 @@ func (s statusPrinter) WriteTable(out io.Writer) error {
}
_, _ = fmt.Fprintf(out, "TEST SUITE: %s\n%s\n%s\n%s\n",
h.Name,
"Last Started: "+h.LastRun.StartedAt.Format(time.ANSIC),
"Last Completed: "+h.LastRun.CompletedAt.Format(time.ANSIC),
"Last Started: "+h.LastRun.StartedAt.Local().Format(time.ANSIC),
"Last Completed: "+h.LastRun.CompletedAt.Local().Format(time.ANSIC),
"Phase: "+h.LastRun.Phase,
)
}

@ -17,6 +17,8 @@ limitations under the License.
package cmd
import (
"bytes"
"strings"
"testing"
"time"
@ -25,6 +27,32 @@ import (
release "helm.sh/helm/v4/pkg/release/v1"
)
// Regression test for #31902: status table timestamps must be rendered in
// the local timezone (derived from TZ), not the zone they were stored with.
func TestStatusTableUsesLocalTime(t *testing.T) {
originalLocal := time.Local
time.Local = time.FixedZone("UTC+2", 2*60*60)
defer func() { time.Local = originalLocal }()
rel := &release.Release{
Name: "tz-release",
Namespace: "default",
Info: &release.Info{
LastDeployed: time.Date(2026, 3, 4, 14, 38, 52, 0, time.UTC),
Status: common.StatusDeployed,
},
}
var buf bytes.Buffer
if err := (statusPrinter{release: rel}).WriteTable(&buf); err != nil {
t.Fatal(err)
}
if !strings.Contains(buf.String(), "LAST DEPLOYED: Wed Mar 4 16:38:52 2026") {
t.Fatalf("expected LAST DEPLOYED rendered in local zone (UTC+2), got:\n%s", buf.String())
}
}
func TestStatusCmd(t *testing.T) {
releasesMockWithStatus := func(info *release.Info, hooks ...*release.Hook) []*release.Release {
info.LastDeployed = time.Unix(1452902400, 0).UTC()

Loading…
Cancel
Save