mirror of
https://github.com/helmfile/helmfile.git
synced 2026-09-30 14:01:46 +02:00
c6d0310029b22b6b6cf9a1300ef8f548ea245896
893
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c6d0310029 |
fix(state): resolve OCI repo prefix in ad-hoc release dependencies (#2579)
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> |
||
|
|
420cc3ba9c |
fix: add trackFailOnError option to control kubedog exit code (#2576)
* 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> |
||
|
|
902c5ced17 |
feat: add 'create' subcommand to scaffold helmfile deployment projects (#2574)
* 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> |
||
|
|
08a22772f7 |
feat: add --write-output flag to helmfile fetch for air-gapped environments (#2572)
* feat: add --write-output flag to helmfile fetch for air-gapped environments Add --write-output flag to helmfile fetch that outputs a modified helmfile.yaml with chart references updated to point to downloaded local chart paths. Combined with --output-dir, this enables preparing all charts for deployment in air-gapped environments. Usage: helmfile fetch --output-dir ./charts --write-output > helmfile-airgapped.yaml Fixes #2571 Signed-off-by: yxxhero <yxxhero@users.noreply.github.com> Signed-off-by: yxxhero <aiopsclub@163.com> * fix: update fetch-write-output integration test grep to match YAML list item chart field Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d00f71ab-d40d-4220-9b11-97674597685f Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: send status messages to stderr and enforce sequential processing in --write-output mode Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d338e24c-4f6f-4a59-a319-4b975e0efdcb Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: restore SequentialHelmfiles after Fetch and use %s for YAML string formatting Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/cfa9f3f4-c72f-4760-9c51-88bc6f30add2 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * test: add test for SequentialHelmfiles restore after Fetch with --write-output Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/cfa9f3f4-c72f-4760-9c51-88bc6f30add2 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: disable live output on --write-output and fix shell quoting/portability in integration test Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/b0eb0d3d-493b-4d77-b8eb-2a5c0ce70d86 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: use unquoted ${helmfile} variable to allow word splitting for EXTRA_HELMFILE_FLAGS Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d025a111-f7d0-439e-bf14-5508c40d0b51 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: restore helm.EnableLiveOutput after Fetch --write-output via defer Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/ddb8c5fc-ebd1-4f09-9474-5da58938a219 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * test: strengthen enableLiveOutput restore assertion with non-trivial initial value Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d1d0ba9e-5c97-48e1-b761-8bdee391efb2 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * feat: restrict --write-output to a single helmfile state file with clear error Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/f608a0d0-7f52-4e3f-9fac-ab966bd01efb Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * refactor: apply code review suggestions for variable and test naming Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/f608a0d0-7f52-4e3f-9fac-ab966bd01efb Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: replace naked return with explicit return ok, errs to fix nakedret lint error Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/4b060131-a977-44b0-98f7-42bc108ae8e8 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: buffer YAML output and update --write-output flag description Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/50c6ad2e-125c-43c1-b9c3-37fe1686a8eb Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: shorten --write-output flag description, move detail to Long help Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/50c6ad2e-125c-43c1-b9c3-37fe1686a8eb Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> --------- Signed-off-by: yxxhero <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> |
||
|
|
a8e8b67086 |
fix: use --post-renderer-args=VALUE format to prevent Helm flag parsing failure (#2570)
* 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> |
||
|
|
bda57b741f |
build(deps): replace werf/kubedog-for-werf-helm with werf/kubedog (#2568)
* 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> |
||
|
|
dac42105dd |
fix: deduplicate chart dependencies in helmfile.lock (#2567)
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> |
||
|
|
10deabb142 |
Honor skipSchemaValidation during chartification when forceNamespace is set (#2550)
* fix(state): honor skipSchemaValidation in chartify template args Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/a695cbff-c37a-403a-9658-09f4fdaa65d0 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * test(state): harden chartify skip-schema flag detection Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/a695cbff-c37a-403a-9658-09f4fdaa65d0 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix(state): propagate cli skip-schema-validation to chartify Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/70ebf027-0ab5-4bdb-a4b4-5a77c822ee95 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> |
||
|
|
9fa0529304 |
fix: apply post-renderer to output-dir-template output (#2531)
* 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> |
||
|
|
5368ab8d95 |
fix: skip subhelmfiles when selectors conflict with CLI selectors (#2545)
* 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> |
||
|
|
c57134cda7 |
Fix helmfile init failing to update outdated helm plugins with Helm v4 (#2554)
* 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> |
||
|
|
fc31dbfc5e |
fix: eliminate race condition in rewriteChartDependencies (#2541)
* 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> |
||
|
|
7a60255a9b |
enabledns flags available on template command (#2511)
* enabledns flags available on template command Enable dns flag was not available in helmfile template command Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
c584c0e07f |
fix: helmDefaults.postRendererArgs not passed to helm commands (#2510)
* fix: helmDefaults.postRendererArgs not passed to helm commands (#2508)
The commit
|
||
|
|
6faa477290 |
fix: update state values files handling to replace arrays instead of merging (#2537)
* feat: update state values handling to replace arrays instead of merging Signed-off-by: Vojta Polak <vojta.polak@gmail.com> * test: non-shallow copy of OverrideCLISetValues in DeepCopy + test Signed-off-by: Vojta Polak <vojta.polak@gmail.com> * fix: update error message for empty CalleePath in Load function Signed-off-by: Vojta Polak <vojta.polak@gmail.com> --------- Signed-off-by: Vojta Polak <vojta.polak@gmail.com> |
||
|
|
acb7ce36fc |
fix: add mutex lock for concurrent rewriteChartDependencies access (#2509)
* fix: add mutex lock for concurrent rewriteChartDependencies access Prevent race conditions when multiple goroutines concurrently access the same Chart.yaml by introducing a per-chart-path mutex via sync.Map. Signed-off-by: yxxhero <yxxhero@users.noreply.github.com> Signed-off-by: yxxhero <aiopsclub@163.com> * fix: unlock mutex on all error paths and improve race condition test validation Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/135e06b8-99e8-42cb-859d-524b2d2b1907 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: remove duplicate mutex, reuse getNamedRWMutex, restore on write failure, add test barrier Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/f93746bf-82fa-46b1-b8f0-b34bc9aa749c Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: early unlock when unmodified, assert exact restore in race test Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/5981aea4-2799-4560-9272-315d28d4b7d7 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: improve comment wording and strengthen race test start barrier Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/9e4d6f4f-cdc1-4e9e-bdc6-81061ebc1dcc Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> --------- Signed-off-by: yxxhero <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> |
||
|
|
b9378b17f6 |
fix: boolean false overrides dropped in multi-document helmfiles (#2527) (#2532)
* 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> |
||
|
|
fc6cf5d2cc |
Update Go from 1.25.8 to 1.26.2 (#2535)
* Update Go from 1.25.8 to 1.26.2 Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/e2d1bf3c-7879-44ff-956b-2d645281d159 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * Fix CI: upgrade golangci-lint to v2.11.4 for Go 1.26 support Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/ca09eb2b-b0fa-4f27-bee6-fd867b8cec29 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> |
||
|
|
de1c14c3f2 |
chore: rename variables to match in apply and sync (#2521)
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> |
||
|
|
4bdb6f097c |
fix: keep all chart dependencies key / values (#2501)
* 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> |
||
|
|
732e4ad913 |
fix: helmfile fetch fails for kustomization directories (#2504)
* 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
|
||
|
|
c70b20ad7a |
feat: add an arg that passing description to helm upgrade command (#2497)
* feat: add an arg that passing description to `helm upgrade` command fix: github actions Signed-off-by: swimablefish <swimablefish@gmail.com> * fix: lint and test failed Signed-off-by: swimablefish <swimablefish@gmail.com> * feat: encapsulation Signed-off-by: swimablefish <swimablefish@gmail.com> * feat: add version gate Signed-off-by: swimablefish <swimablefish@gmail.com> * feat: rephrase Signed-off-by: swimablefish <swimablefish@gmail.com> --------- Signed-off-by: swimablefish <swimablefish@gmail.com> |
||
|
|
e72315a876 |
build: update helm-diff to v3.15.3 (#2498)
Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
472e8c7a2d |
fix: error on missing secret key when using vals (#2496)
* 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> |
||
|
|
5c67cbcd6a |
fix: pass --timeout flag through to helm for sync and apply (#2495)
* fix: propagate timeout flag Signed-off-by: Hristiyan Ivanov <hristiyan.d.ivanov@gmail.com> * test: add test for propagating timeout flag Signed-off-by: Hristiyan Ivanov <hristiyan.d.ivanov@gmail.com> * feat: add timeout flag to apply command Signed-off-by: Hristiyan Ivanov <hristiyan.d.ivanov@gmail.com> * test: add test for timeout flag for helmfile apply Signed-off-by: Hristiyan Ivanov <hristiyan.d.ivanov@gmail.com> * fix: improve description of timeout flag Signed-off-by: Hristiyan Ivanov <hristiyan.d.ivanov@gmail.com> --------- Signed-off-by: Hristiyan Ivanov <hristiyan.d.ivanov@gmail.com> |
||
|
|
43b426892e |
fix: cleanup hooks not receiving error signal (#2475)
* fix: cleanup hooks not receiving error signal Closes #1041 Signed-off-by: yxxhero <11087727+yxxhero@users.noreply.github.com> Signed-off-by: yxxhero <aiopsclub@163.com> * Add tests for cleanup hooks error propagation 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> * fix tests Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <11087727+yxxhero@users.noreply.github.com> Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
df01afbbeb |
fix: helmfile list now reflects version from helmfile.lock (#2486)
* 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> |
||
|
|
06d0994b84 |
Fix interactive apply asks in no change situation (#945)
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> |
||
|
|
d613c5484c |
feat: add --force-conflicts flag support for Helm 4 (#2480)
* 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> |
||
|
|
607225c34d |
fix: use --force-replace flag for Helm 4 instead of deprecated --force (#2477)
* fix: use --force-replace flag for Helm 4 instead of deprecated --force Helm 4 deprecated the --force flag in favor of --force-replace. This fix detects the Helm version and uses the appropriate flag: - Helm 4: --force-replace - Helm 3: --force Also fixed a nil pointer panic in appendHideNotesFlags when called with nil SyncOpts. Fixes #2476 Signed-off-by: yxxhero <aiopsclub@163.com> * fix(ci): pin semver to v2.12.0 for Go 1.25 compatibility semver@latest requires Go 1.26.1 but the project uses Go 1.25.4. Pinning to v2.12.0 which is compatible with Go 1.25. Signed-off-by: yxxhero <aiopsclub@163.com> * test: add test cases for force flag from defaults with nil release Add test cases to cover the scenario where release.Force is nil and HelmDefaults.Force enables force for both Helm 3 and Helm 4. Signed-off-by: yxxhero <aiopsclub@163.com> * test: add nil ops test and rename misleading test names - Add test case for appendHideNotesFlags with ops=nil to prevent regression - Rename force-from-default-nil-release-* to force-from-default-nil-force-* for clarity (release.Force is nil, not the release itself) Signed-off-by: yxxhero <aiopsclub@163.com> * refactor: add explicit parentheses for force condition Add explicit parentheses around the two disjuncts in the force condition to make the intended grouping unambiguous and easier to read. Signed-off-by: yxxhero <aiopsclub@163.com> * refactor: check ops nil before Helm version in appendHideNotesFlags - Swap the order to check ops == nil first to avoid unnecessary IsVersionAtLeast call - Restore the "see Helm release" comment for consistency with other flag helpers Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
c375b48550 |
fix: nested helmfile values should replace arrays, not merge element-by-element (#2458)
PR #2367 introduced CLIOverrides to give --state-values-set element-by-element array merge semantics. However, nested helmfile values (helmfiles[].values:) were also routed into CLIOverrides, causing their arrays to merge instead of replace. This broke the pre-v1.3.0 behavior where passing an array via helmfiles[].values: would fully replace the child's default array. Add OverrideValuesAreCLI flag to SubhelmfileEnvironmentSpec so the loader can distinguish CLI flags from nested helmfile values. CLI values continue using CLIOverrides (element-by-element merge); nested helmfile values now use Values (Sparse merge strategy → full array replacement). Fixes #2451 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
c6e7249eb9 |
feat: add helm-legacy track mode for Helm v4 compatibility (#2466)
Add support for trackMode: helm-legacy to use Helm v4's --wait=legacy flag, which maintains compatibility with Helm v3's wait behavior during migration. Helm v4 changed the default --wait behavior from polling to a watcher-based approach. This can cause issues with charts that have broken livenessProbe configurations without startupProbe. The --wait=legacy flag preserves the Helm v3 polling behavior for smoother migration. Changes: - Add TrackModeHelmLegacy constant in pkg/kubedog/options.go - Use kubedog.TrackMode constants instead of raw strings in helmx.go - Enhance appendWaitFlags to use --wait=legacy for Helm v4 when trackMode is helm-legacy - Add nil check for logger before logging warning - Add version check with warning when helm-legacy is used with Helm v3 - Update validation in pkg/config to accept helm-legacy track mode - Update command-line flags in cmd/apply.go and cmd/sync.go - Add comprehensive documentation in docs/advanced-features.md - Add thorough test coverage including warning message verification Behavior: - Helm v4 + helm-legacy: Uses --wait=legacy - Helm v3 + helm-legacy: Falls back to --wait with warning - Helm v4 + helm: Uses --wait (watcher mode) - Any + kubedog: Skips --wait flag Fixes #2464 Signed-off-by: yxxhero <aiopsclub@163.com> Co-authored-by: Copilot <copilot@github.com> |
||
|
|
615e8132ee |
fix: pass --kubeconfig to chartify's helm template call (#2449)
When using jsonPatches or kustomize patches with helmfile, chartify runs "helm template" internally to render the chart before applying patches. The lookup() helm function requires cluster access (--dry-run=server). Previously, --kubeconfig was passed to helm diff and helm upgrade commands, but not to chartify's internal helm template call. This caused failures when users specified --kubeconfig flag with a non-default kubeconfig location. This fix ensures --kubeconfig is passed to chartify's TemplateArgs for cluster-requiring commands (sync, apply, diff, etc.), alongside the existing --kube-context and --dry-run=server flags. Fixes #2444 Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
ce09f560d9 | fix: configure kubedog rate limiter to prevent context cancellation (#2446) | ||
|
|
6e21671228 |
feat: kubedog integration with unified resource handling (#2383)
* feat: add kubedog-based resource tracking integration Add kubedog tracking as an alternative to Helm's --wait flag with: - Real-time deployment progress tracking - Container log streaming - Fine-grained resource filtering (trackKinds/skipKinds/trackResources) Features: - New pkg/resource package for unified manifest parsing and filtering - New pkg/kubedog package wrapping kubedog library - CLI flags: --track-mode, --track-timeout, --track-logs - Helmfile YAML support for trackMode, trackTimeout, trackLogs, trackKinds, skipKinds, trackResources - Case-insensitive kind matching for filtering - Multi-context support with proper kubeconfig/kubeContext handling Tracking supports: Deployment, StatefulSet, DaemonSet, Job Resource filtering priority (highest to lowest): 1. trackResources - explicit resource whitelist 2. skipKinds - blacklist specific kinds 3. trackKinds - whitelist specific kinds Integration: - Disable Helm --wait when using kubedog tracking - Track after successful Helm sync/apply - Respect release.Namespace as fallback for resources without namespace - Use getKubeContext() for correct cluster targeting Tests: - Unit tests for resource filtering and kubedog options - Integration test with httpbin chart - E2E snapshot tests for YAML serialization - Documentation in docs/advanced-features.md Signed-off-by: yxxhero <aiopsclub@163.com> * fix: address PR #2383 review comments (round 4) 1. resource/filter.go: Skip empty whitelist entries in matchWhitelist - At least one field (kind/name/namespace) must be specified - Prevents matching all resources with empty TrackResources entries 2. config/apply.go: Add ValidateConfig for track-mode validation - Validate --track-mode must be 'helm' or 'kubedog' - Reject invalid values like --track-mode foo 3. config/sync.go: Add ValidateConfig for track-mode validation - Same validation as apply command - Ensures consistent behavior across commands Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
2be73dd21d |
build: update helm-diff to v3.15.1 (#2442)
Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
b5dc75ad72 |
fix: local chart with external dependencies error when repos configured (#2433)
* fix: local chart with external dependencies error when repos configured When helm repo update was run, the code unconditionally set skipRefresh=true for all builds, causing helm dep build --skip-refresh to fail for local charts with external dependencies not listed in helmfile.yaml. Now only non-local charts (precomputed skipRefresh=true) get --skip-refresh, while local charts preserve their skipRefresh=false to allow refreshing repos for external dependencies. Fixes #2431 Signed-off-by: yxxhero <aiopsclub@163.com> * test: update snapshot tests for local chart refresh behavior Local charts now run helm repo update during helm dep build to support external dependencies not listed in helmfile.yaml (fixes #2431). Signed-off-by: yxxhero <aiopsclub@163.com> * refactor: remove redundant skipRefresh assignment The condition 'if didUpdateRepo && r.skipRefresh { r.skipRefresh = true }' was a no-op since setting true to true has no effect. The precomputed skipRefresh value from prepareChartForRelease is already correct, so we simply preserve it without modification. Signed-off-by: yxxhero <aiopsclub@163.com> * refactor: only call UpdateRepo when at least one build uses --skip-refresh Avoid redundant helm repo update when all builds have skipRefresh=false, as each helm dep build will refresh repos itself in that case. Co-authored-by: Copilot <copilot@github.com> Signed-off-by: yxxhero <aiopsclub@163.com> * test: update release_template_inheritance snapshot for skipRefresh optimization UpdateRepo is now only called when at least one build uses --skip-refresh, so local charts without skipRefresh no longer trigger the global repo update. Signed-off-by: yxxhero <aiopsclub@163.com> * test: add regression test for issue #2431 Add TestIssue2431_LocalChartWithExternalDependency to verify that local charts with external dependencies on repos NOT in helmfile.yaml work correctly. The test ensures: - UpdateRepo is NOT called when all builds have skipRefresh=false - helm dep build does NOT receive --skip-refresh flag Signed-off-by: yxxhero <aiopsclub@163.com> * test: add integration test for issue #2431 Add test case to verify that local charts with repos configured in helmfile.yaml work correctly. The test ensures that helmfile template does not fail with 'no cached repository' or 'no repository definition' errors when: - helmfile.yaml has non-OCI repos configured - Local chart is used (which may have external dependencies not in helmfile.yaml) Signed-off-by: yxxhero <aiopsclub@163.com> * test: update issue #2431 integration test to match issue scenario Add external dependency (karma chart from wiremind repo) to local chart's Chart.yaml, matching the exact scenario described in issue #2431 where: - helmfile.yaml has repos configured (vector) - Local chart depends on a repo NOT in helmfile.yaml (wiremind) Signed-off-by: yxxhero <aiopsclub@163.com> * revert: remove unit tests and restore e2e snapshot outputs Remove pkg/state/run_helm_dep_builds_skip_refresh_test.go and restore chart_need snapshot outputs to original state. The fix is verified by the integration test for issue #2431. Signed-off-by: yxxhero <aiopsclub@163.com> * test: remove snapshot outputs to regenerate them Remove chart_need snapshot outputs so they can be regenerated by tests. Signed-off-by: yxxhero <aiopsclub@163.com> * revert: restore release_template_inheritance snapshot output Signed-off-by: yxxhero <aiopsclub@163.com> * restore: add back unit tests for skipRefresh behavior Signed-off-by: yxxhero <aiopsclub@163.com> * restore: add back chart_need snapshot outputs Signed-off-by: yxxhero <aiopsclub@163.com> * test: update snapshot outputs for skipRefresh optimization - Remove TestIssue2431_LocalChartWithExternalDependency unit test - Update chart_need outputs: local chart runs helm dep build with repo refresh - Update release_template_inheritance: no deps so no repo refresh output Signed-off-by: yxxhero <aiopsclub@163.com> * fix: update test comments and names per review feedback - Update TestRunHelmDepBuilds_MultipleBuilds comment to remove reference to removed didUpdateRepo variable - Rename test case to accurately describe condition being tested (build with skipRefresh=true instead of misleading 'non-local chart') Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> Co-authored-by: Copilot <copilot@github.com> |
||
|
|
3537f5f5c4 |
feat: Add IP Network to supported HCL Functions (#2426)
* Add IP Network to supported HCL Functions This patch adds CIDR functions from the `go-cty-funcs` package to supported HCL functions Signed-off-by: Oleh Neichev <oleg.neichev@gmail.com> * Test HCL CIDR Functions Signed-off-by: Oleh Neichev <oleg.neichev@gmail.com> --------- Signed-off-by: Oleh Neichev <oleg.neichev@gmail.com> |
||
|
|
69bed171ab |
fix: use absolute baseDir in sequential helmfiles for correct values path resolution (#2425)
* fix: use absolute baseDir in sequential helmfiles for correct values path resolution (#2424) PR #2410 introduced a regression where a relative directory was passed as baseDir instead of an absolute one, causing values and secrets file paths to resolve incorrectly when using --sequential-helmfiles with helmfile.d/. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: mirror reporter's bases/templates/inherit setup in issue-2424 integration test Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> --------- Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
2b0086b196 |
fix: only pass --skip-refresh to helm dep build when helm repo update was run (#2419)
When no repositories are defined in helmfile.yaml, local charts with external dependencies need to refresh the repo cache. Previously, we always passed --skip-refresh to helm dep build, which broke this case. Now --skip-refresh is only passed when we actually ran helm repo update, meaning repos are configured AND no skip refresh flags are set. This preserves the precomputed skipRefresh value from prepareChartForRelease which accounts for CLI flags, helmDefaults.skipRefresh, and release.skipRefresh. Fixes #2417 Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
27c78a123e |
fix: skip helm repo update when only OCI repos are configured (#2420)
When using only OCI repositories, helmfile would attempt to run 'helm repo update' which fails with 'no repositories found' error. OCI repositories don't need 'helm repo update' as they use 'helm registry login' instead. This fix adds a HasNonOCIRepositories() helper function and uses it to determine whether to run 'helm repo update'. Fixes #2418 Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
fad470f38a |
feat: allow for HCL values override (#2402)
* feat: allow for HCL values override Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * fix: ensure overriden HCL expression uses range from latest defined block vars Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: implement HCL cty values override tests Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * docs: better describe new behavior Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * fix: add extra parenthesis for better readability Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: implement variable override in decodeGraph() function, AFTER interpolation, providing back access to hv.* and local.* accessors Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: implement better HCL test to override values using local.* and hv.* accessors and pre-processing function calls Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: remove deprecated hclParseError() function (and test) Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: don't let HCL override with null value win Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: proper test condition on HCL map type merge (and tests) Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: more accurate HCL test error statement Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: ensure HCL DAG graph collects dependencies from ALL definitions to ensure proper evaluation order even if only earlier definitions have dependencies Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: verify HCL mixed-types merges are correctly supported Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * docs: improved environment values precedence section with HCL override support Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: HCL test spell-check, linter failure Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: implement HCL override e2e tests Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * fix: correct hcl_loader test error message Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * fix: ensure correct cty type is returned in case of object/map hcl merge Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * fix: ensure hcl locals from a previous definition/file do not leak into this evaluation when merging Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * fix: correct e2e hcl_override test; missing line in output string comparison Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * docs: spell-check on HCL doc Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> * chore: update comment for accuracy in HCL read routine Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> --------- Signed-off-by: Benjamin Zores <benjamin.zores@gmail.com> Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> |
||
|
|
abfe73fa6f |
fix: helmDefaults.skipRefresh ignored in runHelmDepBuilds (#2415)
fix: helmDefaults.skipRefresh ignored in runHelmDepBuilds (#2269) `runHelmDepBuilds()` only checked the CLI flag (`opts.SkipRefresh`) when deciding whether to run `helm repo update` before building dependencies. This meant that setting `helmDefaults.skipRefresh: true` in helmfile.yaml had no effect on the repo update call inside dep builds. Add `!st.HelmDefaults.SkipRefresh` to the guard condition so that `helmDefaults.skipRefresh: true` is respected alongside the CLI flag. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
c63947483c |
fix: eliminate os.Chdir in sequential helmfiles to fix relative path resolution (#2410)
* fix: eliminate os.Chdir in sequential helmfiles to fix relative path resolution The sequential code path used within() → os.Chdir() to change the process-wide working directory when processing helmfile.d files. This broke relative environment variable paths (e.g. KUBECONFIG=kubeconfig.yaml) because they resolved from the wrong directory after chdir. Replace the chdir-based approach with the same baseDir parameter pattern used by the parallel code path, passing explicit directory context through loadDesiredStateFromYamlWithBaseDir() instead of mutating global process state. Closes #2409 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: restore within() for single-file sequential to preserve chart path format The previous approach used baseDir for all sequential processing, which changed chart path format in output (e.g. from "../../../../charts/raw" to "test/integration/charts/raw"). This broke integration tests that compare chart paths in expected output. Now the sequential branch uses two strategies: - Single file: use os.Chdir via within() to preserve backward-compatible relative chart paths in output - Multiple files with --sequential-helmfiles: use baseDir parameter to avoid os.Chdir, fixing relative env var paths like KUBECONFIG (#2409) Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: revert e2e snapshot outputs to match within() behavior The previous commit restored within() for single-file sequential processing, which produces relative chart paths (e.g. ../../charts/raw) and filename-only FilePath. Revert the e2e snapshot expected outputs to match main branch since single-file behavior is now identical. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: restructure integration test for multi-file sequential processing - Point -f at helmfile.d/ directly (not parent dir) so findDesiredStateFiles discovers the yaml files - Add second helmfile to trigger baseDir path (len > 1) - Inline environment config to avoid base file relative path issues - Verify both releases appear in output instead of comparing with parallel (which may differ in ordering) Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: reduce cognitive complexity and improve accuracy of sequential helmfiles Replace inline visitSubHelmfiles closure with calls to the existing processNestedHelmfiles() method, matching the parallel path. This eliminates duplicated nested logic and reduces gocognit complexity below the CI threshold of 110. Also fixes help text and docs to accurately describe that single-file processing still uses within(), and adds kubeContext verification to the integration test. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * test: validate kubeContext resolution in sequential helmfiles integration test Restructure the integration test to replicate the exact user scenario from issue #2409: - Multiple files in helmfile.d/ using bases: with relative paths (../bases/) for environments and defaults - Environment values set kubeContext via .Environment.Values - helmDefaults.kubeContext rendered from gotmpl - Local chart references (../../../../charts/raw) from helmfile.d/ - Run diff against the minikube cluster to exercise kubeContext resolution, which would fail with "context does not exist" if os.Chdir() broke relative path resolution - Also verify template output for both releases and relative values file (values/common.yaml) resolution Fix normalizeChart() in util.go to be idempotent — skip re-prefixing when the chart path already starts with basePath. This prevents double-prefixing of local chart paths (e.g. helmfile.d/test/.../raw) when normalizeChart is called multiple times (once during chart preparation and again during diff/sync). Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> --------- Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
ca8fc293e9 |
fix: helmBinary setting ignored in multi-document YAML files (#2414)
* fix: helmBinary setting ignored in multi-document YAML files The helmBinary setting in helmfile.yaml was being ignored when using multi-document YAML files (files with --- separators). Root Cause: When processing multi-document YAML files, the load() function splits the file into parts and processes each part separately. Each part was calling applyDefaultsAndOverrides() which would set an empty helmBinary to the default 'helm'. When merging parts, the default value from a later part would override the correct value from an earlier part. Fix: - Added a new applyDefaults parameter to ParseAndLoad() to control when defaults are applied - Modified rawLoad() to pass applyDefaults=false when processing individual parts - Added a call to ApplyDefaultsAndOverrides() after all parts are merged to apply defaults once on the final merged state - Exported ApplyDefaultsAndOverrides() method for use by the app package Fixes: #2319 Signed-off-by: yxxhero <aiopsclub@163.com> * fix: update comment per PR review Change 're-apply' to 'apply' since defaults are never applied during part processing (applyDefaults=false is passed), so this is the first and only time defaults are applied to the merged state. Signed-off-by: yxxhero <aiopsclub@163.com> * fix: clarify applyDefaults logic in test LoadFile callbacks Add explicit applyDefaults variable with comment explaining why it equals evaluateBases: base files shouldn't apply defaults, only the main file should after all parts/bases are merged. Signed-off-by: yxxhero <aiopsclub@163.com> * fix: address PR review comments - Remove applyDefaults parameter from rawLoad() since it's always false - Add regression test for multi-document YAML with helmBinary (issue #2319) Signed-off-by: yxxhero <aiopsclub@163.com> * test: add integration test for helmBinary in multi-document YAML Add TestHelmBinaryPreservedInMultiDocumentYAML that exercises the full loadDesiredStateFromYaml path to ensure helmBinary from the first document is preserved when merging multi-document YAML files. This is a regression test at the load() orchestration level for issue #2319. Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
cd918b79d1 |
fix: support XDG-style multiple paths in HELM_PLUGINS (#2412)
* fix: support XDG-style multiple paths in HELM_PLUGINS Use filepath.SplitList to properly handle XDG-style paths with multiple directories (e.g., HELM_PLUGINS=/path/one:/path/two) when looking up plugin versions. Previously, the code only scanned a single directory. Fixes #2411 Signed-off-by: yxxhero <aiopsclub@163.com> * fix: address PR review comments for XDG plugins path support - Track and return first non-IsNotExist error from os.ReadDir - Skip empty path elements from filepath.SplitList - Use os.PathListSeparator for cross-platform test compatibility Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
3dab01c16f |
fix: prevent panic in helmfile init on plugin install errors (#2401)
toCLIError() panics on unhandled error types (e.g. helmexec.ExitError from a failed helm plugin install). On Windows, plugin install hooks often fail due to missing 'sh', causing helmfile init to crash even when the plugin binary was placed correctly. - Add helmexec.ExitError case to toCLIError and replace panic in the default case with a graceful error return - After AddPlugin/UpdatePlugin errors, verify whether the plugin is actually present before failing; log a warning and continue if so Fixes #1983 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
0129681222 |
feat: add helmfile unittest command for helm-unittest integration (#2400)
Adds a new `helmfile unittest` command that integrates the helm-unittest plugin, allowing users to define unit test paths per release and run them via helmfile. Closes #2376 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
503c397810 |
feat: support .Environment.* in --output-dir-template (#2375)
* feat: support .Environment.* in --output-dir-template
This commit adds support for accessing environment values in the --output-dir-template flag.
Previously, users could only access .OutputDir, .State.*, and .Release.* in the template.
Now .Environment.* is also available, allowing users to use environment values in the
output directory path.
Example usage:
helmfile template -e test-1 --output-dir-template='{{ .OutputDir }}/{{ .Environment.cluster.name }}/{{ .Environment.Name }}/{{ .Release.Name }}'
This produces output like: ./gitops/my-test-cluster/test-1/release-name/
Changes:
- Add Environment field to GenerateOutputDir template data
- Add Environment field to generateChartPath template data (now a method on HelmState)
- Update help text for --output-dir-template flag in template and fetch commands
- Add test cases for Environment in template
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address PR review comments for --output-dir-template
- Clarify .Environment.Name, .Environment.KubeContext, .Environment.Values.* in help text
- Update generateChartPath comment to reflect broader usage (fetch, pull, OCI)
- Add tests for GenerateOutputDir with Environment fields
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address additional PR review comments
- Move HelmState setup outside test loop to reduce duplication
- Document Environment field (.Name, .KubeContext, .Values) in template data structs
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
|
||
|
|
58df057dcc |
fix: skip cache refresh for shared cache paths to prevent race conditions (#2396)
* fix: skip cache refresh for shared cache paths to prevent race conditions When multiple helmfile processes run in parallel (e.g., as ArgoCD plugin), they share the same OCI chart cache in ~/.cache/helmfile. One process could delete and re-download (refresh) a cached chart while another process was still using it, causing "path not found" errors. This fix: - Adds isSharedCachePath() helper to detect shared cache paths - Skips chart deletion/refresh for paths in the shared cache directory - Users can force refresh by running `helmfile cache cleanup` first Fixes #2387 Signed-off-by: yxxhero <aiopsclub@163.com> * docs: document OCI chart caching behavior and multi-process safety Add documentation for: - OCI chart cache location and behavior - How to force cache refresh with `helmfile cache cleanup` - Multi-process safety when using shared cache - Cache management commands (info, cleanup) Signed-off-by: yxxhero <aiopsclub@163.com> * fix: address review comments for shared cache handling - Return error instead of chartActionDownload for corrupted shared cache - Change refresh skip log from Debugf to Infof for user visibility - Add t.Helper() to createTestLogger test helper Signed-off-by: yxxhero <aiopsclub@163.com> * fix: handle symlinks and add debug logging in isSharedCachePath - Use filepath.EvalSymlinks to resolve symlinks before path comparison - Add debug logging when filepath.Abs fails - Add test case for symlink to shared cache directory Signed-off-by: yxxhero <aiopsclub@163.com> * fix: address copilot review comments - Include underlying error in corrupted cache error message - Add cleanup for test directories created in shared cache - Clarify --skip-refresh flag documentation Signed-off-by: yxxhero <aiopsclub@163.com> * fix: handle edge case when chartPath equals sharedCacheDir - isSharedCachePath now returns true for exact match with cache dir - Add test case for exact match with shared cache directory Signed-off-by: yxxhero <aiopsclub@163.com> * test: add integration test for acquireChartLock shared cache behavior Add TestAcquireChartLockSharedCacheSkipRefresh to verify that acquireChartLock returns chartActionUseCached instead of chartActionRefresh when the chart exists in the shared cache, even when refresh is requested. This tests the core fix for the race condition issue #2387. Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |