Skip to content

Instantly share code, notes, and snippets.

@douglascamata
Last active February 5, 2026 13:13
Show Gist options
  • Select an option

  • Save douglascamata/50ebec060cfa2b8474e27bc3723fcc67 to your computer and use it in GitHub Desktop.

Select an option

Save douglascamata/50ebec060cfa2b8474e27bc3723fcc67 to your computer and use it in GitHub Desktop.
Helm dependency alias/name issue to reproduce the issue reported at https://github.com/helm/helm/issues/31791
module helmbug
go 1.24.0
require helm.sh/helm/v4 v4.0.0
require (
dario.cat/mergo v1.0.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cyphar/filepath-securejoin v0.5.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/extism/go-sdk v1.7.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fluxcd/cli-utils v0.36.0-flux.14 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/ianlancetaylor/demangle v0.0.0-20240805132620-81f5be970eca // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rubenv/sql-migrate v1.8.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/cobra v1.10.1 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/net v0.45.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/term v0.36.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/time v0.12.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.34.1 // indirect
k8s.io/apiextensions-apiserver v0.34.1 // indirect
k8s.io/apimachinery v0.34.1 // indirect
k8s.io/apiserver v0.34.1 // indirect
k8s.io/cli-runtime v0.34.1 // indirect
k8s.io/client-go v0.34.1 // indirect
k8s.io/component-base v0.34.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
k8s.io/kubectl v0.34.1 // indirect
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
sigs.k8s.io/controller-runtime v0.22.3 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/kustomize/api v0.20.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
package main
import (
"context"
"fmt"
"log"
"os"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/chart/loader"
"helm.sh/helm/v4/pkg/cli"
"helm.sh/helm/v4/pkg/downloader"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/registry"
)
func runInstall(ctx context.Context, logger *log.Logger, settings *cli.EnvSettings, releaseName string, chartRef string, chartVersion string, releaseValues map[string]interface{}) error {
actionConfig, err := initActionConfig(settings, logger)
if err != nil {
return fmt.Errorf("failed to init action config: %w", err)
}
installClient := action.NewInstall(actionConfig)
installClient.DryRunStrategy = "client"
installClient.ReleaseName = releaseName
installClient.Namespace = settings.Namespace()
installClient.Version = chartVersion
registryClient, err := newRegistryClient(
settings,
installClient.CertFile,
installClient.KeyFile,
installClient.CaFile,
installClient.InsecureSkipTLSverify,
installClient.PlainHTTP)
if err != nil {
return fmt.Errorf("failed to created registry client: %w", err)
}
installClient.SetRegistryClient(registryClient)
chartPath, err := installClient.ChartPathOptions.LocateChart(chartRef, settings)
if err != nil {
return err
}
providers := getter.All(settings)
charter, err := loader.Load(chartPath)
if err != nil {
return err
}
chartAccessor, err := chart.NewDefaultAccessor(charter)
if err != nil {
return fmt.Errorf("error creating chart accessor: %w", err)
}
// Check chart dependencies to make sure all are present in /charts
if chartDependencies := chartAccessor.MetaDependencies(); chartDependencies != nil {
if err := action.CheckDependencies(charter, chartDependencies); err != nil {
err = fmt.Errorf("failed to check chart dependencies: %w", err)
if !installClient.DependencyUpdate {
return err
}
manager := &downloader.Manager{
Out: logger.Writer(),
ChartPath: chartPath,
Keyring: installClient.ChartPathOptions.Keyring,
SkipUpdate: false,
Getters: providers,
RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug,
RegistryClient: installClient.GetRegistryClient(),
}
if err := manager.Update(); err != nil {
return err
}
// Reload the chart with the updated Chart.lock file.
if charter, err = loader.Load(chartPath); err != nil {
return fmt.Errorf("failed to reload chart after repo update: %w", err)
}
}
}
fmt.Println("Chart dependencies before render:")
if err := printDeps(chartAccessor.MetaDependencies()); err != nil {
return fmt.Errorf("failed to print dependencies: %w", err)
}
_, err = installClient.RunWithContext(ctx, charter, releaseValues)
if err != nil {
return fmt.Errorf("failed to run install: %w", err)
}
fmt.Println("Chart dependencies after render:")
if err := printDeps(chartAccessor.MetaDependencies()); err != nil {
return fmt.Errorf("failed to print dependencies: %w", err)
}
return nil
}
func printDeps(deps []chart.Dependency) error {
for _, dep := range deps {
accessor, err := chart.NewDefaultDependencyAccessor(dep)
if err != nil {
return fmt.Errorf("failed to create dependency accessor: %w", err)
}
fmt.Printf("Name: %s, Alias: %s\n", accessor.Name(), accessor.Alias())
}
return nil
}
var helmDriver string = os.Getenv("HELM_DRIVER")
func initActionConfig(settings *cli.EnvSettings, logger *log.Logger) (*action.Configuration, error) {
return initActionConfigList(settings, logger, false)
}
func initActionConfigList(settings *cli.EnvSettings, logger *log.Logger, allNamespaces bool) (*action.Configuration, error) {
actionConfig := new(action.Configuration)
namespace := func() string {
// For list action, you can pass an empty string instead of settings.Namespace() to list
// all namespaces
if allNamespaces {
return ""
}
return settings.Namespace()
}()
if err := actionConfig.Init(
settings.RESTClientGetter(),
namespace,
helmDriver); err != nil {
return nil, err
}
return actionConfig, nil
}
func newRegistryClient(settings *cli.EnvSettings, certFile, keyFile, caFile string, insecureSkipTLSVerify, plainHTTP bool) (*registry.Client, error) {
opts := []registry.ClientOption{
registry.ClientOptDebug(settings.Debug),
registry.ClientOptEnableCache(true),
registry.ClientOptWriter(os.Stderr),
registry.ClientOptCredentialsFile(settings.RegistryConfig),
}
if plainHTTP {
opts = append(opts, registry.ClientOptPlainHTTP())
}
// Create a new registry client
registryClient, err := registry.NewClient(opts...)
if err != nil {
return nil, fmt.Errorf("failed to initialize registry client: %w", err)
}
return registryClient, nil
}
func main() {
settings := cli.New()
settings.SetNamespace("default")
err := runInstall(
context.Background(),
log.New(os.Stdout, "", log.LstdFlags),
settings,
"test",
"https://cgx.jfrog.io/artifactory/coralogix-charts/otel-integration-0.0.271.tgz",
"0.0.271",
map[string]any{
"global": map[string]any{
"clusterName": "test",
"domain": "test.coralogix.com",
},
},
)
if err != nil {
log.Fatalf("failed to run install: %v", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment