修复:合并请求指派人员无法正常更新
This commit is contained in:
parent
3cbba6e36f
commit
89651b74ca
|
|
@ -98,7 +98,8 @@ func Routers(ctx gocontext.Context) *web.Route {
|
|||
repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.CompareDiff)
|
||||
m.Group("/pulls", func() {
|
||||
m.Group("/{index}", func() {
|
||||
m.Combo("").Get(repo.GetPullRequest)
|
||||
m.Combo("").Get(repo.GetPullRequest).
|
||||
Patch(bind(gitea_api.EditPullRequestOption{}), repo.EditPullRequest)
|
||||
m.Get("/commits", context.RepoRef(), repo.GetPullCommits)
|
||||
m.Get("/files", context.RepoRef(), repo.GetPullFiles)
|
||||
m.Group("/versions", func() {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,32 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
gitea_convert "code.gitea.io/gitea/modules/convert"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
gitea_api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
"code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/convert"
|
||||
hat_git "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/git"
|
||||
hat_pull_service "code.gitlink.org.cn/Gitlink/gitea_hat.git/services/pull"
|
||||
|
|
@ -28,6 +38,189 @@ func CreatePrVersion(ctx *context.APIContext) {
|
|||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func EditPullRequest(ctx *context.APIContext) {
|
||||
form := web.GetForm(ctx).(*gitea_api.EditPullRequestOption)
|
||||
pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if issues_model.IsErrPullRequestNotExist(err) {
|
||||
ctx.NotFound()
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
err = pr.LoadIssue()
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
|
||||
return
|
||||
}
|
||||
issue := pr.Issue
|
||||
issue.Repo = ctx.Repo.Repository
|
||||
|
||||
if err := issue.LoadAttributes(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWrite(unit.TypePullRequests) {
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
oldTitle := issue.Title
|
||||
if len(form.Title) > 0 {
|
||||
issue.Title = form.Title
|
||||
}
|
||||
if len(form.Body) > 0 {
|
||||
issue.Content = form.Body
|
||||
}
|
||||
|
||||
// Update or remove deadline if set
|
||||
if form.Deadline != nil || form.RemoveDeadline != nil {
|
||||
var deadlineUnix timeutil.TimeStamp
|
||||
if (form.RemoveDeadline == nil || !*form.RemoveDeadline) && !form.Deadline.IsZero() {
|
||||
deadline := time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
|
||||
23, 59, 59, 0, form.Deadline.Location())
|
||||
deadlineUnix = timeutil.TimeStamp(deadline.Unix())
|
||||
}
|
||||
|
||||
if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err)
|
||||
return
|
||||
}
|
||||
issue.DeadlineUnix = deadlineUnix
|
||||
}
|
||||
|
||||
// Add/delete assignees
|
||||
|
||||
// Deleting is done the GitHub way (quote from their api documentation):
|
||||
// https://developer.github.com/v3/issues/#edit-an-issue
|
||||
// "assignees" (array): Logins for Users to assign to this issue.
|
||||
// Pass one or more user logins to replace the set of assignees on this Issue.
|
||||
// Send an empty array ([]) to clear all assignees from the Issue.
|
||||
|
||||
if ctx.Repo.CanWrite(unit.TypePullRequests) && (form.Assignees != nil || len(form.Assignee) > 0) {
|
||||
err = issue_service.UpdateAssignees(issue, form.Assignee, form.Assignees, ctx.Doer)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Repo.CanWrite(unit.TypePullRequests) && form.Milestone != 0 &&
|
||||
issue.MilestoneID != form.Milestone {
|
||||
oldMilestoneID := issue.MilestoneID
|
||||
issue.MilestoneID = form.Milestone
|
||||
if err = issue_service.ChangeMilestoneAssign(issue, ctx.Doer, oldMilestoneID); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Repo.CanWrite(unit.TypePullRequests) && form.Labels != nil {
|
||||
labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDsError", err)
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Repo.Owner.IsOrganization() {
|
||||
orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err)
|
||||
return
|
||||
}
|
||||
|
||||
labels = append(labels, orgLabels...)
|
||||
}
|
||||
|
||||
if err = issues_model.ReplaceIssueLabels(issue, labels, ctx.Doer); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "ReplaceLabelsError", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if form.State != nil {
|
||||
if pr.HasMerged {
|
||||
ctx.Error(http.StatusPreconditionFailed, "MergedPRState", "cannot change state of this pull request, it was already merged")
|
||||
return
|
||||
}
|
||||
issue.IsClosed = gitea_api.StateClosed == gitea_api.StateType(*form.State)
|
||||
}
|
||||
statusChangeComment, titleChanged, err := issues_model.UpdateIssueByAPI(issue, ctx.Doer)
|
||||
if err != nil {
|
||||
if issues_model.IsErrDependenciesLeft(err) {
|
||||
ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies")
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateIssueByAPI", err)
|
||||
return
|
||||
}
|
||||
|
||||
if titleChanged {
|
||||
notification.NotifyIssueChangeTitle(ctx.Doer, issue, oldTitle)
|
||||
}
|
||||
|
||||
if statusChangeComment != nil {
|
||||
notification.NotifyIssueChangeStatus(ctx.Doer, issue, statusChangeComment, issue.IsClosed)
|
||||
}
|
||||
|
||||
// change pull target branch
|
||||
if !pr.HasMerged && len(form.Base) != 0 && form.Base != pr.BaseBranch {
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(form.Base) {
|
||||
ctx.Error(http.StatusNotFound, "NewBaseBranchNotExist", fmt.Errorf("new base '%s' not exist", form.Base))
|
||||
return
|
||||
}
|
||||
if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, form.Base); err != nil {
|
||||
if issues_model.IsErrPullRequestAlreadyExists(err) {
|
||||
ctx.Error(http.StatusConflict, "IsErrPullRequestAlreadyExists", err)
|
||||
return
|
||||
} else if issues_model.IsErrIssueIsClosed(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "IsErrIssueIsClosed", err)
|
||||
return
|
||||
} else if models.IsErrPullRequestHasMerged(err) {
|
||||
ctx.Error(http.StatusConflict, "IsErrPullRequestHasMerged", err)
|
||||
return
|
||||
} else {
|
||||
ctx.InternalServerError(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
notification.NotifyPullRequestChangeTargetBranch(ctx.Doer, pr, form.Base)
|
||||
}
|
||||
|
||||
// update allow edits
|
||||
if form.AllowMaintainerEdit != nil {
|
||||
if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, *form.AllowMaintainerEdit); err != nil {
|
||||
if errors.Is(pull_service.ErrUserHasNoPermissionForAction, err) {
|
||||
ctx.Error(http.StatusForbidden, "SetAllowEdits", fmt.Sprintf("SetAllowEdits: %s", err))
|
||||
return
|
||||
}
|
||||
ctx.ServerError("SetAllowEdits", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Refetch from database
|
||||
pr, err = issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pr.Index)
|
||||
if err != nil {
|
||||
if issues_model.IsErrPullRequestNotExist(err) {
|
||||
ctx.NotFound()
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TODO this should be 200, not 201
|
||||
ctx.JSON(http.StatusCreated, gitea_convert.ToAPIPullRequest(ctx, pr, ctx.Doer))
|
||||
}
|
||||
|
||||
func GetPullRequest(ctx *context.APIContext) {
|
||||
pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package issue
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
gitea_issue_service "code.gitea.io/gitea/services/issue"
|
||||
)
|
||||
|
||||
func UpdateAssignees(issue *issues_model.Issue, oneAssignee string, multipleAssignees []string, doer *user_model.User) (err error) {
|
||||
var allNewAssignees []*user_model.User
|
||||
// Keep the old assignee thingy for compatibility reasons
|
||||
if oneAssignee != "" {
|
||||
// Prevent double adding assignees
|
||||
var isDouble bool
|
||||
for _, assignee := range multipleAssignees {
|
||||
if assignee == oneAssignee {
|
||||
isDouble = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isDouble {
|
||||
multipleAssignees = append(multipleAssignees, oneAssignee)
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all assignees to add them
|
||||
for _, assigneeName := range multipleAssignees {
|
||||
assignee, err := user_model.GetUserByName(db.DefaultContext, assigneeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
allNewAssignees = append(allNewAssignees, assignee)
|
||||
}
|
||||
|
||||
// Delete all old assignees not passed
|
||||
if err = gitea_issue_service.DeleteNotPassedAssignee(issue, doer, allNewAssignees); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add all new assignees
|
||||
// Update the assignee. The function will check if the user exists, is already
|
||||
// assigned (which he shouldn't as we deleted all assignees before) and
|
||||
// has access to the repo.
|
||||
for _, assignee := range allNewAssignees {
|
||||
// Extra method to prevent double adding (which would result in removing)
|
||||
err = gitea_issue_service.AddAssigneeIfNotAssigned(issue, doer, assignee.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
Loading…
Reference in New Issue