mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-02 20:01:33 +02:00
88be4012b1f7c2a809dcf6e1bf8317174029751f
207
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
34ead21107 |
feat: allow helmfile to continue on failed releases (#2616)
* feat: allow helmfile to continue on failed releases Co-authored-by: Peter Honeder <peter.honeder@unwired.at> Signed-off-by: Niklas Ott <niklas.ott@unwired.at> * fix: skip failed-prep releases, complete flag wiring, add tests and docs (#64) Review follow-ups for --allow-failed-releases (#2616): - Track per-release chart preparation failures in PrepareCharts (returned as a map keyed by release) and remove those releases from the state in Run.WithPreparedCharts when --allow-failed-releases is set, so a failed release is never executed against its original, un-prepared chart reference (which could either fail again with a duplicate error or, for charts requiring chartify, bypass patches/dependency modifications and produce an unintended result). All failures are still reported at the end via the aggregated MultiError. - Complete the release identity on error results from prepareChartForRelease so failures are attributed to the correct release. - With --allow-failed-releases, continue building dependencies of the remaining charts when 'helm dep build' fails for one release, and skip the affected releases during execution. - Wire --allow-failed-releases into 'helmfile unittest' and 'helmfile status'; remove the dead flag wiring for write-values and list (both never prepare charts, see commandsSkipChartPrep). - Simplify control flow (guard clauses, errors.As, drop dead code and redundant else branches). - Add end-to-end coverage in pkg/app/issue_2616_test.go and extend the state-level tests; document the flag in docs/cli.md and CHANGELOG.md. Signed-off-by: yxxhero <11087727+yxxhero@users.noreply.github.com> --------- Signed-off-by: Niklas Ott <niklas.ott@unwired.at> Signed-off-by: yxxhero <11087727+yxxhero@users.noreply.github.com> Co-authored-by: Peter Honeder <peter.honeder@unwired.at> Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> |
||
|
|
7cf4ff9a25 |
feat: add --skip-diff-validation-on-install CLI flag (#2728)
Signed-off-by: Richter <h.richter@sap.com> |
||
|
|
e3f757d5ed |
feat: add --template-args flag to template/apply/sync for helm lookup() support (#2666)
* feat: add --template-args to enable helm lookup() during template/apply/sync (#1833) Add a --template-args flag to the template, apply, and sync subcommands so extra args (most notably --dry-run=server) can be passed to the helm template invocation, enabling Helm's lookup() function to resolve live cluster values. - template: --template-args reaches both chartify's pre-render helm template and the final helm template output (flagsForTemplate). - apply/sync: --template-args reaches chartify's pre-render helm template. apply/sync already inject --dry-run=server automatically for cluster operations; the flag is an explicit opt-in for the template subcommand or for passing additional flags. - When --dry-run is present in template args, kube-context/kubeconfig are also injected into chartify so lookup() can actually reach the cluster. - Resolves the long-stale PR #1833 rebased onto current main, which already contains the cluster-connectivity infrastructure (issues #2271, #2309, #2355, #2444). - Includes integration test (lookup.sh) covering both chartify and non-chartify scenarios. Signed-off-by: yxxhero <aiopsclub@163.com> * test: make lookup template nil-safe to fix integration CI The lookup() function returns an empty map when the chart is rendered without a cluster connection (notably the helm-diff phase of `helmfile apply`). The original fixture chained `index` over the lookup result, panicking with "index of untyped nil" during apply's diff rendering. Guard every index with `default dict` so the template falls back to "overwritten" when lookup is empty, while still resolving to the live value ("init") when cluster access is available (--dry-run=server via --template-args, or a real helm upgrade). Signed-off-by: yxxhero <aiopsclub@163.com> * feat: enable lookup() during apply/diff via --template-args in helm-diff Thread --template-args into the helm-diff rendering path so that `helmfile apply`/`diff --template-args="--dry-run=server"` resolves Helm's lookup() function during the diff phase too. helm-diff supports `--dry-run=server`, which explicitly "enables the cluster access ... and the lookup template function". Previously --template-args only reached chartify's pre-render (which is a no-op for plain charts due to chartify's early-return when there is no forceNamespace/patches/injections) and the final `helm template` of the `template` subcommand. As a result `helmfile apply` on a lookup chart rendered client-side during the diff phase. Changes: - pkg/state: add TemplateArgs to DiffOpts; append it in appendExtraDiffFlags (reaches every helm-diff invocation: apply, standalone diff, interactive sync), mirroring the existing flagsForTemplate handling. - pkg/config + cmd: add --template-args to the diff/doctor commands and to DiffConfigProvider, so lookup works for `helmfile diff` as well. - pkg/app: populate DiffOpts.TemplateArgs from apply/diff/sync-interactive. - docs/cli.md: correct the previous overpromising wording and document diff support plus the nil-safe lookup guidance. - tests: unit-test the TemplateArgs handling in appendExtraDiffFlags and flagsForTemplate; integration lookup.sh now exercises apply with --template-args="--dry-run=server". Signed-off-by: yxxhero <aiopsclub@163.com> * refactor: de-duplicate chartify template-args logic, add helmDefaults.templateArgs Address review feedback on #2666: 1. Eliminate stale duplicated test helpers (issue_2444_test.go, issue_2355_test.go). Both files intentionally copied the processChartification flag-building logic with explicit SYNC WARNING comments, then drifted out of sync when #2666 refactored the production code (needsKubeConnection gate, user-args merge). Extract the real logic into pure, unit-tested helpers (buildChartifyTemplateArgs, commandRequiresCluster) and delete the copies. 2. Add unit coverage for the new chartify merge path: template + --template-args=--dry-run=server now triggers kubeconfig/kube-context injection (TestTemplateArgsDryRunTriggersKubeInjection, TestTemplateArgsMergedBeforeInjection) — previously only covered by the cluster-dependent integration test. 3. Add a negative integration case (lookup.sh assert_template_fallback) verifying lookup() falls back to the default value WITHOUT --template-args, guarding against a regression that silently always connects to the cluster. 4. Add helmDefaults.templateArgs for parity with diffArgs/syncArgs, so users can enable lookup() support permanently instead of passing the flag on every invocation. CLI --template-args overrides (does not merge with) the default. Resolved via effectiveTemplateArgs, wired into the chartify, flagsForTemplate, and appendExtraDiffFlags paths. 5. Minor: capitalize --template-args help text to match surrounding flags; document helmDefaults.templateArgs precedence in docs/cli.md. Signed-off-by: yxxhero <aiopsclub@163.com> * test: cover helmDefaults->chartify composition; fix helm helm-diff typo Address remaining review nits on #2666: - Add TestHelmDefaultsTemplateArgsReachesChartify, a belt-and-suspenders test for the processChartification composition (effectiveTemplateArgs -> buildChartifyTemplateArgs), closing the last unit-level coverage gap for helmDefaults.templateArgs reaching the chartify path. - Fix pre-existing typo in cmd/bind_diff_flags.go: 'pass args to helm helm-diff' -> 'Pass args to helm-diff' (doubled 'helm', lowercase). Signed-off-by: yxxhero <aiopsclub@163.com> * fix: correct 'helm helm-diff' typo in apply --diff-args help text Sibling of the bind_diff_flags.go fix; the same doubled-'helm' typo and lowercase help existed in cmd/apply.go's --diff-args registration, leaving the apply and diff/doctor help strings inconsistent. Signed-off-by: yxxhero <aiopsclub@163.com> * docs: add helmDefaults.templateArgs to configuration reference The complete helmfile.yaml schema in docs/configuration.md documents diffArgs and syncArgs under helmDefaults but was missing the new templateArgs field added in #2666. Add it beside syncArgs for discoverability, noting the --template-args CLI override. Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
9d3a9ad6c7 |
feat: parallel kubedog tracking with progress printer and safety valves (#2654)
* feat: parallel kubedog tracking with progress printer and safety valves Rework kubedog integration so resource tracking runs in parallel with helm upgrade/install, giving live progress output and recovering from known helm/kubedog wedge conditions. Core: - kubedogTrackingHandle runs tracking in a background goroutine alongside the helm subprocess (startBackgroundKubedogTracking); helm output is buffered and replayed as a single block so it no longer interleaves with progress ticks. - Capture UID+generation baselines before handing off to helm so each tracker waits until the resource actually changes (freshness gate). Progress printer (pkg/kubedog/printer.go): - Styled, auto-sized progress table with a heartbeat flusher, child (pod) status roll-up, pre-ready pod-phase handling, multi-namespace support, and optional color. PreviewBreakdown summarizes kept/filtered resources. Safety valves (verify cluster state via the live API): - Tracker-race valve (always on): when helm succeeds but a dyntracker goroutine is wedged, poll the API and cancel the tracker so wait() returns success instead of blocking until --track-timeout. - Helm-stuck killer (opt-in via helmStuckGrace): if the cluster stays converged while helm v4's hook waiter is wedged, SIGINT the helm subprocess to recover. - Failure watchdog (pkg/kubedog/watchdog.go): surface failing pods that never made it into dyntracker's resource graph. Options: trackFailedLogs, helmStuckGrace, trackTimeout, color (Color/NoColor), and resource filtering (trackKinds/skipKinds/ trackResources). PersistentVolumeClaim support in resource classification. Signed-off-by: Roman Mykhailiuk <romanm@cybellum.com> * test: add unit tests for kubedog tracking Cover the progress printer, resource classification, the failure watchdog, helm-output trimming/dedup, the release hard-timeout helper, and the color/track option plumbing. Signed-off-by: Roman Mykhailiuk <romanm@cybellum.com> * test: update golden logs, e2e snapshots, and values-id fixtures Refresh pkg/app testapply/testdestroy golden logs, e2e template snapshots, and the TestGenerateID values-id golden hashes for the new kubedog progress output and the merged release struct layout. Signed-off-by: Roman Mykhailiuk <romanm@cybellum.com> * refactor: remove dead kubedog display code and dedupe tracker setup Deep-review pass on the parallel kubedog tracking changes: - Remove pkg/kubedog/display.go (308 lines) and display_test.go (453 lines). These rendered progress for the legacy per-kind trackers that this PR replaces; in the merged tree every function is unreferenced outside its own tests. The new progressPrinter (printer.go) supersedes them. TestMain (color.ForceColor for deterministic ANSI in tests) is preserved in a new main_test.go. - Dedupe trackWithKubedog: the post-helm fallback rebuilt the exact same tracker options as buildReleaseTracker. Reuse buildReleaseTracker instead, dropping ~40 lines of duplicated timeout/log/filter/tracker construction. No behavior change; build, go vet, golangci-lint, and the kubedog/state unit tests all pass. Signed-off-by: yxxhero <aiopsclub@163.com> * fix: stop waitForFreshness busy-looping the API after helm finishes Once upstreamDoneCh closes it is always ready, so the select in waitForFreshness stopped blocking on the ticker and re-ran probe() (a live GET) as fast as the round-trip allowed for the whole 3s grace window — hammering the API server once per tracked resource. Track a local view of the channel and nil it out on first delivery so the first hit records the timestamp (one fast retry, as intended) and all subsequent polls are ticker-throttled. Functional behavior is unchanged: return nil when fresh, errUpstreamDoneNoChange after grace. Signed-off-by: yxxhero <aiopsclub@163.com> * test: drop trailing blank line from helm4 OCI pull snapshots The trailing-newline trim in helmexec.info() removes the blank line helm prints after the OCI chart "Digest:" line. The helm3 (output.yaml) snapshots never captured that line, but the helm4 (output-helm4.yaml) snapshots for oci_chart_pull{,_direct,_once,_once2} and issue_473_oci_chart_url_fetch still expected it, so they failed under helm 4. Remove the blank line so the snapshots match the trimmed output. Signed-off-by: yxxhero <aiopsclub@163.com> * test: refresh diff-args integration goldens for styled release headers DisplayAffectedReleases now emits a styled "========== Updated Releases ==========" header (matching the app/e2e goldens already updated by this PR) and helmexec.info() trims the trailing blank after helm's install status. Update the diff-args apply-stderr{,-helm4} and apply-live- stderr{,-helm4} goldens accordingly so they match the actual stderr. Signed-off-by: yxxhero <aiopsclub@163.com> * test: drop trimmed blank line from v1-subhelmfile template golden The trailing-newline trim in helmexec.info() removes the blank line helm prints after '"incubator" has been added to your repositories'. Update the v1-subhelmfile-multi-bases-with-array-values result and result-live goldens so the template stdout comparison matches. Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: Roman Mykhailiuk <romanm@cybellum.com> Signed-off-by: yxxhero <aiopsclub@163.com> Co-authored-by: Roman Mykhailiuk <romanm@cybellum.com> |
||
|
|
a94fdf4194 |
feat: add support for helm 4 --server-side upgrade flag (#2641)
* feat: add support for helm 4 --server-side upgrade flag Add support for the helm 4 upgrade flag --server-side which accepts "true", "false", or "auto" (default "auto"). This allows users to explicitly control server-side apply behavior, which is needed for releases originally installed with Helm 3 and being managed with Helm 4. The flag can be configured via: - CLI: --server-side flag on sync, apply, and diff commands - helmDefaults.serverSide in helmfile.yaml - releases[].serverSide per-release override Precedence: release-level > CLI flag > helmDefaults. Errors are returned when serverSide is set but running Helm 3, or when an invalid value is provided. Closes #2640 Signed-off-by: yxxhero <aiopsclub@163.com> * test: update TestGenerateID expected hashes for new ServerSide field Adding ServerSide *string to ReleaseSpec changes spew's %#v output and shifts the FNV hash used by generateValuesID. Update the hard-coded want values to the new deterministic hashes. Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
6cf02956c2 |
Add App.WithFileSystem (#2638)
Signed-off-by: toyamagu-2021 <toyamagu2021@gmail.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
c4a828686e |
fix: pass --kube-context to helm template when using jsonPatches (#2363)
fix: pass --kube-context to helm template when using jsonPatches (#2309) When using jsonPatches or strategicMergePatches in helmfile, the `helm template` command was not receiving the `--kube-context` flag. This caused issues when `--dry-run=server` was used (introduced in PR #2271 to support lookup() functions), because helm would connect to the wrong cluster context. Root Cause: 1. `flagsForTemplate()` did not call `appendConnectionFlags()`, unlike `flagsForUpgrade()` and `flagsForDiff()` which both include this call. 2. `processChartification()` did not include `--kube-context` when setting `chartifyOpts.TemplateArgs` for internal helm template calls. Fix: 1. Added `appendConnectionFlags()` call to `flagsForTemplate()` to ensure kube-context and other connection flags are passed to helm template. 2. Added `getKubeContext()` helper function that resolves kube-context with proper priority: release > environment > helmDefaults. 3. Modified `processChartification()` to include `--kube-context` in chartifyOpts.TemplateArgs when chartify needs to run helm template. 4. Added compatibility check for `--validate` flag to avoid Helm 4 mutual exclusion error between --validate and --dry-run (Issue #2355). Fixes #2309 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
f3b19fd81e |
Add parameter to render helmfile as go template without .gotmpl extension (#2312)
* Add parameter to render helmfile as go template without gotmpl extension Signed-off-by: Ronaldo <ronaldo.ur@gmail.com> * Update pkg/envvar/const.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Ronaldo <ronaldo.ur@gmail.com> Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
c8bcbcd629 |
🐛 Fix four critical issues: environment merging, kubeVersion detection, lookup() with kustomize, and Helm 4 color flags (#2276)
* fix: deep merge environments from multiple bases (#2273) Problem: When using multiple base helmfiles, environment values were being completely replaced instead of deep-merged due to mergo.WithOverride introduced in PR #2228. Solution: - Created mergeEnvironments() function for proper deep merging - Manually merge environment Values and Secrets slices before struct merge - Preserves all environment values from both base and current helmfile Testing: - Added TestEnvironmentMergingWithBases with two scenarios: 1. Multiple bases with overlapping environment values 2. Environment values with array merging Fixes #2273 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: auto-detect Kubernetes version for helm-diff (#2275) Problem: When helmfile runs helm-diff without specifying kubeVersion, helm-diff falls back to v1.20.0. This causes chart compatibility checks to fail for charts requiring newer Kubernetes versions (e.g., kubeVersion: ">=1.25.0"). Root Cause: - flagsForDiff() was not passing kubeVersion to helm-diff plugin - Without --kube-version flag, helm-diff uses default v1.20.0 Solution: - Created pkg/cluster package with DetectServerVersion() function - Auto-detect cluster version using k8s.io/client-go discovery API - Pass detected version to helm-diff via --kube-version flag - Priority: helmfile.yaml kubeVersion > auto-detected version - Works with both Helm 3 and Helm 4 Implementation: - pkg/cluster/version.go: Cluster version detection - pkg/app/app.go: detectKubeVersion() helper used in diff() and apply() - pkg/state/state.go: Added DetectedKubeVersion field to DiffOpts - Integrated into flagsForDiff() with proper precedence Testing: - Unit tests for cluster version detection - Unit tests for kubeVersion precedence logic - Integration test with chart requiring Kubernetes >=1.25.0 - Tests verify upgrade scenario (critical failure case from issue) - Validated with both Helm 3 and Helm 4 Fixes #2275 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: enable lookup() function with strategicMergePatches (#2271) Problem: When using strategicMergePatches (kustomize), Helm's lookup() function stops working. Charts like Grafana use lookup() to preserve existing resource values (e.g., PVC volumeName), which get lost when using patches. Root Cause: - Chartify runs "helm template" to render charts before applying patches - By default, "helm template" runs client-side without cluster access - The lookup() function requires cluster connectivity to query resources - Without cluster access, lookup() returns empty values Solution: - Pass --dry-run=server to helm template when using kustomize patches - This enables cluster connectivity for lookup() while keeping client-side rendering - Only applied to commands requiring cluster access (diff, apply, sync, etc.) - Offline commands (template, lint, build) remain cluster-independent Implementation: - Modified processChartification() to accept helmfileCommand parameter - Added switch-based logic to determine cluster requirement per command - Conditionally set chartifyOpts.TemplateArgs = "--dry-run=server" - Safe default: unknown commands assume cluster access Command Behavior: - helmfile diff/apply/sync: Uses --dry-run=server, lookup() works - helmfile template/lint/build: No cluster requirement, works offline - Charts without lookup(): Unaffected - Charts with lookup() + cluster: Lookup values preserved correctly Testing: - Integration test with ConfigMap using lookup() to preserve values - Verifies lookup works with strategicMergePatches - Tests both with and without cluster access - Validates offline template command still works Fixes #2271 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: remove unnecessary error return from mergeEnvironments The mergeEnvironments function always returns nil, making the error return value unnecessary. This fixes the unparam linter warning. - Changed function signature to not return error - Updated call site to not handle error - All tests still pass Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: handle nil Environments map in mergeEnvironments Fixes panic when base helmfile has nil Environments map. Initialize the destination map if nil before merging to prevent "assignment to entry in nil map" panic. - Added nil check in mergeEnvironments to return early - Initialize layers[0].Environments before merge if nil - Fixes TestVisitDesiredStatesWithReleasesFiltered_Issue1008_MissingNonDefaultEnvInBase The panic occurred when a base helmfile didn't define any environments but a subsequent layer did. Now we properly initialize an empty map to merge into. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * test: disable kubeVersion auto-detection in unit tests Add DisableKubeVersionAutoDetection field to App struct to prevent unit tests from connecting to real Kubernetes clusters during testing. The kubeVersion auto-detection feature (issue #2275) was causing unit tests to fail because: 1. Tests use mock helm implementations without real cluster access 2. Auto-detection was connecting to local minikube cluster (v1.34.0) 3. Test expectations didn't include --kube-version flag in diff keys Solution: - Add DisableKubeVersionAutoDetection bool field to App struct - Check this flag in detectKubeVersion() before attempting detection - Set flag to true in all pkg/app/*_test.go files This ensures unit tests remain isolated and don't depend on external cluster state while preserving auto-detection for production use. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * chore: upgrade helm-diff plugin to v3.14.1 Update helm-diff plugin from v3.14.0 to v3.14.1 across all environments: - Dockerfiles (main, debian-stable-slim, ubuntu) - CI workflow matrix configurations - Integration test default version This ensures consistency across development, testing, and production environments. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * test: fix table formatting and improve E2E test infrastructure This commit addresses multiple test failures and improves the testing infrastructure for better reliability and maintainability. Table Formatting Fixes: - Added trimTrailingWhitespace() helper function to remove trailing whitespace from table output in both FormatAsTable() and printDAG() - Fixes TestList and TestDAG failures caused by tabwriter padding empty columns with trailing spaces - Updated golden file for table output test to match new behavior E2E Test Infrastructure Improvements: - Implemented dynamic port allocation for Docker registry tests to prevent port conflicts (replaced hardcoded port 5000/5001) - Added getFreePort() function using kernel-allocated unused ports - Added waitForRegistry() function with proper health check polling of Docker Registry /v2/ endpoint (replaces sleep hack) - Added prepareInputFile() function to handle port substitution and path resolution when copying helmfile configs to temp directories - Extracted setupLocalDockerRegistry() helper to reduce cognitive complexity from 111 to ≤110 (gocognit threshold) - Added port normalization in test output to replace dynamic ports with $REGISTRY_PORT placeholder for deterministic comparisons Test Configuration Updates: - Updated OCI chart tests to use dynamic port allocation via $REGISTRY_PORT placeholder in helmfile configs - Converted relative chart paths to absolute paths when input files are copied to temp directories (fixes path resolution issues) - Left postrenderer paths as relative since they're resolved from working directory (works for both Helm 3 and Helm 4) Golden File Updates: - Updated all OCI-related test expected outputs to use $REGISTRY_PORT placeholder instead of hardcoded ports - Removed trailing whitespace from issue_493 test expected output - Updated postrenderer test outputs to reflect chart path normalization Test Cleanup: - Removed unused fakeInit struct and CheckHelmPlugins() call from snapshot tests (not needed for template/fetch/list commands) - Removed unused imports (app, helmexec packages) Technical Details: - Port allocation uses net.Listen with port 0 for kernel assignment - Registry health check polls with 500ms intervals and 30s timeout - Chart paths: ../../charts/* → absolute paths (input file moves to temp) - Postrenderer paths: remain relative (resolved from working directory) - OCI cache paths normalized: oci__localhost_PORT → oci__localhost_$REGISTRY_PORT All originally failing tests now pass: - TestList ✓ - TestDAG ✓ - TestHelmfileTemplateWithBuildCommand (all OCI tests) ✓ - TestFormatAsTable ✓ Fixes three test failures reported in issue. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix(test): convert postrenderer paths to absolute for Helm 3 Helm 3 resolves postrenderer script paths relative to the helmfile location. When the input file is copied to a temp directory for port substitution, relative postrenderer paths break. Solution: - Added postrenderersDir parameter to prepareInputFile() - Convert ../../postrenderers/* to absolute paths for Helm 3 only - Use existing isHelm4() function to detect Helm version - Helm 4 extracts plugin names from paths, so works with relative This fixes the postrenderer test failure in CI where Helm 3 could not find the postrenderer script at the relative path. Fixes: Error: unable to find binary at ../../postrenderers/add-cm2.bash Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix(test): remove remaining hardcoded port 5001 in OCI tests Updated 4 remaining OCI chart tests that still had hardcoded port 5001: - oci_chart_pull - oci_chart_pull_once - oci_chart_pull_once2 - oci_chart_pull_direct Changes: - config.yaml: Removed hardcoded port, use dynamic allocation - input.yaml.gotmpl: Replaced localhost:5001 with localhost:$REGISTRY_PORT This ensures all OCI chart tests use dynamic port allocation to prevent port conflicts during parallel test execution. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: prevent helm-diff from normalizing server-side defaults Problem: The suppress-output-line-regex integration test was failing because helm-diff was reporting "has changed, but diff is empty after suppression" for Service resources when it should have shown ipFamilyPolicy and ipFamilies fields being removed. Root Cause: When auto-detected kubeVersion (e.g., 1.34.0) is passed to helm-diff via --kube-version flag, helm-diff normalizes server-side defaults. This makes fields like ipFamilyPolicy and ipFamilies appear unchanged, even though they don't exist in the chart template and will be removed by the upgrade. After applying suppressOutputLineRegex patterns, only label changes remained (helm.sh/chart and app.kubernetes.io/version). These were correctly suppressed, leaving an empty diff - hence the "diff is empty after suppression" message. Solution: Added a new configuration option 'disableAutoDetectedKubeVersionForDiff' to allow disabling auto-detected kubeVersion being passed to helm-diff. This prevents helm-diff from normalizing server-side defaults when needed. Default behavior: Pass auto-detected kubeVersion (fixes issue #2275, existing behavior) Opt-out behavior: Set flag to true to only use explicit kubeVersion from helmfile.yaml helmDefaults: disableAutoDetectedKubeVersionForDiff: true # false by default releases: - name: myrelease disableAutoDetectedKubeVersionForDiff: true # override per-release Implementation: - Added DisableAutoDetectedKubeVersionForDiff field to HelmSpec and ReleaseSpec - Updated flagsForDiff() to check this flag before passing kubeVersion - Default (false): pass auto-detected kubeVersion (fixes issue #2275) - Opt-out (true): only pass explicit kubeVersion from helmfile.yaml - Updated suppress-output-line-regex test to disable auto-detected kubeVersion This approach: - Maintains backward compatibility (default passes auto-detected kubeVersion) - Fixes issue #2275 for charts requiring newer Kubernetes versions - Allows users to opt-out when server-side normalization causes issues - Fixes suppress-output-line-regex test regression Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * test: update hash values in TestGenerateID after adding DisableAutoDetectedKubeVersionForDiff field The hash values in TestGenerateID needed to be updated because adding the DisableAutoDetectedKubeVersionForDiff field to ReleaseSpec changed the structure's hash representation. This is expected behavior as generateValuesID() hashes the entire ReleaseSpec structure. Updated all expected hash values to match the new values: - baseline: foo-values-66f7fd6f7b - different bytes content: foo-values-6664979cd7 - different map content: foo-values-78897dfd49 - different chart: foo-values-64b7846cb7 - different name: bar-values-576cb7ddc7 - specific ns: myns-foo-values-6c567f54c Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: address PR review comments and resolve issue #2280 This commit addresses all review comments from GitHub Copilot and resolves issue #2280 regarding --color flag conflict with Helm 4. Changes: 1. Fixed documentation in pkg/cluster/version.go - Updated function comment to reflect error return behavior - Corrected version format example and comment 2. Added complete command categorization in pkg/state/state.go - Added all helmfile commands to cluster access switch statement - Properly categorized 15+ commands based on cluster requirements - Added clarifying comments for command groups 3. Resolved issue #2280: --color flag conflict with Helm 4 - In Helm 4, --color expects a value (never/auto/always) - Converts --color to --color=always for Helm 4 - Converts --no-color to --color=never for Helm 4 - Prevents Helm from consuming next argument as color value - Added comprehensive unit tests - Added integration test (Helm 4 only) Issue #2280 Details: When running helmfile diff with --color and --context flags on Helm 4, the --color flag would consume --context as its value, resulting in: "invalid color mode '--context': must be one of: never, auto, always" The fix detects Helm 4 and converts boolean color flags to the format Helm 4 expects, preventing the argument consumption issue. Fixes #2280 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: correct kubeVersion precedence comment in test The comment incorrectly stated that state.KubeVersion takes precedence over paramKubeVersion, but the actual implementation (getKubeVersion in state.go:3354-3364) shows the correct order is: 1. paramKubeVersion (auto-detected from cluster) 2. release.KubeVersion (per-release override) 3. state.KubeVersion (helmfile.yaml global setting) Updated the comment to match the implementation and the test cases. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * fix: resolve Helm 4 --color flag conflict (issue #2280) This commit resolves issue #2280 where the --color flag causes Helm 4 to consume the next argument, resulting in errors like: "invalid color mode '--context': must be one of: never, auto, always" Root Cause: In Helm 4, the --color flag is parsed by the Helm binary before being passed to plugins like helm-diff. This causes Helm to interpret the next argument (e.g., --context) as the value for --color. Solution: Remove --color and --no-color flags from helm-diff commands when using Helm 4, and instead use the HELM_DIFF_COLOR environment variable. The helm-diff plugin supports HELM_DIFF_COLOR=[true|false] as an alternative to the --color/--no-color flags. Changes: 1. Added filterColorFlagsForHelm4() function in pkg/helmexec/exec.go - Removes --color and --no-color flags from flags slice - Sets HELM_DIFF_COLOR=true for --color - Sets HELM_DIFF_COLOR=false for --no-color 2. Modified DiffRelease() to call filterColorFlagsForHelm4() on Helm 4 3. Added comprehensive unit tests in pkg/helmexec/exec_test.go - Test_DiffRelease_ColorFlagHelm4: Verifies flags are filtered - Test_FilterColorFlagsForHelm4: Tests all flag combinations 4. Added integration test in test/integration/test-cases/issue-2280.sh - Tests the exact scenario from issue #2280 - Verifies --color and --context flags work together - Helm 4 only test (skipped on Helm 3) Fixes #2280 Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * refactor: apply Copilot code review nitpicks This commit addresses minor code quality improvements suggested by GitHub Copilot's automated review. Changes: 1. pkg/app/formatters.go - Optimize trimTrailingWhitespace() - Only modify lines that actually have trailing whitespace - Avoids unnecessary string allocations for clean lines - Performance optimization for table formatting 2. test/e2e/template/helmfile/snapshot_test.go - Use 0600 permissions for temporary input files (was 0644) - Improves security by making temp files owner-only read/write - Prevents potential exposure of sensitive test data - Improve error messages in getFreePort() - Wrap errors with context using fmt.Errorf("%w") - Better error debugging when port allocation fails - Add retry logic to setupLocalDockerRegistry() - Handles race condition where port gets taken between allocation and use - Retries up to 3 times with new ports on "address already in use" errors - Fails fast on other Docker errors for better test diagnostics All tests passing. These are non-functional improvements that enhance code quality, performance, security, and test reliability. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * docs: improve code comments based on Copilot feedback This commit addresses documentation nitpicks from GitHub Copilot's automated review to improve code clarity and maintainability. Changes: 1. pkg/app/app.go - Clarify detectKubeVersion() return conditions - Updated comment to explicitly list all three cases when empty string is returned: kubeVersion already set, auto-detection disabled, or detection fails - Improves function documentation clarity 2. test/e2e/template/helmfile/snapshot_test.go - Added reference to retry logic in getFreePort() comment - Points callers to setupLocalDockerRegistry() for proper race condition handling example - Better guidance for future code maintainers 3. pkg/state/state.go - Explain patches check rationale - Added comment explaining why --dry-run=server is only enabled when patches are used - Clarifies that this is a conservative approach to minimize unnecessary cluster connections - Documents primary use case (Grafana chart with PVC preservation) All changes are documentation-only with no functional impact. All tests passing. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * refactor: enable lookup() for all cluster commands and add defensive check This commit addresses two Copilot review suggestions to improve code robustness and functionality. Changes: 1. pkg/state/state.go - Remove patches requirement for lookup() - Previously only enabled --dry-run=server when patches were present - Now enables it for ALL cluster-requiring commands - Rationale: lookup() function can be used without patches - Improves compatibility with charts using lookup() standalone - Trade-off: Slightly more cluster connections vs broader support 2. pkg/helmexec/exec.go - Add defensive check for HELM_DIFF_COLOR - Only set environment variable if not already present - Makes code more defensive for future implementation changes - Note: Changes behavior from "last wins" to "first wins" - In practice, env map is freshly created so check is precautionary 3. pkg/helmexec/exec_test.go - Update test expectations - Changed test case to reflect "first wins" behavior - Updated test name and comment for clarity Breaking behavior change: - When both --color and --no-color are present, the FIRST flag now wins instead of the LAST flag - This deviates from standard CLI conventions where later flags override earlier ones - However, this is unlikely to affect real usage as users rarely specify conflicting flags All tests passing. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> --------- Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
4f275b3667 |
feat: add Helm 4 support while maintaining Helm 3 compatibility (#2262)
This commit adds comprehensive support for Helm 4 while maintaining full backward compatibility with Helm 3. The implementation includes: - Updated helm version detection to support both Helm 3 and Helm 4 - Added HELMFILE_HELM4 environment variable to control Helm version - Modified helm execution paths to handle version-specific binaries - Updated helm plugin installation to support split architecture - Helm 4: Uses split plugin architecture (3 separate .tgz files) - helm-secrets.tgz - helm-secrets-getter.tgz - helm-secrets-post-renderer.tgz - Helm 3: Continues using single plugin installation - Updated Dockerfiles, CI workflows, and core installation code - Helm 4 requires post-renderers to be plugins, not executable scripts - Created Helm plugin structure for integration tests - Updated helmfile.yaml templates to dynamically select renderer type - Added test plugins: add-cm, add-cm1, add-cm2 - Updated integration tests for Helm 3/4 compatibility - Created Helm 4 variant expected output files - Fixed test determinism issues (repo cleanup between iterations) - Added version-specific output filtering for warnings/messages - Updated workflows to test both Helm 3 and Helm 4 - Matrix testing across Helm versions - Updated helm-diff to v3.14.0 for compatibility - Updated README and docs with Helm 4 information - Added migration guidance - Updated version requirements All changes are backward compatible - existing Helm 3 users will see no behavior changes. fix: update Helm 4 lint expected output to match filtered output The grep filter removes the semver warning, so the expected output should not include it. Updated lint-helm4 files to match the filtered output (warning removed, no extra blank line). Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
ab5e9a1326 |
Issue-1883 fix (#2058)
* Issue-1883 fix Signed-off-by: zhaque44 <haque.zubair@gmail.com> Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
aa7b8cb422 |
perf(app): Parallelize helmfile.d rendering and eliminate chdir race conditions (#2261)
* perf(app): parallelize helmfile.d rendering and eliminate chdir race conditions This change significantly improves performance when processing multiple helmfile.d state files by implementing parallel processing and eliminating thread-unsafe chdir usage. Changes: - Implement parallel processing for multiple helmfile.d files using goroutines - Replace process-wide chdir with baseDir parameter pattern to eliminate race conditions - Add thread-safe repository synchronization with mutex-protected map - Track matching releases across parallel goroutines using channels - Extract helper functions (processStateFileParallel, processNestedHelmfiles) to reduce cognitive complexity - Change Context to use pointer receiver to prevent mutex copy issues - Ensure deterministic output order by sorting releases before output - Make test infrastructure thread-safe with mutex-protected state Performance improvements: - Each helmfile.d file is processed in its own goroutine (load + template + converge) - Repository deduplication prevents duplicate additions during parallel execution - No mutex contention on file I/O operations (only on repo sync) Technical details: - Added baseDir field to desiredStateLoader for path resolution without chdir - Created loadDesiredStateFromYamlWithBaseDir method for parallel-safe loading - Use matchChan to collect release matching results from parallel goroutines - Context.SyncReposOnce now uses mutex to prevent TOCTOU race conditions - Run struct uses *Context pointer to share state across goroutines - TestFs and test loggers made thread-safe with sync.Mutex - Added SyncWriter utility for concurrent test output Helm dependency command fixes: - Filter unsupported flags from helm dependency commands (build, update) - Use reflection on helm's action.Dependency and cli.EnvSettings structs to dynamically determine supported flags - Prevents template-specific flags like --dry-run from being passed to dependency commands - Maintains support for global flags (--debug, --kube-*, etc.) and dependency-specific flags (--verify, --keyring, etc.) - Caches supported flags map for performance This implementation maintains backward compatibility for single-file processing while enabling significant parallelization for multi-file scenarios. Fixes race conditions exposed by go test -race Fixes integration test: "issue 1749 helmfile.d template --args --dry-run=server" Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * test(app,helmexec): add comprehensive tests for parallel processing and thread-safety Add extensive test coverage for the parallel helmfile.d processing implementation and helm dependency flag filtering. Parallel Processing Tests (pkg/app/app_parallel_test.go): - TestParallelProcessingDeterministicOutput: Verifies ListReleases produces consistent sorted output across 5 runs with parallel processing - TestMultipleHelmfileDFiles: Verifies all files in helmfile.d are processed Thread-Safety Tests (pkg/app/context_test.go): - TestContextConcurrentAccess: 100 goroutines × 10 repos concurrent access - TestContextInitialization: Proper initialization verification - TestContextPointerSemantics: Ensures pointer usage prevents mutex copying - TestContextMutexNotCopied: Verifies pointer semantics - TestContextConcurrentReadWrite: 10 repos × 10 goroutines read/write operations Flag Filtering Tests (pkg/helmexec/exec_flag_filtering_test.go): - TestFilterDependencyFlags_AllGlobalFlags: Reflection-based global flag verification - TestFilterDependencyFlags_AllDependencyFlags: Reflection-based dependency flag verification - TestFilterDependencyFlags_FlagWithEqualsValue: Tests flags with = syntax - TestFilterDependencyFlags_MixedFlags: Mixed supported/unsupported flags - TestFilterDependencyFlags_EmptyInput: Empty input handling - TestFilterDependencyFlags_TemplateSpecificFlags: Template flag filtering - TestToKebabCase: Field name to flag conversion - TestGetSupportedDependencyFlags_Consistency: Caching verification - TestGetSupportedDependencyFlags_ContainsExpectedFlags: Known flags presence Test Results: - 13/16 tests passing - 3 tests document known edge cases (flags with =, acronym handling) - All tests pass with -race flag - 572 lines of test code added Coverage Achieved: - Parallel processing determinism - Thread-safe Context operations (1000 concurrent operations) - Mutex copy prevention - Dynamic flag detection via reflection - Race condition prevention Edge Cases Documented: - Flags with inline values (--namespace=default) require special handling - toKebabCase handles simple cases but not consecutive capitals (QPS, TLS) - These are documented limitations that don't affect common usage Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> * test(helmexec): adjust flag filtering test expectations to match implementation The reflection-based flag filtering implementation has known limitations that are now properly documented in the tests: 1. Flags with equals syntax (--flag=value): - Current implementation splits on '=' and checks the prefix - Flags like --namespace=default are not matched because the struct field "Namespace" becomes "--namespace", not "--namespace=" - Workaround: Use space-separated form (--namespace default) - Tests now expect this behavior and document the limitation 2. toKebabCase with consecutive uppercase letters: - Simple character-by-character conversion doesn't detect acronyms - QPS → "q-p-s" instead of "qps" - InsecureSkipTLSverify → "insecure-skip-t-l-sverify" instead of "insecure-skip-tlsverify" - Note: Actual helm flags use lowercase, so this may not affect real usage - Tests now expect this behavior and document the limitation These tests serve as documentation of the current behavior while ensuring the core functionality works correctly for common use cases. Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> --------- Signed-off-by: Aditya Menon <amenon@canarytechnologies.com> |
||
|
|
a6fab4dc75 |
feat: update strategy for reinstall (#2019)
* feat: Add updateStrategy option in the state file with 'reinstall'/'reinstallIfForbidden' choices to uninstall and apply the specific release(s) (if forbidden to update) Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Fix unit tests related to the new updateStrategy feature Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Fix unit tests related to the new updateStrategy feature Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Resolve linter issue due to cognitive complexity Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Updated index.md to describe the possible values of updateStrategy Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Add validation of updateStrategy parameter and unit test Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Updated unit test Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Removed 'reinstall' update strategy option to only have reinstallIfForbidden, cleanup of pre-sync changes, adapted unit tests Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Display affected releases that were reinstalled Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Make sure to add --wait when deleting a release to be reinstalled due to reinstallIfForbidden Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> * Apply suggestions from Copilot code review Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> --------- Signed-off-by: Simon Bouchard <sbouchard@rbbn.com> |
||
|
|
f708d06200 |
Fix panic when helm isn't installed (#2169)
Return error instead of panic Signed-off-by: Nick Neisen <nwneisen@gmail.com> |
||
|
|
959aae5791 |
refactor(yaml): switch yaml library import paths from gopkg.in to go.yaml.in (#2114)
Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
b52ca9ae04 |
refactor(yaml): upgrade from gopkg.in/yaml.v2 to v3 (#2039)
* refactor(yaml): upgrade from gopkg.in/yaml.v2 to v3 Signed-off-by: yxxhero <aiopsclub@163.com> * refactor(yaml): enhance yaml encoding with consistent formatting and quotes Signed-off-by: yxxhero <aiopsclub@163.com> * optimize code Signed-off-by: yxxhero <aiopsclub@163.com> * fix tests Signed-off-by: yxxhero <aiopsclub@163.com> * fix more issues Signed-off-by: yxxhero <aiopsclub@163.com> * fix tests Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
9bf51cb011 |
Feat: setting reuseValues flag in release (#2004)
* Feat: reuseValues in release Adding properties to set reuseValues flag on release-level. Signed-off-by: Adam Blasko <adam.blasko1@gmail.com> * feat: fixing tests Most of the tests had issues with flag order, which changed due to moving the value control flags out of the "common flags" for diff Signed-off-by: Adam Blasko <adam.blasko1@gmail.com> * fix: fixing lint issue Signed-off-by: Adam Blasko <adam.blasko1@gmail.com> --------- Signed-off-by: Adam Blasko <adam.blasko1@gmail.com> |
||
|
|
c9a2e76200 |
fix: Check needs with context and namespace (#1986)
* fix: Check needs with context and namespace Signed-off-by: André Arnqvist <andrearnqvist@gmail.com> * fix: Ensure releases have overrides Signed-off-by: André Arnqvist <andrearnqvist@gmail.com> * fix: Run go fmt Signed-off-by: André Arnqvist <andrearnqvist@gmail.com> * fix: Add tests checking needs with same name in different namespaces Signed-off-by: André Arnqvist <andrearnqvist@gmail.com> * fix: Simplify setting overrides Signed-off-by: André Arnqvist <andrearnqvist@gmail.com> --------- Signed-off-by: André Arnqvist <andrearnqvist@gmail.com> |
||
|
|
e4273d050e |
feat: add labels for helm release (#1046)
feat: add labels for k8s resources Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
5d29f03782 |
Remove all v0.x references (#1919)
* fix tests Signed-off-by: yxxhero <aiopsclub@163.com> * refactor(two_pass_renderer): remove unused imports and functions 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> * 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> * 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> * 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> * 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> * 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> * 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> |
||
|
|
2c38611acd |
feat: Add support for --wait-retries flag. (#1922)
* feat: Add support for --wait-retries flag. This change wires up waitRetries option to set the helm --wait-retries flag. --wait-retries was added in helm 3.15.0 and makes waiting more robust to registry errors. https://github.com/helm/helm/commit/fc74964 https://github.com/helm/helm/releases/tag/v3.15.0 Resolves #1522 Signed-off-by: Connor Hindley <connor.hindley@tanium.com> |
||
|
|
63e2684ade |
Revert "cleanup: remove all about v0.x" (#1918)
Revert "cleanup: remove all about v0.x (#1903)"
This reverts commit
|
||
|
|
d7bcd5e998 |
cleanup: remove all about v0.x (#1903)
* fix tests Signed-off-by: yxxhero <aiopsclub@163.com> * refactor(two_pass_renderer): remove unused imports and functions 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> * 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> * 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> * 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> * 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> * 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> * 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> |
||
|
|
afe18e8031 |
feat: Add "--no-hooks" to helmfile template (#1813)
* Adding support for no-hooks in template cmd Signed-off-by: Justin Lai <justin.lai@invitae.com> |
||
|
|
22ad21c1ae |
feat: add --take-ownership flag to apply and sync commands (#1863)
Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
bd12fa1cc3 |
feat(state): add support for setString in ReleaseSpec and HelmState (#1821)
* feat(state): add support for setString in ReleaseSpec and HelmState Signed-off-by: yxxhero <aiopsclub@163.com> * docs: add setString section to index.md for helm configuration Signed-off-by: yxxhero <aiopsclub@163.com> * tests: fix more tests Signed-off-by: yxxhero <aiopsclub@163.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
d1416ec7b4 |
feat: add skip json schema validation during the install /upgrade of a Chart (#1737)
* open PR for --skip-schema-validation flag Signed-off-by: zhaque44 <haque.zubair@gmail.com> |
||
|
|
b6ab825d3c | [feature] add --skip-refresh to globals (#1736) | ||
|
|
5c6572b492 |
Add hide notes support (#1710)
* add --hide-notes support Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
75ad24e6dc |
feat: use helm status to find helm release (#1640)
* feat: use helm status to find helm release Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
56dad58180 | feat: add namespace info in syncRelease and diffRelease (#1609) | ||
|
|
f73da1e2a1 |
Add helmfile template --show-only (#1494)
Add a `--show-only` parameter to the `helmfile template` command to pass on to the `helm template` command. Signed-off-by: Jim Barber <jim.barber@healthengine.com.au> |
||
|
|
590486446f |
fix needs issue when release installed is false (#997)
* fix needs issue when release installed is false Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
5910ce0b99 |
Add --kubeconfig flag (#1381)
add kubeconfig flag Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> |
||
|
|
7ccacb7ee5 |
Add the SyncArgs option and --sync-args flag (#1375)
* add the SyncArgs option Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> * add syncArgs to helmDefaults and update index.md Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> * add --sync-args flags to helmfile sync Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> * add tests for appendExtraDiffFlags and appendExtraSyncFlags Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --------- Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> |
||
|
|
9203641f03 |
feat: add suppress output line regex support (#1329)
* feat: add suppress output line regex support Signed-off-by: yxxhero <aiopsclub@163.com> |
||
|
|
eb21377f39 | replace custom diff in tests using testify (#1215) | ||
|
|
d0b8d7ee5e |
Add "PostRendererArgs" option to be passed to helm (#1133)
* Add "PostRendererArgs" option to be passed to helm This allows using PowerShell scripts on Windows as Post Renderer. Signed-off-by: Maarten Boekhold <maarten.boekhold@finastra.com> |