* 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>
Applies various security patches and bug fixes:
https://go.dev/doc/devel/release#go1.25.minor
Also:
* Update CONTRIBUTING to indicate to use -s flag when signing commits
Signed-off-by: eadred <eadred77@googlemail.com>
* feat: Refactor TestRewriteChartDependencies
Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
* fix: keep all chart dependencies key / values
In rewriteChartDependencies we were only parsing name / repository / version,
thus dropping keys like condition / import-values.
This at least fixes the use of condition.
Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
---------
Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
* fix: helmfile fetch fails for kustomization directories
Fixes#2503
When running `helmfile fetch` on a release that points to a local
kustomization directory (without Chart.yaml), the command failed with
"Chart.yaml is missing".
The issue was that the condition `helmfileCommand != "pull"` in
prepareChartForRelease skipped chartification for ALL cases during
fetch, including local kustomization directories that NEED chartify
to convert them to Helm charts.
Solution:
- Added `NeedsChartifyForLocalDir` field to the Chartify struct to
track when chartification is needed because the local directory
is not a Helm chart (no Chart.yaml)
- Modified the condition to skip chartification for "pull" ONLY when
it's not a local directory without Chart.yaml
This preserves the original fix (commit 1f134d93) for remote charts
with transformers while fixing local kustomization directories.
Signed-off-by: yxxhero <aiopsclub@163.com>
* test: add integration test for helmfile fetch with kustomization
Add test case for issue #2503 to verify helmfile fetch works correctly
with local kustomization directories (without Chart.yaml).
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: error on missing secret key when using vals
Add HELMFILE_VALS_FAIL_ON_MISSING_KEY_IN_MAP environment variable
to control whether vals should fail when a referenced key does not
exist in the secret map.
Previously, when a secret reference like ref+vault://path#/nonexistent-key
pointed to a non-existent key, vals would silently return an empty string
without error. This could lead to deployments with missing configuration.
Default behavior remains backward compatible (returns empty string).
Set HELMFILE_VALS_FAIL_ON_MISSING_KEY_IN_MAP=true to enable strict mode.
Fixes#1563
Signed-off-by: yxxhero <aiopsclub@163.com>
* refactor: extract buildValsOptions helper and improve tests
- Extract buildValsOptions() to make vals configuration testable
- Use t.Setenv instead of manual env save/restore in tests
- Test actual vals.Options output including FailOnMissingKeyInMap
Addresses PR review comments on #2496
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: use strconv.ParseBool and make tests hermetic
- Use strconv.ParseBool for FailOnMissingKeyInMap parsing to support
common boolean values like 'TRUE', '1', '0', etc.
- Always set env vars explicitly in tests (even to empty string) to
prevent flaky tests when env vars are set externally
- Add test cases for various boolean formats
Signed-off-by: yxxhero <aiopsclub@163.com>
* docs: add documentation for vals-related environment variables
Add documentation for:
- HELMFILE_AWS_SDK_LOG_LEVEL: configure AWS SDK logging for vals
- HELMFILE_VALS_FAIL_ON_MISSING_KEY_IN_MAP: enable strict mode for secret refs
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: improve error handling and case-insensitive comparison
- buildValsOptions now returns error for invalid boolean values
instead of silently defaulting to false
- Use strings.EqualFold for case-insensitive 'off' comparison
to handle OFF, Off, etc.
- Add test cases for invalid boolean and uppercase OFF
- Update docs to mention case-insensitive and error behavior
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: normalize log level and improve singleton initialization
- Normalize AWS log level 'off' to lowercase for true case-insensitivity
- Replace sync.Once with mutex to allow recovery from config errors
- Update tests to expect normalized 'off' value
- Update docs to clarify when error is raised
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: helmfile list now reflects version from helmfile.lock
The list command now resolves locked dependencies before returning
release information, ensuring the version field reflects the pinned
version from helmfile.lock when present.
Fixes#1953
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address PR review comments
- Remove redundant maps.Copy in list() - labels already merged by GetReleasesWithLabels()
- Fix default lockfile path to use basePath for multi-file mode
- Update test to expect basePath-joined lockfile path
- Add multi-file test for lockfile resolution in helmfile.d directory
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix more test
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix tests
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: propagate errors instead of panic in list()
When skipCharts=false, errors from list() now properly propagate instead
of causing a crash. Uses a closure variable to capture the error and
propagates it after withPreparedCharts completes.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix tests
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix tests
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix tests
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>