This changes the behaviour of the cleanup event during sync to be
triggered right before the function exits and matches the behaviour of
apply
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
Co-authored-by: Raphael Luba <raphael@leanbyte.com>
This commit deduplicates the preparation logic for sync and apply by
moving it to a common function.
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
Co-authored-by: Raphael Luba <raphael@leanbyte.com>
* 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 <raphael@leanbyte.com>
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
* feat: expose Helm interface and HelmState
This adds a function to get the current HelmState
Co-authored-by: Raphael Luba <raphael@leanbyte.com>
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
* feat: return an error instead of panicking on multiple calls on WithPreparedCharts
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
---------
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
Co-authored-by: Raphael Luba <raphael@leanbyte.com>
* feat(state): add mergeStrategy field to EnvironmentSpec
Introduces a per-environment mergeStrategy with valid values "override"
(default, current behavior) and "fallback". This commit only adds the
field, the constants, and a parse-time validator; the loader still
ignores the value, so behavior is unchanged.
Subsequent commits thread the value through the values loader and
implement the fallback semantics.
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
* refactor(state): thread mergeStrategy through values loader
Adds a mergeStrategy string parameter to LoadEnvironmentValues,
loadValuesEntries, and mapMerge so the value can flow from
EnvironmentSpec down to the merge call site. Behavior is unchanged in
this commit; mapMerge ignores the strategy and the next commit
implements the fallback semantics.
Top-level state.DefaultValues and the --state-values-file/-set loaders
are passed an empty strategy ("") since they have no per-environment
spec to consult and stay on the default override behavior.
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
* feat(state): implement fallback merge strategy
Adds a hand-rolled fallbackDeepMerge that, unlike mergo, preserves
keys present in the destination even when their value is the zero
value (false, 0, "", nil, empty list/map). mapMerge dispatches to it
when mergeStrategy == "fallback"; "override" and the empty default
keep using mergo with WithOverride so existing behaviour is unchanged.
Validation lives at the entry of LoadEnvironmentValues so a single
chokepoint guards the field. Invalid values produce an error naming
both the offending value and the valid options.
Tests cover: first-file-wins precedence, gap filling, deep nested
merge, three-file chains, explicit zero-value preservation (the case
naïve mergo gets wrong), explicit nil preservation, inline map
entries, override regression, default-equals-override equivalence,
and invalid-strategy errors.
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
* feat(state): expose prior-file values in fallback template context
Under mergeStrategy: fallback, .gotmpl values files can now reference
values from earlier files in the same `values:` list via .Values
(e.g. `service.domain: "service.{{ .Values.cluster.domain }}"`).
The accumulated result is layered under env.GetMergedValues so env
defaults, env values, and CLI overrides still win on overlap. Override
mode keeps the historical template context — unchanged — so this is
strictly opt-in via the mergeStrategy field.
Together with the precedence flip from the previous commit, this lets
users replace the brittle two-stage `merged-values.yaml.gotmpl`
workaround with native helmfile syntax.
Tests cover the headline cross-file template reference case and pin
the override-mode contract that prior-file values stay invisible.
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
* docs: document mergeStrategy and fallback semantics
Adds a new section to values-and-merging.md describing the override vs
fallback strategies, the explicit-zero-value preservation guarantee,
and the cross-file template reference behavior. Adds a brief pointer
to environments.md so users land on the new field from the
environment values discussion.
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
* refactor(state): reuse maputil.MergeMaps for fallback merge
Replaces the hand-rolled fallbackDeepMerge with a single call to
maputil.MergeMaps, swapping its arguments so the accumulated dest wins
over the new src file. Same first-file-wins semantic, fewer lines, and
the fallback path now inherits the same slice merge strategies the
rest of helmfile already uses.
The one observable behavior shift is for explicit nil values: under
fallback, nil in an earlier file no longer 'wins' over a non-nil value
in a later file — instead it falls through (matching MergeMaps' rule
that nil from the override side only fills missing keys). This is
internally consistent: nil-overwrites is an mergo.WithOverride quirk
that lives only in the override path. The renamed test
NilFallsThroughToFallback pins the new behavior with a comment
referencing the contrast with override mode (Issue1154).
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
---------
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
When a release `dependencies[].chart` is given as `<repoName>/<chart>`
and the matching `repositories:` entry has `oci: true`, helmfile now
rewrites it to `oci://<repoURL>/<chart>` before passing it to chartify.
Without this, chartify's lookup falls into its `helm repo list` branch,
which never finds OCI repos because helm 3+ does not register OCI
registries as named repos (they live in the `helm registry login`
state instead). The user-visible failure was:
failed reading adhoc dependencies: no helm list entry found for
repository "<name>". please `helm repo add` it!
Explicit `oci://` URLs already worked through chartify's OCI branch;
this change makes the `<repoName>/<chart>` form behave the same way.
Non-OCI repo prefixes, unknown prefixes, single-segment names, and
explicit `oci://` URLs all pass through unchanged. A debug log records
each rewrite at the call site for easier troubleshooting.
Fixes#1756.
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de>
* fix: add trackFailOnError option to control kubedog exit code behavior
When kubedog release tracking fails (e.g. pod ImagePullBackOff), helmfile
exits with code 0 instead of a non-zero exit code. Add a trackFailOnError
configuration option (default: false) that when set to true, propagates
kubedog tracking failures to the exit code.
The option is available as:
- Per-release YAML: trackFailOnError: true
- CLI flag: --track-fail-on-error (sync and apply commands)
Extract trackReleaseIfEnabled helper to consolidate kubedog tracking logic
from two duplicated call sites into a single maintainable method.
Fixes#2507
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: add //go:build ignore to server.go to fix go test CI failure
The test/integration/test-cases/issue-2103/input/server.go is a
package main helper binary used by the issue-2103 integration test.
When go test -coverprofile runs on this package, it fails with
"go: no such tool covdata" in the CI environment.
Adding //go:build ignore excludes the file from go list ./... (and
therefore from PKGS in the Makefile), while still allowing the
integration test to build it explicitly via file path:
go build -o server ./path/to/server.go
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/8a7000af-72b7-48f8-8a82-24813b5df341
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: update TestGenerateID expected hashes after adding TrackFailOnError field
Adding TrackFailOnError *bool to ReleaseSpec changed the spew
serialization of the struct, which changed the FNV-32a hash values
produced by generateValuesID. Update temp_test.go with the new
expected hash strings.
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/caa86cd9-73d1-4894-b745-fd70c0811fd6
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* feat: add 'create' subcommand to scaffold helmfile deployment projects
Add 'helmfile create [NAME]' command that generates a best-practice
helmfile project structure with:
- helmfile.yaml with commented examples (helmDefaults, repositories,
environments, releases)
- environments/default.yaml for environment-specific values
- values/.gitkeep placeholder for release values
Supports --output-dir/-o for custom output path and --force to
overwrite existing files. Validates project name to prevent path
traversal.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: add overwrite protection for all scaffold files and unit tests for create command
- pkg/app/create.go: extract writeFileIfNotExists helper that respects the
--force flag; all three scaffold files (helmfile.yaml,
environments/default.yaml, values/.gitkeep) now refuse to overwrite
without --force
- pkg/config/create.go: ValidateConfig now checks all three scaffold paths
and reports every already-existing file in a single error before
proceeding, instead of only checking helmfile.yaml
- pkg/app/create_test.go: add unit tests covering new directory, current
directory, per-file overwrite rejection without --force, and full
overwrite with --force
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/eb6d9e4b-0f72-4e26-b841-e1e39a2b2e83
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: remove redundant absDir from ValidateConfig error message
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/eb6d9e4b-0f72-4e26-b841-e1e39a2b2e83
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: address create command review feedback
- cmd/create.go: add config.NewCLIConfigImpl() call for consistency with other
subcommands; update --force flag help text to list all overwritten files
- pkg/config/create.go: delegate to c.GlobalImpl.ValidateConfig() at end of
ValidateConfig() for global option validation (--color/--no-color)
- pkg/config/create_test.go: add unit tests for CreateImpl.ValidateConfig()
covering path separator rejection, '..' rejection, existing-file detection
per-file and with --force, and global color conflict delegation
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/6327d657-5888-4b94-85fb-def80c0a193f
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: clarify test helper name and comment in create_test.go
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/6327d657-5888-4b94-85fb-def80c0a193f
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: atomic preflight check in App.Create before any writes
Refactor Create to collect all conflicting scaffold paths up front
before writing anything. When --force is not set and any scaffold file
already exists, the command returns a single error listing all
conflicts without touching the filesystem.
Also removes the now-unnecessary writeFileIfNotExists helper and adds a
test (TestCreate_PreflightAtomicOnLaterConflict) verifying that a
conflict on a later file (e.g. environments/default.yaml) prevents even
the first file (helmfile.yaml) from being created.
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/aae6f2e6-7f9e-42b8-afa3-78edd3215127
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: handle non-IsNotExist Stat errors in preflight check; add whitespace name test; fix gci formatting
- pkg/app/create.go: treat os.Stat errors that are NOT os.IsNotExist as
hard errors in the preflight scan, surfacing permission/IO issues before
any writes happen; remove trailing blank line that caused gci failure
- pkg/config/create.go: same non-IsNotExist error handling in ValidateConfig
- pkg/config/create_test.go: add TestCreateImpl_ValidateConfig_WhitespaceOnlyName
covering the " " (whitespace-only) name rejection branch
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d6574f56-f46d-46f7-99d9-e0b0b897b3b5
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* refactor: eliminate duplicated scaffold existence check; use O_EXCL for TOCTOU protection
- pkg/config/create.go: remove file-existence check from ValidateConfig
(duplicate of App.Create's preflight); ValidateConfig now only validates
the project name and delegates to GlobalImpl.ValidateConfig. Remove unused
os/path/filepath imports.
- pkg/app/create.go: add writeScaffoldFile helper that uses O_CREATE|O_EXCL
when force=false, so a file appearing between the preflight check and the
actual write is caught rather than silently overwritten (TOCTOU protection).
- pkg/config/create_test.go: remove four file-existence tests that tested the
now-deleted ValidateConfig logic; file-conflict coverage remains in
pkg/app/create_test.go. Simplify ValidName and GlobalColorConflict tests.
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/82f82e72-934f-416c-8662-5060e92284fa
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: wrap O_EXCL error with --force hint; add writeScaffoldFile unit tests
- pkg/app/create.go: wrap os.IsExist error from writeScaffoldFile with a
message that names the conflicting file and suggests --force, so the user
gets actionable output even in the TOCTOU case
- pkg/app/create_test.go: add TestWriteScaffoldFile_CreatesNewFile,
TestWriteScaffoldFile_ExistingFileNoForce, and
TestWriteScaffoldFile_ExistingFileWithForce to cover the helper directly
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/82f82e72-934f-416c-8662-5060e92284fa
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: wrap App.Create errors in *app.Error; reject '.' as project name; add '.' name test
- pkg/app/create.go: wrap all App.Create fmt.Errorf returns with appError("", ...)
so toCLIError produces a clean user-friendly message instead of
"unexpected error: *fmt.wrapError: ..."
- pkg/config/create.go: reject "." as a NAME alongside ".." to prevent
accidentally scaffolding into the current directory via a named argument
- pkg/config/create_test.go: add TestCreateImpl_ValidateConfig_NameDot
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/6d64508e-2d66-47e9-a02a-7669a2f481b7
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: drop unused outputDir param from test helper to fix unparam lint error
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/11cd65e9-c5ef-4195-9375-bc929169616b
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: drop unused force param from test helper to fix unparam lint error
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/0e1bdac5-708f-4615-ae6d-e22fc1e921f2
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* fix: use --post-renderer-args=VALUE format to prevent Helm flag parsing failure
When postRendererArgs contains values like short flags (e.g. -v), passing
--post-renderer-args and the value as separate arguments causes Helm to
interpret the value as its own flag. Using the --post-renderer-args=VALUE
format unambiguously binds the value to the flag.
Fixes#2563
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: update hasFlagWithValue doc/errors and add -v short-flag test cases
- Update hasFlagWithValue doc comment to describe both '--flag value' and
'--flag=value' forms
- Update t.Errorf messages in app_test.go to reflect both accepted formats
- Add 'post-renderer-args-short-flag-value' test case (-v) to both
TestHelmState_flagsForUpgrade and TestHelmState_flagsForTemplate to
verify --post-renderer-args=-v emission (core regression from #2563)
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/dd95f046-358b-4867-9069-9432c1b5318e
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Update vals to v0.44.0 to fix YC_TOKEN json-string handling for
Yandex Lockbox secret decryption. Also bumps transitive dependencies
including yandex-cloud/go-genproto (0.69.0 -> 0.75.0) which contains
the actual fix.
Add replace directives to pin k8s.io/{api,apimachinery,client-go} to
v0.35.4 for compatibility with helm and kubedog dependencies that
still require removed k8s.io/api packages (scheduling/v1alpha1,
autoscaling/v2beta2).
Closes#2564
Signed-off-by: yxxhero <aiopsclub@163.com>
* build(deps): replace werf/kubedog-for-werf-helm with werf/kubedog
Replace the fork github.com/werf/kubedog-for-werf-helm with the upstream
github.com/werf/kubedog. The fork was a temporary compatibility shim; the
upstream repository now includes the necessary k8s API fixes.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix(kubedog): initialize InformerFactory to prevent nil pointer panic
The upstream werf/kubedog now requires an InformerFactory for its resource
trackers (deployment, statefulset, daemonset, job, canary), but the
multitrack layer still passes nil. Bypass the broken multitrack feed layer
by creating resource trackers directly with a properly initialized
InformerFactory.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix(lint): correct misspelling of canceled
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
When multiple releases reference the same chart with the same name,
repository, and version, helmfile deps would write duplicate entries
to helmfile.lock. This adds deduplication of resolved dependencies
after sorting and before writing the lock file.
Fixes#2562
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: apply post-renderer to output-dir-template output
When --output-dir and --post-renderer are both passed to helm template,
Helm writes pre-post-renderer content to files and sends post-renderer
output to stdout. This workaround strips --output-dir from helm flags,
captures the post-renderer-processed stdout, and writes it to the output
directory.
Fixes#2515
Signed-off-by: yxxhero <aiopsclub@163.com>
* test: add integration test for issue-2515 (post-renderer with output-dir-template)
Verifies that --post-renderer output is written to files when
--output-dir-template is set, instead of pre-renderer content.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address review comments - correct HasPrefix args, fix output dir structure, fix test mock init
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/33d92423-fc47-4080-8307-5af9b16dd9c6
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: wrap file operation errors with context in post-renderer workaround
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/33d92423-fc47-4080-8307-5af9b16dd9c6
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: correct chart path and use absolute case dir path in integration test
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/43b7a794-1e7b-4577-8829-deb544a1a105
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: restrict --output-dir + --post-renderer workaround to Helm 3 only
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/229b14e2-b1ad-4f19-bd00-b8f7821383cd
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: clean up stale templates dir on re-runs in Helm 3 post-renderer workaround
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/f6c66284-8eca-4db3-8711-c9b6d3a9c179
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: detect --post-renderer=<path> form and use targeted file cleanup
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/8c9e4af4-84ae-4cbd-bc0a-8fcd9adddaed
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* feat: add Helm 4 post-renderer plugin and enable Helm 4 issue-2515 integration test
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/3da2949c-a9d6-4e16-9b4a-a7e241080089
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: search recursively for YAML files in Helm 4 output-dir integration test
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/c5d33143-f611-40db-b73a-e5189d944ffd
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: limit find depth and truncate log in Helm 4 integration test fallback message
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/c5d33143-f611-40db-b73a-e5189d944ffd
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* fix: skip subhelmfiles when selectors conflict with CLI selectors (#2544)
When CLI selectors are provided (e.g. -l name=b), subhelmfiles whose
explicit selectors are provably incompatible are now skipped entirely,
avoiding unnecessary YAML loading and template rendering.
Two selector sets are incompatible when every pair has a positive label
conflict: same key with different values (e.g. name=b vs name=a).
Negative labels are not compared.
Fixes#2544
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address PR review comments - use CLI selectors, fix doc comment, add malformed selector test
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/1f1c33ce-e50d-4781-85b8-d606b5d4ca54
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: add debug logging, unit tests, docs, and fix integration test for subhelmfile selector skip
- Add debug log when skipping subhelmfile due to selector conflict
- Add TestSubhelmfileSelectorsConflict with 11 cases for direct unit coverage
- Document the selector-based subhelmfile skip optimization in docs/index.md
- Fix integration test: use 'app' label key instead of reserved 'name' key
(GetReleasesWithLabels overwrites labels["name"] with the release name)
Signed-off-by: yxxhero <aiopsclub@163.com>
* refactor: avoid map allocation in positiveLabelsCompatibleWith
Compare positive label slices directly instead of allocating a map per
comparison, as label counts are typically small (1-3 entries).
Addresses Copilot review comment on PR #2545.
Signed-off-by: yxxhero <aiopsclub@163.com>
* docs: clarify subhelmfile selector docs per Copilot review feedback
Reword the first two bullets to avoid the contradiction between
'CLI selectors are ignored' and the new skip optimization.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address Copilot review comments round 3
- Log parse errors from SelectorsAreCompatible at debug level instead of
silently discarding them
- Hoist regex compilation to package-level vars in ParseLabels to avoid
repeated compilation per selector
- Replace EXIT traps with explicit cleanup calls in integration test to
avoid interfering with the parent runner's trap
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* Initial plan
* Fix helmfile init not updating outdated helm plugins with Helm v4
- UpdatePlugin now handles secrets plugin with Helm 4 by using the split
plugin architecture (uninstall old + install via installHelmSecretsV4)
- UpdatePlugin falls back to uninstall + reinstall when helm plugin update
fails (e.g., with Helm 4 or tarball-installed plugins)
- Fix string-based semver comparison for helm-secrets version check in
both AddPlugin and UpdatePlugin using proper semver comparison
- Add helmSecretsRequiresSplitInstall helper for reuse and correctness
- Add tests for update failure fallback scenarios
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/533f1b1c-dda6-4934-af27-051e4eaa9927
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* Address reviewer feedback: preserve update error context and add version assertions in tests
- exec.go: include original update error in fallback log message; wrap both
errors (update + reinstall) when reinstall also fails so callers get full context
- init_test.go: add semver import and GetPluginVersion assertions after
CheckHelmPlugins to verify plugins are at required versions on disk
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/c784db7d-7d4c-40a0-97f0-a31eb8901cd6
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* Address second round of reviewer feedback
- exec.go: rename UpdatePlugin parameter path→repo for clarity
- exec.go: fix uninstallPlugin to only emit INFO log when err == nil
- exec_test.go: add Test_helmSecretsRequiresSplitInstall table-driven tests
covering v4.6.9, v4.7.0, v4.8.0, v4.10.0, pre-release, invalid and empty
- exec_test.go: add Test_UpdatePlugin_Helm4SecretsUsesUninstallReinstall
verifying that Helm 4 + secrets uses uninstall+reinstall (not plugin update)
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/cbd3f8c9-ec7d-4500-b168-cb1c2f7c87bc
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* Add len(args) >= 3 guards in test mock for plugin update/uninstall cases
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/ea0f5afc-d52d-473b-b759-853a8f841a26
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* Return early with combined error when uninstall fails in UpdatePlugin fallback
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/bb9a675c-309d-4b06-83d4-a6fe078dce64
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: eliminate race condition in rewriteChartDependencies by copying chart before modifying
Instead of modifying the original Chart.yaml in-place (which causes race
conditions when multiple releases reference the same local chart), copy the
chart to a temporary directory and rewrite the copy's dependencies. This
eliminates the need for per-chart mutex locks and prevents file corruption
when concurrent goroutines process releases sharing the same local chart.
Fixes#2502
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address PR review comments for rewriteChartDependencies
- Handle non-NotExist errors from st.fs.Stat to surface permission/IO failures
- Reword function doc to clarify temp copy is conditional on rewrite being needed
- Assert rewrittenPath vs tempDir based on expectModified in test table
Signed-off-by: yxxhero <aiopsclub@163.com>
* test: add integration test for issue #2502 race condition with shared local chart
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: separate environments and releases with --- in helmfile.yaml
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: correct file:// path and remove --skip-deps for dependency build
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: correct file:// dependency path (5 levels up to test/integration/)
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: remove output validation from race condition test
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: assert WriteFile/MkdirTemp/RemoveAll/CopyDir in DefaultFileSystem test
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: add strategicMergePatches to trigger chartify in race condition test
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: scope test values under raw subchart and align ConfigMap name with strategic merge patches
The race condition test values.yaml had templates at the top level instead
of scoped under the raw subchart key, causing helm template to produce no
output and chartify's ReplaceWithRendered to fail with an empty
helmx.1.rendered directory. Also align the ConfigMap name to match the
strategicMergePatches target.
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
* enabledns flags available on template command
Enable dns flag was not available in helmfile template command
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: helmDefaults.postRendererArgs not passed to helm commands (#2508)
The commit b5eb8793 (#1839) added template support for postRendererArgs
by copying HelmDefaults.PostRendererArgs to each release and then
niling out HelmDefaults.PostRendererArgs. However, the nil-out
prevented the fallback in appendPostRenderArgsFlags from ever being
reached, causing helmDefaults.postRendererArgs to be silently ignored
when no release-level postRendererArgs was set.
Remove the nil-out line so that HelmDefaults.PostRendererArgs remains
available as a fallback while still supporting template expressions
via the copy-to-release mechanism.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: use helm4-compatible postRenderer value in app tests
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/17a1a3c2-e104-49c5-a607-1e81a7b9de06
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: remove postRendererArgs copy loop so CLI flags can override helmDefaults
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/c85f0436-2346-402e-8ad6-e08a4fff7413
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* test: add missing CLI>helmDefault and release>CLI postRendererArgs priority tests
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/37cf3613-a4e1-4eac-b6bc-002761256d31
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* fix: clarify comment wording in app_test.go
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/37cf3613-a4e1-4eac-b6bc-002761256d31
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* refactor: extract newPostRendererTestApp and hasFlagWithValue helpers in app_test.go
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/faf50bca-33b2-4eb4-8ef1-49f470dfa5b7
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* fix: environment values pollution causing boolean false overrides to be dropped (#2527)
PR #2367 introduced envCopy.Values = values in NewEnvironmentTemplateData,
where values = GetMergedValues() = Defaults + Values + CLIOverrides. This
caused .Environment.Values to include Defaults, so when multi-part helmfiles
re-assigned environment values via {{ toYaml .Environment.Values }}, Defaults
values (e.g. helmDefaults.atomic: true) were written into the environment
Values field. Later, GetMergedValues() applied Values over Defaults, causing
the stale atomic: true to win over the correct atomic: false override.
Fix: set .Environment.Values to Values + CLIOverrides only (excluding Defaults),
so re-assignment patterns don't pollute the Values layer with Defaults.
Signed-off-by: yxx <yxx@users.noreply.github.com>
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: rename test to correctly reflect Values override Defaults precedence
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/1b251877-7050-404b-8cc7-abd6aa3ec36b
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* test: flip regression test fixture to exercise false override (issue #2527)
Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/c428fd46-b698-4e88-bff2-4c9ac72d2deb
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
---------
Signed-off-by: yxx <yxx@users.noreply.github.com>
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit only renames some variables to match other places in the
code, so the variable names are less confusing, it does not add or
change any functionality
Signed-off-by: Niklas Ott <niklas.ott@unwired.at>
Co-authored-by: Raphael Luba <raphael@leanbyte.com>