From 4a20eadfd7ecc1e71a02f5c96d6f92d9818b0a28 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Tue, 18 Jan 2022 23:26:42 +0000
Subject: [PATCH] Restore propagation of ErrDependenciesLeft (#18325)

Unfortunately #17643 prevented all propagation of ErrDependenciesLeft meaning
that dependency errors that prevent closing of issues get swallowed.

This PR restores propagation of the error but instead swallows the error in the
places where it needs to be swallowed.

Fix #18223

Signed-off-by: Andrew Thornton <art27@cantab.net>
---
 services/issue/status.go | 8 ++++----
 services/pull/merge.go   | 5 ++++-
 services/pull/pull.go    | 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/services/issue/status.go b/services/issue/status.go
index 5b8d21274d..64fbccd26a 100644
--- a/services/issue/status.go
+++ b/services/issue/status.go
@@ -8,6 +8,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/models/db"
 	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/notification"
 )
 
@@ -15,10 +16,9 @@ import (
 func ChangeStatus(issue *models.Issue, doer *user_model.User, closed bool) error {
 	comment, err := issue.ChangeStatus(doer, closed)
 	if err != nil {
-		// Don't return an error when dependencies are open as this would let the push fail
-		if models.IsErrDependenciesLeft(err) {
-			if closed {
-				return models.FinishIssueStopwatchIfPossible(db.DefaultContext, doer, issue)
+		if models.IsErrDependenciesLeft(err) && closed {
+			if err := models.FinishIssueStopwatchIfPossible(db.DefaultContext, doer, issue); err != nil {
+				log.Error("Unable to stop stopwatch for issue[%d]#%d: %v", issue.ID, issue.Index, err)
 			}
 		}
 		return err
diff --git a/services/pull/merge.go b/services/pull/merge.go
index 34cab2fd71..f6a6415bff 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -105,7 +105,10 @@ func Merge(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repos
 		close := ref.RefAction == references.XRefActionCloses
 		if close != ref.Issue.IsClosed {
 			if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil {
-				return err
+				// Allow ErrDependenciesLeft
+				if !models.IsErrDependenciesLeft(err) {
+					return err
+				}
 			}
 		}
 	}
diff --git a/services/pull/pull.go b/services/pull/pull.go
index c1844372ea..db3533ebe4 100644
--- a/services/pull/pull.go
+++ b/services/pull/pull.go
@@ -514,7 +514,7 @@ func CloseBranchPulls(doer *user_model.User, repoID int64, branch string) error
 
 	var errs errlist
 	for _, pr := range prs {
-		if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrPullWasClosed(err) {
+		if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrPullWasClosed(err) && !models.IsErrDependenciesLeft(err) {
 			errs = append(errs, err)
 		}
 	}