Repository: roboll/helmfile
Pull request #1179 (2020-04-04 19:21:17)

feat: add option `--include-tests` for diff and apply command
Just like `--suppress-secrets` option of diff and apply command, there is an option `--include-tests` comes from [helm-diff](https://github.com/databus23/helm-diff) plugin.

```diff
NAME:
   helmfile diff - diff releases from state file against env (helm diff)

USAGE:
   helmfile diff [command options] [arguments...]

OPTIONS:
   --args value                  pass args to helm exec
   --set value                   additional values to be merged into the command
   --values value                additional value files to be merged into the command
   --skip-deps helm repo update  skip running helm repo update and `helm dependency build`
   --detailed-exitcode           return a non-zero exit code when there are changes
+  --include-tests               enable the diffing of the helm test hooks
   --suppress-secrets            suppress secrets in the output. highly recommended to specify on CI/CD use-cases
   --concurrency value           maximum number of concurrent helm processes to run, 0 is unlimited (default: 0)
   --context value               output NUM lines of context around changes (default: 0)
```
```diff
NAME:
   helmfile apply - apply all resources from state file only when there are changes

USAGE:
   helmfile apply [command options] [arguments...]

OPTIONS:
   --set value                   additional values to be merged into the command
   --values value                additional value files to be merged into the command
   --concurrency value           maximum number of concurrent helm processes to run, 0 is unlimited (default: 0)
   --context value               output NUM lines of context around changes (default: 0)
   --detailed-exitcode           return a non-zero exit code 2 instead of 0 when there were changes detected AND the changes are synced successfully
   --args value                  pass args to helm exec
   --retain-values-files         Stop cleaning up values files passed to Helm. Together with --log-level=debug, you can manually rerun helm commands as Helmfile did for debugging purpose
+  --include-tests               enable the diffing of the helm test hooks
   --suppress-secrets            suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases
   --suppress-diff               suppress diff in the output. Usable in new installs
   --skip-deps helm repo update  skip running helm repo update and `helm dependency build`
```


Patch:
diff --git a/go.sum b/go.sum
index 88756d3..2988a42 100644
--- a/go.sum
+++ b/go.sum
@@ -562,6 +562,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
 github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
 github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
diff --git a/main.go b/main.go
index 6be1f7d..1832439 100644
--- a/main.go
+++ b/main.go
@@ -191,6 +191,10 @@ func main() {
 					Name:  "detailed-exitcode",
 					Usage: "return a non-zero exit code when there are changes",
 				},
+				cli.BoolFlag{
+					Name:  "include-tests",
+					Usage: "enable the diffing of the helm test hooks",
+				},
 				cli.BoolFlag{
 					Name:  "suppress-secrets",
 					Usage: "suppress secrets in the output. highly recommended to specify on CI/CD use-cases",
@@ -346,6 +350,10 @@ func main() {
 					Name:  "retain-values-files",
 					Usage: "Stop cleaning up values files passed to Helm. Together with --log-level=debug, you can manually rerun helm commands as Helmfile did for debugging purpose",
 				},
+				cli.BoolFlag{
+					Name:  "include-tests",
+					Usage: "enable the diffing of the helm test hooks",
+				},
 				cli.BoolFlag{
 					Name:  "suppress-secrets",
 					Usage: "suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases",
@@ -558,6 +566,10 @@ func (c configImpl) RetainValuesFiles() bool {
 	return c.c.Bool("retain-values-files")
 }
 
+func (c configImpl) IncludeTests() bool {
+	return c.c.Bool("include-tests")
+}
+
 func (c configImpl) SuppressSecrets() bool {
 	return c.c.Bool("suppress-secrets")
 }
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 0658667..3d37c34 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -812,7 +812,7 @@ func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, bool, []error) {
 
 	// TODO Better way to detect diff on only filtered releases
 	{
-		changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.SuppressSecrets(), c.SuppressDiff(), false, diffOpts)
+		changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.IncludeTests(), c.SuppressSecrets(), c.SuppressDiff(), false, diffOpts)
 
 		var err error
 		deletingReleases, err = st.DetectReleasesToBeDeletedForSync(helm, st.Releases)
diff --git a/pkg/app/config.go b/pkg/app/config.go
index 0989ee2..18d39db 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -40,6 +40,8 @@ type ApplyConfigProvider interface {
 	Set() []string
 	SkipDeps() bool
 
+	IncludeTests() bool
+
 	SuppressSecrets() bool
 	SuppressDiff() bool
 
@@ -73,6 +75,8 @@ type DiffConfigProvider interface {
 	Set() []string
 	SkipDeps() bool
 
+	IncludeTests() bool
+
 	SuppressSecrets() bool
 	SuppressDiff() bool
 
diff --git a/pkg/app/run.go b/pkg/app/run.go
index 3cc03fb..75b741e 100644
--- a/pkg/app/run.go
+++ b/pkg/app/run.go
@@ -85,7 +85,7 @@ func (r *Run) Diff(c DiffConfigProvider) []error {
 		NoColor: c.NoColor(),
 		Set:     c.Set(),
 	}
-	_, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.SuppressSecrets(), c.SuppressDiff(), true, opts)
+	_, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.IncludeTests(), c.SuppressSecrets(), c.SuppressDiff(), true, opts)
 
 	return errs
 }
diff --git a/pkg/state/state.go b/pkg/state/state.go
index 184bd0b..b6163dd 100644
--- a/pkg/state/state.go
+++ b/pkg/state/state.go
@@ -951,7 +951,7 @@ type diffPrepareResult struct {
 	errors  []*ReleaseError
 }
 
-func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValues []string, concurrency int, detailedExitCode, suppressSecrets bool, opt ...DiffOpt) ([]diffPrepareResult, []error) {
+func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValues []string, concurrency int, detailedExitCode, includeTests, suppressSecrets bool, opt ...DiffOpt) ([]diffPrepareResult, []error) {
 	opts := &DiffOpts{}
 	for _, o := range opt {
 		o.Apply(opts)
@@ -1014,6 +1014,10 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu
 					flags = append(flags, "--detailed-exitcode")
 				}
 
+				if includeTests {
+					flags = append(flags, "--include-tests")
+				}
+
 				if suppressSecrets {
 					flags = append(flags, "--suppress-secrets")
 				}
@@ -1099,13 +1103,13 @@ type DiffOpt interface{ Apply(*DiffOpts) }
 
 // DiffReleases wrapper for executing helm diff on the releases
 // It returns releases that had any changes
-func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode, suppressSecrets bool, suppressDiff bool, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) {
+func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode, includeTests, suppressSecrets, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) {
 	opts := &DiffOpts{}
 	for _, o := range opt {
 		o.Apply(opts)
 	}
 
-	preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, suppressSecrets, opts)
+	preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, includeTests, suppressSecrets, opts)
 	if len(prepErrs) > 0 {
 		return []ReleaseSpec{}, prepErrs
 	}


