* 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>
This commit makes the apply logic exit early in the event there are no
changes to releases. I believe this effectively reverts helmfile#522.
Updates relevant snapshots
Clarify conditions under which preapply hooks are triggered to include that they will no longer fire if there is a no-op.
Docs as requested by the maintainer from a copilot request made by them.
Fixes: helmfile#679
Signed-off-by: Thomas Arrow <thomas.arrow@wikimedia.de>
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
* feat: add --force-conflicts flag support for Helm 4
Add support for Helm 4's --force-conflicts flag which forces server-side
apply changes against conflicts. This flag is mutually exclusive with
--force/--force-replace and only available in Helm 4.
Fixes#2429
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address review comments on force-conflicts feature
- Fix comment grammar: 'forces' instead of 'force'
- Improve error messages to indicate both sources (releases[] and helmDefaults)
- Add test case for helmDefaults.forceConflicts with Helm 3 (should error)
- Update TestGenerateID expected hashes after adding ForceConflicts field to structs
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
* build(deps): bump Helm from v4.1.1 to v4.1.3
- Update Helm version to v4.1.3 in Dockerfiles (Alpine, Ubuntu, Debian)
- Update Helm version in CI workflow
- Update SHA256 checksums for amd64 and arm64 architectures
- Update go.mod dependency
Signed-off-by: yxxhero <aiopsclub@163.com>
* build(deps): bump Helm from v3.20.0 to v3.20.1
Signed-off-by: yxxhero <aiopsclub@163.com>
* go mod tidy
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>