Change target branch for pull request (#6488)

* Adds functionality to change target branch of created pull requests

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Use const instead of var in JavaScript additions

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Check if branches are equal and if PR already exists before changing target branch

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Make sure to check all commits

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Print error messages for user as error flash message

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Disallow changing target branch of closed or merged pull requests

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Resolve conflicts after merge of upstream/master

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Change order of branch select fields

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Removes duplicate check

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Use ctx.Tr for translations

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Recompile JS

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Use correct translation namespace

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Remove redundant if condition

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Moves most change branch logic into pull service

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Completes comment

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Add Ref to ChangesPayload for logging changed target branches
instead of creating a new struct

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Revert changes to go.mod

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Directly use createComment method

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Return 404 if pull request is not found. Move written check up

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Remove variable declaration

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Return client errors on change pull request target errors

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Return error in commit.HasPreviousCommit

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Adds blank line

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Test patch before persisting new target branch

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Update patch before testing (not working)

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Removes patch calls when changeing pull request target

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Removes unneeded check for base name

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Moves ChangeTargetBranch completely to pull service. Update patch status.

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Set webhook mode after errors were validated

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Update PR in one transaction

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Move logic for check if head is equal with branch to pull model

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Adds missing comment and simplify return

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>

* Adjust CreateComment method call

Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>
This commit is contained in:
Mario Lubenka 2019-12-16 07:20:25 +01:00 committed by Lunny Xiao
parent 59d6401486
commit 61db834904
19 changed files with 461 additions and 19 deletions

View file

@ -11,6 +11,7 @@ import (
"crypto/subtle"
"fmt"
"html"
"net/http"
"path"
"strings"
@ -467,6 +468,7 @@ func ViewPullCommits(ctx *context.Context) {
ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = commits.Len()
getBranchData(ctx, issue)
ctx.HTML(200, tplPullCommits)
}
@ -596,6 +598,7 @@ func ViewPullFiles(ctx *context.Context) {
ctx.ServerError("GetCurrentReview", err)
return
}
getBranchData(ctx, issue)
ctx.HTML(200, tplPullFiles)
}
@ -1010,3 +1013,74 @@ func DownloadPullDiffOrPatch(ctx *context.Context, patch bool) {
return
}
}
// UpdatePullRequestTarget change pull request's target branch
func UpdatePullRequestTarget(ctx *context.Context) {
issue := GetActionIssue(ctx)
pr := issue.PullRequest
if ctx.Written() {
return
}
if !issue.IsPull {
ctx.Error(http.StatusNotFound)
return
}
if !ctx.IsSigned || (!issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) {
ctx.Error(http.StatusForbidden)
return
}
targetBranch := ctx.QueryTrim("target_branch")
if len(targetBranch) == 0 {
ctx.Error(http.StatusNoContent)
return
}
if err := pull_service.ChangeTargetBranch(pr, ctx.User, targetBranch); err != nil {
if models.IsErrPullRequestAlreadyExists(err) {
err := err.(models.ErrPullRequestAlreadyExists)
RepoRelPath := ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
errorMessage := ctx.Tr("repo.pulls.has_pull_request", ctx.Repo.RepoLink, RepoRelPath, err.IssueID)
ctx.Flash.Error(errorMessage)
ctx.JSON(http.StatusConflict, map[string]interface{}{
"error": err.Error(),
"user_error": errorMessage,
})
} else if models.IsErrIssueIsClosed(err) {
errorMessage := ctx.Tr("repo.pulls.is_closed")
ctx.Flash.Error(errorMessage)
ctx.JSON(http.StatusConflict, map[string]interface{}{
"error": err.Error(),
"user_error": errorMessage,
})
} else if models.IsErrPullRequestHasMerged(err) {
errorMessage := ctx.Tr("repo.pulls.has_merged")
ctx.Flash.Error(errorMessage)
ctx.JSON(http.StatusConflict, map[string]interface{}{
"error": err.Error(),
"user_error": errorMessage,
})
} else if models.IsErrBranchesEqual(err) {
errorMessage := ctx.Tr("repo.pulls.nothing_to_compare")
ctx.Flash.Error(errorMessage)
ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"error": err.Error(),
"user_error": errorMessage,
})
} else {
ctx.ServerError("UpdatePullRequestTarget", err)
}
return
}
notification.NotifyPullRequestChangeTargetBranch(ctx.User, pr, targetBranch)
ctx.JSON(http.StatusOK, map[string]interface{}{
"base_branch": pr.BaseBranch,
})
}