Test patch:
diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go
index c97a93a..d35d786 100644
--- a/pkg/app/app_test.go
+++ b/pkg/app/app_test.go
@@ -2000,6 +2000,7 @@ type applyConfig struct {
 	set               []string
 	validate          bool
 	skipDeps          bool
+	includeTests      bool
 	suppressSecrets   bool
 	suppressDiff      bool
 	noColor           bool
@@ -2030,6 +2031,10 @@ func (a applyConfig) SkipDeps() bool {
 	return a.skipDeps
 }
 
+func (a applyConfig) IncludeTests() bool {
+	return a.includeTests
+}
+
 func (a applyConfig) SuppressSecrets() bool {
 	return a.suppressSecrets
 }
diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go
index afadc5d..91691ad 100644
--- a/pkg/state/state_test.go
+++ b/pkg/state/state_test.go
@@ -1391,7 +1391,7 @@ func TestHelmState_DiffReleases(t *testing.T) {
 				logger:      logger,
 				valsRuntime: valsRuntime,
 			}
-			_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false)
+			_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false, false)
 			if errs != nil && len(errs) > 0 {
 				t.Errorf("unexpected error: %v", errs)
 			}
@@ -1556,7 +1556,7 @@ func TestHelmState_DiffReleasesCleanup(t *testing.T) {
 `,
 			})
 			state = injectFs(state, testfs)
-			if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false); errs != nil && len(errs) > 0 {
+			if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false, false); errs != nil && len(errs) > 0 {
 				t.Errorf("unexpected errors: %v", errs)
 			}