mirror of https://github.com/helm/helm
feat: honor SOURCE_DATE_EPOCH for chart archives (#32162)
* feat: honor SOURCE_DATE_EPOCH for chart archives Add StampModTimes() on Chart struct to recursively set ModTime on all chart file entries. CLI reads SOURCE_DATE_EPOCH env var and wires through all 5 commands: package, install, upgrade, dep build, dep update. Removes unused v3 duplicate source_date_epoch.go (YAGNI). Inlines env var parsing to CLI layer from chart util. Signed-off-by: Lohit Kolluri <lohitkolluri@gmail.com> * docs: document SOURCE_DATE_EPOCH in environment variables help Add a short entry for $SOURCE_DATE_EPOCH to the env var table shown in 'helm help'. The variable is honored by 'helm package', 'install', 'upgrade', 'dep build', and 'dep update' to produce reproducible chart archives. Full documentation belongs in helm-www. Signed-off-by: Lohit Kolluri <lohitkolluri@gmail.com> * fix: adapt SourceDateEpoch to upstream refactored dep check Upstream/main restructured the dependency error handling in install.go and upgrade.go from a nested-if block (if DependencyUpdate) to an early-return pattern (if !DependencyUpdate). Adapt the feature's Manager construction to match the new code structure. Signed-off-by: Lohit Kolluri <lohitkolluri@gmail.com> --------- Signed-off-by: Lohit Kolluri <lohitkolluri@gmail.com>pull/31756/merge
parent
d0e56d4362
commit
ad93b7df63
@ -0,0 +1,42 @@
|
||||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// sourceDateEpochFromEnv returns SOURCE_DATE_EPOCH when set, or nil when unset.
|
||||
func sourceDateEpochFromEnv() (*time.Time, error) {
|
||||
epochStr, ok := os.LookupEnv("SOURCE_DATE_EPOCH")
|
||||
if !ok || epochStr == "" {
|
||||
return nil, nil
|
||||
}
|
||||
epoch, err := strconv.ParseInt(epochStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid SOURCE_DATE_EPOCH: %w", err)
|
||||
}
|
||||
if epoch < 0 {
|
||||
return nil, errors.New("invalid SOURCE_DATE_EPOCH: must not be negative")
|
||||
}
|
||||
t := time.Unix(epoch, 0).UTC()
|
||||
return &t, nil
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSourceDateEpochFromEnv(t *testing.T) {
|
||||
t.Setenv("SOURCE_DATE_EPOCH", "1609459200")
|
||||
|
||||
got, err := sourceDateEpochFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("sourceDateEpochFromEnv() error: %v", err)
|
||||
}
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil epoch")
|
||||
}
|
||||
want := time.Unix(1609459200, 0).UTC()
|
||||
if !got.Equal(want) {
|
||||
t.Fatalf("expected %v, got %v", want, *got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceDateEpochFromEnvUnset(t *testing.T) {
|
||||
t.Setenv("SOURCE_DATE_EPOCH", "")
|
||||
|
||||
got, err := sourceDateEpochFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("sourceDateEpochFromEnv() error: %v", err)
|
||||
}
|
||||
if got != nil {
|
||||
t.Fatalf("expected nil epoch, got %v", *got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceDateEpochFromEnvInvalid(t *testing.T) {
|
||||
t.Setenv("SOURCE_DATE_EPOCH", "not-a-number")
|
||||
|
||||
if _, err := sourceDateEpochFromEnv(); err == nil {
|
||||
t.Fatal("expected error for invalid SOURCE_DATE_EPOCH")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceDateEpochFromEnvNegative(t *testing.T) {
|
||||
t.Setenv("SOURCE_DATE_EPOCH", "-1")
|
||||
|
||||
if _, err := sourceDateEpochFromEnv(); err == nil {
|
||||
t.Fatal("expected error for negative SOURCE_DATE_EPOCH")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceDateEpochFromEnvZero(t *testing.T) {
|
||||
t.Setenv("SOURCE_DATE_EPOCH", "0")
|
||||
|
||||
got, err := sourceDateEpochFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("sourceDateEpochFromEnv() error: %v", err)
|
||||
}
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil epoch")
|
||||
}
|
||||
want := time.Unix(0, 0).UTC()
|
||||
if !got.Equal(want) {
|
||||
t.Fatalf("expected %v, got %v", want, *got)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue