From fcc0d4d92d9688d4a021eca075fc51945971a824 Mon Sep 17 00:00:00 2001 From: Thomas Arrow Date: Mon, 4 Sep 2023 14:02:20 +0100 Subject: [PATCH 1/3] Fix interactive apply asks in no change situation 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 Fixes: helmfile#679 Signed-off-by: Thomas Arrow --- docs/index.md | 2 +- pkg/app/app.go | 4 ++++ .../testapply/helm-status-check-to-release-existence/log | 5 ----- pkg/app/testdata/testapply/noop/log | 7 ------- .../testdata/testapply_hooks/hooks_for_no-diff_release/log | 6 ------ 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/docs/index.md b/docs/index.md index 84948bd6..bc734a67 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1483,7 +1483,7 @@ Hooks associated to `presync` events are triggered before each release is synced This is the ideal event to execute any commands that may mutate the cluster state as it will not be run for read-only operations like `lint`, `diff` or `template`. `preapply` hooks are triggered before a release is uninstalled, installed, or upgraded as part of `helmfile apply`. -This is the ideal event to hook into when you are going to use `helmfile apply` for every kind of change and you want the hook to be triggered regardless of whether the releases have changed or not. Be sure to make each `preapply` hook command idempotent. Otherwise, rerunning helmfile-apply on a transient failure may end up either breaking your cluster, or the hook that runs for the second time will never succeed. +This is the ideal event to hook into when you are going to use `helmfile apply` for every kind of change and it is acceptable for the hook to be triggered regardless of whether the releases have changed or not (n.b. if there are no changes for any releases then this will not run). Be sure to make each `preapply` hook command idempotent. Otherwise, rerunning helmfile-apply on a transient failure may end up either breaking your cluster, or the hook that runs for the second time will never succeed. `preuninstall` hooks are triggered immediately before a release is uninstalled as part of `helmfile apply`, `helmfile sync`, `helmfile delete`, and `helmfile destroy`. diff --git a/pkg/app/app.go b/pkg/app/app.go index 798e46a1..57d40722 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1637,6 +1637,10 @@ Do you really want to apply? // Traverse DAG of all the releases so that we don't suffer from false-positive missing dependencies st.Releases = selectedAndNeededReleases + if len(releasesToBeUpdated) == 0 && len(releasesToBeDeleted) == 0 { + return true, false, nil + } + if !interactive || interactive && r.askForConfirmation(confMsg) { if _, preapplyErrors := withDAG(st, helm, a.Logger, state.PlanOptions{Purpose: "invoking preapply hooks for", Reverse: true, SelectedReleases: toApplyWithNeeds, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error { for _, r := range subst.Releases { diff --git a/pkg/app/testdata/testapply/helm-status-check-to-release-existence/log b/pkg/app/testdata/testapply/helm-status-check-to-release-existence/log index ed6cbc3e..61e346a1 100644 --- a/pkg/app/testdata/testapply/helm-status-check-to-release-existence/log +++ b/pkg/app/testdata/testapply/helm-status-check-to-release-existence/log @@ -4,9 +4,4 @@ merged environment: &{default map[] map[] map[]} 2 release(s) found in helmfile.yaml Checking release existence using `helm status` for release foo_notFound -invoking preapply hooks for 1 groups of releases in this order: -GROUP RELEASES -1 default//bar, default//foo_notFound - -invoking preapply hooks for releases in group 1/1: default//bar, default//foo_notFound changing working directory back to "/path/to" diff --git a/pkg/app/testdata/testapply/noop/log b/pkg/app/testdata/testapply/noop/log index 936964d2..9a65e238 100644 --- a/pkg/app/testdata/testapply/noop/log +++ b/pkg/app/testdata/testapply/noop/log @@ -3,11 +3,4 @@ changing working directory to "/path/to" merged environment: &{default map[] map[] map[]} 2 release(s) found in helmfile.yaml -invoking preapply hooks for 2 groups of releases in this order: -GROUP RELEASES -1 default//foo -2 default//bar - -invoking preapply hooks for releases in group 1/2: default//foo -invoking preapply hooks for releases in group 2/2: default//bar changing working directory back to "/path/to" diff --git a/pkg/app/testdata/testapply_hooks/hooks_for_no-diff_release/log b/pkg/app/testdata/testapply_hooks/hooks_for_no-diff_release/log index b2f0bdff..0da06e80 100644 --- a/pkg/app/testdata/testapply_hooks/hooks_for_no-diff_release/log +++ b/pkg/app/testdata/testapply_hooks/hooks_for_no-diff_release/log @@ -1,9 +1,3 @@ hook[prepare] logs | foo hook[prepare] logs | - -hook[preapply] logs | foo -hook[preapply] logs | - -hook[cleanup] logs | foo -hook[cleanup] logs | From 78c5c8043a54b64cd215e40d2182a21d672ec12d Mon Sep 17 00:00:00 2001 From: Thomas Arrow Date: Mon, 26 Jan 2026 21:54:44 +0000 Subject: [PATCH 2/3] Update preapply hook description for clarity Clarify conditions under which preapply hooks are triggered to include that they will no longer fire if there is a no-op. Recommended by the maintainer's copilot request --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index bc734a67..eaf81c60 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1483,7 +1483,7 @@ Hooks associated to `presync` events are triggered before each release is synced This is the ideal event to execute any commands that may mutate the cluster state as it will not be run for read-only operations like `lint`, `diff` or `template`. `preapply` hooks are triggered before a release is uninstalled, installed, or upgraded as part of `helmfile apply`. -This is the ideal event to hook into when you are going to use `helmfile apply` for every kind of change and it is acceptable for the hook to be triggered regardless of whether the releases have changed or not (n.b. if there are no changes for any releases then this will not run). Be sure to make each `preapply` hook command idempotent. Otherwise, rerunning helmfile-apply on a transient failure may end up either breaking your cluster, or the hook that runs for the second time will never succeed. +This is the ideal event to hook into when you are going to use helmfile apply for every kind of change. Note that preapply hooks will only run if at least one release has changes to apply. Be sure to make each preapply hook command idempotent. Otherwise, rerunning helmfile apply on a transient failure may end up either breaking your cluster, or the hook that runs for the second time will never succeed. `preuninstall` hooks are triggered immediately before a release is uninstalled as part of `helmfile apply`, `helmfile sync`, `helmfile delete`, and `helmfile destroy`. From fc85cdac2eaad92092078cc1ab7471ff8cb41120 Mon Sep 17 00:00:00 2001 From: Thomas Arrow Date: Mon, 26 Jan 2026 21:56:28 +0000 Subject: [PATCH 3/3] add code markdown --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index eaf81c60..2f99d79b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1483,7 +1483,7 @@ Hooks associated to `presync` events are triggered before each release is synced This is the ideal event to execute any commands that may mutate the cluster state as it will not be run for read-only operations like `lint`, `diff` or `template`. `preapply` hooks are triggered before a release is uninstalled, installed, or upgraded as part of `helmfile apply`. -This is the ideal event to hook into when you are going to use helmfile apply for every kind of change. Note that preapply hooks will only run if at least one release has changes to apply. Be sure to make each preapply hook command idempotent. Otherwise, rerunning helmfile apply on a transient failure may end up either breaking your cluster, or the hook that runs for the second time will never succeed. +This is the ideal event to hook into when you are going to use `helmfile apply` for every kind of change. Note that preapply hooks will only run if at least one release has changes to apply. Be sure to make each `preapply` hook command idempotent. Otherwise, rerunning `helmfile apply` on a transient failure may end up either breaking your cluster, or the hook that runs for the second time will never succeed. `preuninstall` hooks are triggered immediately before a release is uninstalled as part of `helmfile apply`, `helmfile sync`, `helmfile delete`, and `helmfile destroy`.