From 0da1b22bfbe6545be09dc2e3e17fe1241eb58cff Mon Sep 17 00:00:00 2001 From: Niklas Ott Date: Mon, 26 May 2025 10:32:49 +0200 Subject: [PATCH 1/3] feat: expose WithPreparedCharts and SyncRun This exposes the previously internal functions withPreparedCharts and sync to be used by tooling built on top of helmfile Co-authored-by: Raphael Luba Signed-off-by: Niklas Ott --- pkg/app/app.go | 32 ++++++++++++++++---------------- pkg/app/run.go | 8 +++++++- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/pkg/app/app.go b/pkg/app/app.go index a4b40b88..97bb2aaa 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -162,7 +162,7 @@ func (a *App) Diff(c DiffConfigProvider) error { includeCRDs := !c.SkipCRDs() - prepErr := run.withPreparedCharts("diff", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("diff", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -233,7 +233,7 @@ func (a *App) Template(c TemplateConfigProvider) error { // https://github.com/helmfile/helmfile/issues/1749 run.helm.SetExtraArgs() - prepErr := run.withPreparedCharts("template", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("template", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -261,7 +261,7 @@ func (a *App) Template(c TemplateConfigProvider) error { func (a *App) WriteValues(c WriteValuesConfigProvider) error { return a.ForEachState(func(run *Run) (ok bool, errs []error) { - prepErr := run.withPreparedCharts("write-values", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("write-values", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -313,7 +313,7 @@ func (a *App) Lint(c LintConfigProvider) error { var lintErrs []error // `helm lint` on helm v2 and v3 does not support remote charts, that we need to set `forceDownload=true` here - prepErr := run.withPreparedCharts("lint", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("lint", state.ChartPrepareOptions{ ForceDownload: true, SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), @@ -355,7 +355,7 @@ func (a *App) Unittest(c UnittestConfigProvider) error { var unittestErrs []error // helm unittest needs local charts, so force download - prepErr := run.withPreparedCharts("unittest", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("unittest", state.ChartPrepareOptions{ ForceDownload: true, SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), @@ -392,7 +392,7 @@ func (a *App) Unittest(c UnittestConfigProvider) error { func (a *App) Fetch(c FetchConfigProvider) error { return a.ForEachState(func(run *Run) (ok bool, errs []error) { - prepErr := run.withPreparedCharts("pull", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("pull", state.ChartPrepareOptions{ ForceDownload: true, SkipRefresh: c.SkipRefresh(), SkipRepos: c.SkipRefresh() || c.SkipDeps(), @@ -416,7 +416,7 @@ func (a *App) Sync(c SyncConfigProvider) error { return a.ForEachState(func(run *Run) (ok bool, errs []error) { includeCRDs := !c.SkipCRDs() - prepErr := run.withPreparedCharts("sync", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("sync", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -428,7 +428,7 @@ func (a *App) Sync(c SyncConfigProvider) error { Validate: c.Validate(), Concurrency: c.Concurrency(), }, func() []error { - ok, errs = a.sync(run, c) + ok, errs = a.SyncRun(run, c) return errs }) @@ -452,7 +452,7 @@ func (a *App) Apply(c ApplyConfigProvider) error { err := a.ForEachState(func(run *Run) (ok bool, errs []error) { includeCRDs := !c.SkipCRDs() - prepErr := run.withPreparedCharts("apply", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("apply", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -497,7 +497,7 @@ func (a *App) Apply(c ApplyConfigProvider) error { func (a *App) Status(c StatusesConfigProvider) error { return a.ForEachState(func(run *Run) (ok bool, errs []error) { - err := run.withPreparedCharts("status", state.ChartPrepareOptions{ + err := run.WithPreparedCharts("status", state.ChartPrepareOptions{ SkipRepos: true, SkipDeps: true, Concurrency: c.Concurrency(), @@ -517,7 +517,7 @@ func (a *App) Status(c StatusesConfigProvider) error { func (a *App) Destroy(c DestroyConfigProvider) error { return a.ForEachState(func(run *Run) (ok bool, errs []error) { if !c.SkipCharts() { - err := run.withPreparedCharts("destroy", state.ChartPrepareOptions{ + err := run.WithPreparedCharts("destroy", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -546,7 +546,7 @@ func (a *App) Test(c TestConfigProvider) error { "or set helm.sh/hook-delete-policy\n") } - err := run.withPreparedCharts("test", state.ChartPrepareOptions{ + err := run.WithPreparedCharts("test", state.ChartPrepareOptions{ SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), @@ -567,7 +567,7 @@ func (a *App) Test(c TestConfigProvider) error { func (a *App) PrintDAGState(c DAGConfigProvider) error { var err error return a.ForEachState(func(run *Run) (ok bool, errs []error) { - err = run.withPreparedCharts("show-dag", state.ChartPrepareOptions{ + err = run.WithPreparedCharts("show-dag", state.ChartPrepareOptions{ SkipRepos: true, SkipDeps: true, Concurrency: 2, @@ -584,7 +584,7 @@ func (a *App) PrintDAGState(c DAGConfigProvider) error { func (a *App) PrintState(c StateConfigProvider) error { return a.ForEachState(func(run *Run) (_ bool, errs []error) { - err := run.withPreparedCharts("build", state.ChartPrepareOptions{ + err := run.WithPreparedCharts("build", state.ChartPrepareOptions{ SkipRepos: true, SkipDeps: true, Concurrency: 2, @@ -657,7 +657,7 @@ func (a *App) ListReleases(c ListConfigProvider) error { var listErr error if !c.SkipCharts() { - prepErr := run.withPreparedCharts("list", state.ChartPrepareOptions{ + prepErr := run.WithPreparedCharts("list", state.ChartPrepareOptions{ SkipRepos: true, SkipDeps: true, Concurrency: 2, @@ -2095,7 +2095,7 @@ func (a *App) status(r *Run, c StatusesConfigProvider) (bool, []error) { return true, errs } -func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) { +func (a *App) SyncRun(r *Run, c SyncConfigProvider) (bool, []error) { st := r.state helm := r.helm diff --git a/pkg/app/run.go b/pkg/app/run.go index 91e25bb5..88c6bab8 100644 --- a/pkg/app/run.go +++ b/pkg/app/run.go @@ -57,7 +57,7 @@ func (r *Run) prepareChartsIfNeeded(helmfileCommand string, dir string, concurre return releaseToChart, nil } -func (r *Run) withPreparedCharts(helmfileCommand string, opts state.ChartPrepareOptions, f func() []error) error { +func (r *Run) WithPreparedCharts(helmfileCommand string, opts state.ChartPrepareOptions, f func() []error) error { if r.ReleaseToChart != nil { panic("Run.PrepareCharts can be called only once") } @@ -238,3 +238,9 @@ func (r *Run) diff(triggerCleanupEvent bool, detailedExitCode bool, c DiffConfig return &infoMsg, releasesToBeUpdated, releasesToBeDeleted, nil } + +// Hack to get access to helmfile’s API +// -rluba, 2025-05-19 +func (r *Run) GetState() *state.HelmState { + return r.state +} From 187600be488a13175c728955c24cf5ad4dc19a9e Mon Sep 17 00:00:00 2001 From: Niklas Ott Date: Wed, 8 Apr 2026 11:31:00 +0200 Subject: [PATCH 2/3] feat: expose HelmState This adds a function to get the current HelmState Co-authored-by: Raphael Luba Signed-off-by: Niklas Ott --- pkg/app/run.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/app/run.go b/pkg/app/run.go index 88c6bab8..6eb05021 100644 --- a/pkg/app/run.go +++ b/pkg/app/run.go @@ -239,8 +239,6 @@ func (r *Run) diff(triggerCleanupEvent bool, detailedExitCode bool, c DiffConfig return &infoMsg, releasesToBeUpdated, releasesToBeDeleted, nil } -// Hack to get access to helmfile’s API -// -rluba, 2025-05-19 func (r *Run) GetState() *state.HelmState { return r.state } From b46b26860a405e9257689c95c0731cf29956b12b Mon Sep 17 00:00:00 2001 From: Niklas Ott Date: Wed, 8 Apr 2026 11:39:09 +0200 Subject: [PATCH 3/3] feat: expose Helm This adds a function to get the Helm interface to execute helm commands by code Co-authored-by: Raphael Luba Signed-off-by: Niklas Ott --- pkg/app/run.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/app/run.go b/pkg/app/run.go index 6eb05021..0ecbffc6 100644 --- a/pkg/app/run.go +++ b/pkg/app/run.go @@ -242,3 +242,7 @@ func (r *Run) diff(triggerCleanupEvent bool, detailedExitCode bool, c DiffConfig func (r *Run) GetState() *state.HelmState { return r.state } + +func (r *Run) GetHelm() helmexec.Interface { + return r.helm +}