diff --git a/pkg/app/app.go b/pkg/app/app.go index a3947c35..0658667f 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -148,7 +148,13 @@ func (a *App) Diff(c DiffConfigProvider) error { if len(deferredErrs) > 0 { // We take the first release error w/ exit status 2 (although all the defered errs should have exit status 2) // to just let helmfile itself to exit with 2 - return deferredErrs[0] + // See https://github.com/roboll/helmfile/issues/749 + code := 2 + e := &Error{ + msg: "Identified at least on change", + code: &code, + } + return e } return nil @@ -1299,7 +1305,7 @@ func (e *Error) Code() int { panic(fmt.Sprintf("[bug] assertion error: unexpected state: unable to handle errors: %v", e.Errors)) } -func appError(msg string, err error) error { +func appError(msg string, err error) *Error { return &Error{msg: msg, Errors: []error{err}} } diff --git a/pkg/app/run.go b/pkg/app/run.go index 2ce267d8..3cc03fb6 100644 --- a/pkg/app/run.go +++ b/pkg/app/run.go @@ -86,6 +86,7 @@ func (r *Run) Diff(c DiffConfigProvider) []error { Set: c.Set(), } _, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.SuppressSecrets(), c.SuppressDiff(), true, opts) + return errs } diff --git a/pkg/state/release_error.go b/pkg/state/release_error.go index 3cf849a7..8a0f3815 100644 --- a/pkg/state/release_error.go +++ b/pkg/state/release_error.go @@ -13,9 +13,19 @@ type ReleaseError struct { } func (e *ReleaseError) Error() string { - return fmt.Sprintf("failed processing release %s: %v", e.Name, e.err.Error()) + return e.err.Error() } -func newReleaseError(release *ReleaseSpec, err error) *ReleaseError { - return &ReleaseError{release, err, ReleaseErrorCodeFailure} +func NewReleaseError(release *ReleaseSpec, err error, code int) *ReleaseError { + return &ReleaseError{ + ReleaseSpec: release, + err: err, + Code: code, + } +} + +func newReleaseFailedError(release *ReleaseSpec, err error) *ReleaseError { + wrappedErr := fmt.Errorf("failed processing release %s: %v", release.Name, err.Error()) + + return NewReleaseError(release, wrappedErr, ReleaseErrorCodeFailure) } diff --git a/pkg/state/state.go b/pkg/state/state.go index 7220d5b4..184bd0b5 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -330,7 +330,7 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu flags, flagsErr := st.flagsForUpgrade(helm, release, workerIndex) mut.Unlock() if flagsErr != nil { - results <- syncPrepareResult{errors: []*ReleaseError{newReleaseError(release, flagsErr)}} + results <- syncPrepareResult{errors: []*ReleaseError{newReleaseFailedError(release, flagsErr)}} continue } @@ -338,14 +338,14 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu for _, value := range additionalValues { valfile, err := filepath.Abs(value) if err != nil { - errs = append(errs, newReleaseError(release, err)) + errs = append(errs, newReleaseFailedError(release, err)) } ok, err := st.fileExists(valfile) if err != nil { - errs = append(errs, newReleaseError(release, err)) + errs = append(errs, newReleaseFailedError(release, err)) } else if !ok { - errs = append(errs, newReleaseError(release, fmt.Errorf("file does not exist: %s", valfile))) + errs = append(errs, newReleaseFailedError(release, fmt.Errorf("file does not exist: %s", valfile))) } flags = append(flags, "--values", valfile) } @@ -484,7 +484,7 @@ func (st *HelmState) DeleteReleasesForSync(affectedReleases *AffectedReleases, h context := st.createHelmContext(release, workerIndex) if _, err := st.triggerPresyncEvent(release, "sync"); err != nil { - relErr = newReleaseError(release, err) + relErr = newReleaseFailedError(release, err) } else { var args []string if helm.IsHelm3() { @@ -499,7 +499,7 @@ func (st *HelmState) DeleteReleasesForSync(affectedReleases *AffectedReleases, h m.Lock() if err := helm.DeleteRelease(context, release.Name, deletionFlags...); err != nil { affectedReleases.Failed = append(affectedReleases.Failed, release) - relErr = newReleaseError(release, err) + relErr = newReleaseFailedError(release, err) } else { affectedReleases.Deleted = append(affectedReleases.Deleted, release) } @@ -580,11 +580,11 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme context := st.createHelmContext(release, workerIndex) if _, err := st.triggerPresyncEvent(release, "sync"); err != nil { - relErr = newReleaseError(release, err) + relErr = newReleaseFailedError(release, err) } else if !release.Desired() { installed, err := st.isReleaseInstalled(context, helm, *release) if err != nil { - relErr = newReleaseError(release, err) + relErr = newReleaseFailedError(release, err) } else if installed { var args []string if helm.IsHelm3() { @@ -596,7 +596,7 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme m.Lock() if err := helm.DeleteRelease(context, release.Name, deletionFlags...); err != nil { affectedReleases.Failed = append(affectedReleases.Failed, release) - relErr = newReleaseError(release, err) + relErr = newReleaseFailedError(release, err) } else { affectedReleases.Deleted = append(affectedReleases.Deleted, release) } @@ -606,7 +606,7 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme m.Lock() affectedReleases.Failed = append(affectedReleases.Failed, release) m.Unlock() - relErr = newReleaseError(release, err) + relErr = newReleaseFailedError(release, err) } else { m.Lock() affectedReleases.Upgraded = append(affectedReleases.Upgraded, release) @@ -1035,7 +1035,7 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu if len(errs) > 0 { rsErrs := make([]*ReleaseError, len(errs)) for i, e := range errs { - rsErrs[i] = newReleaseError(release, e) + rsErrs[i] = newReleaseFailedError(release, e) } results <- diffPrepareResult{errors: rsErrs} } else { @@ -1344,7 +1344,7 @@ func (st *HelmState) PrepareReleases(helm helmexec.Interface, helmfileCommand st release := st.Releases[i] if _, err := st.triggerPrepareEvent(&release, helmfileCommand); err != nil { - errs = append(errs, newReleaseError(&release, err)) + errs = append(errs, newReleaseFailedError(&release, err)) continue } }