Merge branch 'main' into fix-include-needs-transitive-1003

This commit is contained in:
copilot-swe-agent[bot]
2026-03-24 23:15:46 +00:00
33 changed files with 1127 additions and 227 deletions
+16 -4
View File
@@ -140,8 +140,15 @@ func (st *HelmState) mergeLockedDependencies() (*HelmState, error) {
// When basePath is set (e.g. when loaded with baseDir instead of os.Chdir),
// resolve the lock file path relative to basePath so it can be found
// without changing the working directory.
if lockFile != "" && st.basePath != "" && !filepath.IsAbs(lockFile) {
lockFile = filepath.Join(st.basePath, lockFile)
switch {
case lockFile != "":
if st.basePath != "" && !filepath.IsAbs(lockFile) {
lockFile = filepath.Join(st.basePath, lockFile)
}
case st.basePath != "":
// When no custom lockfile is specified, use the default lockfile name
// joined with basePath to ensure it's found when not changing CWD.
lockFile = filepath.Join(st.basePath, filename+".lock")
}
depMan := NewChartDependencyManager(filename, st.logger, lockFile)
@@ -258,8 +265,13 @@ func getUnresolvedDependenciess(st *HelmState) (string, *UnresolvedDependencies)
func updateDependencies(st *HelmState, shell helmexec.DependencyUpdater, unresolved *UnresolvedDependencies, filename, wd string) (*HelmState, error) {
lockFile := st.LockFile
if lockFile != "" && st.basePath != "" && !filepath.IsAbs(lockFile) {
lockFile = filepath.Join(st.basePath, lockFile)
switch {
case lockFile != "":
if st.basePath != "" && !filepath.IsAbs(lockFile) {
lockFile = filepath.Join(st.basePath, lockFile)
}
case st.basePath != "":
lockFile = filepath.Join(st.basePath, filename+".lock")
}
depMan := NewChartDependencyManager(filename, st.logger, lockFile)
+34 -3
View File
@@ -353,7 +353,10 @@ type ReleaseSpec struct {
UnitTests []string `yaml:"unitTests,omitempty"`
// Name is the name of this release
Name string `yaml:"name,omitempty"`
Name string `yaml:"name,omitempty"`
// Description is the description for this release that will be passed to helm upgrade with --description flag
Description string `yaml:"description,omitempty"`
Namespace string `yaml:"namespace,omitempty"`
Labels map[string]string `yaml:"labels,omitempty"`
Values []any `yaml:"values,omitempty"`
@@ -917,6 +920,7 @@ type SyncOpts struct {
TrackMode string
TrackTimeout int
TrackLogs bool
Description string
}
type SyncOpt interface{ Apply(*SyncOpts) }
@@ -3158,8 +3162,8 @@ func (st *HelmState) TriggerGlobalPrepareEvent(helmfileCommand string) (bool, er
return st.triggerGlobalReleaseEvent("prepare", nil, helmfileCommand)
}
func (st *HelmState) TriggerGlobalCleanupEvent(helmfileCommand string) (bool, error) {
return st.triggerGlobalReleaseEvent("cleanup", nil, helmfileCommand)
func (st *HelmState) TriggerGlobalCleanupEvent(helmfileCommand string, evtErr error) (bool, error) {
return st.triggerGlobalReleaseEvent("cleanup", evtErr, helmfileCommand)
}
func (st *HelmState) triggerGlobalReleaseEvent(evt string, evtErr error, helmfileCmd string) (bool, error) {
@@ -3447,6 +3451,28 @@ func (st *HelmState) appendChartDownloadFlags(flags []string, release *ReleaseSp
return flags
}
// appendDescriptionFlags appends the helm command-line flag for release description
// Command line takes precedence over config file
func (st *HelmState) appendDescriptionFlags(flags []string, release *ReleaseSpec, opt *SyncOpts, helm helmexec.Interface) ([]string, error) {
description := release.Description
if opt != nil && opt.Description != "" {
description = opt.Description
}
if description != "" {
if !helm.IsVersionAtLeast("3.3.0") {
// Determine error message based on source
if opt != nil && opt.Description != "" {
return nil, fmt.Errorf("--description flag requires Helm 3.3.0 or greater")
}
return nil, fmt.Errorf("releases[].description requires Helm 3.3.0 or greater")
}
flags = append(flags, "--description", description)
}
return flags, nil
}
func (st *HelmState) needsPlainHttp(release *ReleaseSpec, repo *RepositorySpec) bool {
var repoPlainHttp, relPlainHttp bool
if repo != nil {
@@ -3576,6 +3602,11 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp
flags = st.appendPostRenderFlags(flags, release, postRenderer, helm)
flags, err := st.appendDescriptionFlags(flags, release, opt, helm)
if err != nil {
return nil, nil, err
}
var postRendererArgs []string
if opt != nil {
postRendererArgs = opt.PostRendererArgs
+187 -5
View File
@@ -908,6 +908,188 @@ func TestHelmState_flagsForUpgrade(t *testing.T) {
"--namespace", "test-namespace",
},
},
{
name: "description-from-release",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.10.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
Description: "Release description from config",
},
syncOpts: &SyncOpts{},
want: []string{
"--version", "0.1",
"--description", "Release description from config",
"--namespace", "test-namespace",
},
},
{
name: "description-from-cli",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.10.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
},
syncOpts: &SyncOpts{
Description: "CLI description from --description flag",
},
want: []string{
"--version", "0.1",
"--description", "CLI description from --description flag",
"--namespace", "test-namespace",
},
},
{
name: "description-cli-overrides-release",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.10.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
Description: "Release description from config",
},
syncOpts: &SyncOpts{
Description: "CLI description overrides config",
},
want: []string{
"--version", "0.1",
"--description", "CLI description overrides config",
"--namespace", "test-namespace",
},
},
{
name: "description-empty-string-not-passed",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.10.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
Description: "",
},
syncOpts: &SyncOpts{
Description: "",
},
want: []string{
"--version", "0.1",
"--namespace", "test-namespace",
},
},
{
name: "description-from-config-unsupported-version-3.1.0",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.1.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
Description: "Release description from config",
},
syncOpts: &SyncOpts{},
wantErr: "releases[].description requires Helm 3.3.0 or greater",
},
{
name: "description-from-config-unsupported-version-3.2.4",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.2.4"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
Description: "Release description from config",
},
syncOpts: &SyncOpts{},
wantErr: "releases[].description requires Helm 3.3.0 or greater",
},
{
name: "description-from-cli-unsupported-version",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.2.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
},
syncOpts: &SyncOpts{
Description: "CLI description from --description flag",
},
wantErr: "--description flag requires Helm 3.3.0 or greater",
},
{
name: "description-empty-on-old-version",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.1.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
// No description set
},
syncOpts: &SyncOpts{},
want: []string{
"--version", "0.1",
"--namespace", "test-namespace",
// No --description flag should appear
},
},
{
name: "description-from-config-supported-version-3.3.0",
defaults: HelmSpec{
Verify: false,
CreateNamespace: &disable,
},
version: semver.MustParse("3.3.0"),
release: &ReleaseSpec{
Chart: "test/chart",
Version: "0.1",
Name: "test-charts",
Namespace: "test-namespace",
Description: "Release description from config",
},
syncOpts: &SyncOpts{},
want: []string{
"--version", "0.1",
"--description", "Release description from config",
"--namespace", "test-namespace",
},
},
}
for i := range tests {
tt := tests[i]
@@ -2548,10 +2730,10 @@ generated: 2019-05-16T15:42:45.50486+09:00
}
logger := helmexec.NewLogger(io.Discard, "debug")
basePath := "/src"
basePath := filepath.ToSlash(t.TempDir())
state := &HelmState{
basePath: basePath,
FilePath: "/src/helmfile.yaml",
FilePath: filepath.Join(basePath, "helmfile.yaml"),
ReleaseSetSpec: ReleaseSetSpec{
Releases: []ReleaseSpec{
{
@@ -2584,8 +2766,8 @@ generated: 2019-05-16T15:42:45.50486+09:00
}
fs := testhelper.NewTestFs(map[string]string{
"/example/Chart.yaml": `foo: FOO`,
"/src/example/Chart.yaml": `foo: FOO`,
"/example/Chart.yaml": `foo: FOO`,
filepath.Join(basePath, "example/Chart.yaml"): `foo: FOO`,
})
fs.Cwd = basePath
state = injectFs(state, fs)
@@ -2648,7 +2830,7 @@ func TestHelmState_ResolveDeps_NoLockFile(t *testing.T) {
logger: logger,
fs: &filesystem.FileSystem{
ReadFile: func(f string) ([]byte, error) {
if f != "helmfile.lock" {
if f != filepath.Join("/src", "helmfile.lock") {
return nil, fmt.Errorf("stub: unexpected file: %s", f)
}
return nil, os.ErrNotExist
+6 -6
View File
@@ -38,39 +38,39 @@ func TestGenerateID(t *testing.T) {
run(testcase{
subject: "baseline",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
want: "foo-values-5bc9c89c6b",
want: "foo-values-6ccb848dcd",
})
run(testcase{
subject: "different bytes content",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
data: []byte(`{"k":"v"}`),
want: "foo-values-7bf9c8bcdf",
want: "foo-values-5bcbbc4c85",
})
run(testcase{
subject: "different map content",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
data: map[string]any{"k": "v"},
want: "foo-values-65694d8947",
want: "foo-values-7c6468f955",
})
run(testcase{
subject: "different chart",
release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"},
want: "foo-values-856c5f7dd5",
want: "foo-values-8645f5847f",
})
run(testcase{
subject: "different name",
release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"},
want: "bar-values-fff55fbf5",
want: "bar-values-54bd8c865",
})
run(testcase{
subject: "specific ns",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"},
want: "myns-foo-values-6bfbb74765",
want: "myns-foo-values-b4849b445",
})
for id, n := range ids {