* [API] Add update pr headBranch api Signed-off-by: a1012112796 <1012112796@qq.com>tags/v1.13.0-rc1
@@ -5,7 +5,7 @@ | |||
package integrations | |||
import ( | |||
"fmt" | |||
"net/http" | |||
"net/url" | |||
"testing" | |||
"time" | |||
@@ -19,7 +19,7 @@ import ( | |||
"github.com/stretchr/testify/assert" | |||
) | |||
func TestPullUpdate(t *testing.T) { | |||
func TestAPIPullUpdate(t *testing.T) { | |||
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | |||
//Create PR to test | |||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | |||
@@ -31,17 +31,19 @@ func TestPullUpdate(t *testing.T) { | |||
assert.NoError(t, err) | |||
assert.EqualValues(t, 1, diffCount.Behind) | |||
assert.EqualValues(t, 1, diffCount.Ahead) | |||
assert.NoError(t, pr.LoadBaseRepo()) | |||
assert.NoError(t, pr.LoadIssue()) | |||
message := fmt.Sprintf("Merge branch '%s' into %s", pr.BaseBranch, pr.HeadBranch) | |||
err = pull_service.Update(pr, user, message) | |||
assert.NoError(t, err) | |||
session := loginUser(t, "user2") | |||
token := getTokenForLoggedInUser(t, session) | |||
req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?token="+token, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index) | |||
session.MakeRequest(t, req, http.StatusOK) | |||
//Test GetDiverging after update | |||
diffCount, err = pull_service.GetDiverging(pr) | |||
assert.NoError(t, err) | |||
assert.EqualValues(t, 0, diffCount.Behind) | |||
assert.EqualValues(t, 2, diffCount.Ahead) | |||
}) | |||
} | |||
@@ -806,6 +806,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
Patch(reqToken(), reqRepoWriter(models.UnitTypePullRequests), bind(api.EditPullRequestOption{}), repo.EditPullRequest) | |||
m.Get(".diff", repo.DownloadPullDiff) | |||
m.Get(".patch", repo.DownloadPullPatch) | |||
m.Post("/update", reqToken(), repo.UpdatePullRequest) | |||
m.Combo("/merge").Get(repo.IsPullRequestMerged). | |||
Post(reqToken(), mustNotBeArchived, bind(auth.MergePullRequestForm{}), repo.MergePullRequest) | |||
m.Group("/reviews", func() { | |||
@@ -968,3 +968,99 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) | |||
return headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch | |||
} | |||
// UpdatePullRequest merge PR's baseBranch into headBranch | |||
func UpdatePullRequest(ctx *context.APIContext) { | |||
// swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/update repository repoUpdatePullRequest | |||
// --- | |||
// summary: Merge PR's baseBranch into headBranch | |||
// produces: | |||
// - application/json | |||
// parameters: | |||
// - name: owner | |||
// in: path | |||
// description: owner of the repo | |||
// type: string | |||
// required: true | |||
// - name: repo | |||
// in: path | |||
// description: name of the repo | |||
// type: string | |||
// required: true | |||
// - name: index | |||
// in: path | |||
// description: index of the pull request to get | |||
// type: integer | |||
// format: int64 | |||
// required: true | |||
// responses: | |||
// "200": | |||
// "$ref": "#/responses/empty" | |||
// "403": | |||
// "$ref": "#/responses/forbidden" | |||
// "404": | |||
// "$ref": "#/responses/notFound" | |||
// "409": | |||
// "$ref": "#/responses/error" | |||
// "422": | |||
// "$ref": "#/responses/validationError" | |||
pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) | |||
if err != nil { | |||
if models.IsErrPullRequestNotExist(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) | |||
} | |||
return | |||
} | |||
if pr.HasMerged { | |||
ctx.Error(http.StatusUnprocessableEntity, "UpdatePullRequest", err) | |||
return | |||
} | |||
if err = pr.LoadIssue(); err != nil { | |||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err) | |||
return | |||
} | |||
if pr.Issue.IsClosed { | |||
ctx.Error(http.StatusUnprocessableEntity, "UpdatePullRequest", err) | |||
return | |||
} | |||
if err = pr.LoadBaseRepo(); err != nil { | |||
ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) | |||
return | |||
} | |||
if err = pr.LoadHeadRepo(); err != nil { | |||
ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) | |||
return | |||
} | |||
allowedUpdate, err := pull_service.IsUserAllowedToUpdate(pr, ctx.User) | |||
if err != nil { | |||
ctx.Error(http.StatusInternalServerError, "IsUserAllowedToMerge", err) | |||
return | |||
} | |||
if !allowedUpdate { | |||
ctx.Status(http.StatusForbidden) | |||
return | |||
} | |||
// default merge commit message | |||
message := fmt.Sprintf("Merge branch '%s' into %s", pr.BaseBranch, pr.HeadBranch) | |||
if err = pull_service.Update(pr, ctx.User, message); err != nil { | |||
if models.IsErrMergeConflicts(err) { | |||
ctx.Error(http.StatusConflict, "Update", "merge failed because of conflict") | |||
return | |||
} | |||
ctx.Error(http.StatusInternalServerError, "pull_service.Update", err) | |||
return | |||
} | |||
ctx.Status(http.StatusOK) | |||
} |
@@ -666,7 +666,7 @@ func ViewPullFiles(ctx *context.Context) { | |||
ctx.HTML(200, tplPullFiles) | |||
} | |||
// UpdatePullRequest merge master into PR | |||
// UpdatePullRequest merge PR's baseBranch into headBranch | |||
func UpdatePullRequest(ctx *context.Context) { | |||
issue := checkPullInfo(ctx) | |||
if ctx.Written() { | |||
@@ -7285,6 +7285,59 @@ | |||
} | |||
} | |||
}, | |||
"/repos/{owner}/{repo}/pulls/{index}/update": { | |||
"post": { | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"repository" | |||
], | |||
"summary": "Merge PR's baseBranch into headBranch", | |||
"operationId": "repoUpdatePullRequest", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "owner of the repo", | |||
"name": "owner", | |||
"in": "path", | |||
"required": true | |||
}, | |||
{ | |||
"type": "string", | |||
"description": "name of the repo", | |||
"name": "repo", | |||
"in": "path", | |||
"required": true | |||
}, | |||
{ | |||
"type": "integer", | |||
"format": "int64", | |||
"description": "index of the pull request to get", | |||
"name": "index", | |||
"in": "path", | |||
"required": true | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"$ref": "#/responses/empty" | |||
}, | |||
"403": { | |||
"$ref": "#/responses/forbidden" | |||
}, | |||
"404": { | |||
"$ref": "#/responses/notFound" | |||
}, | |||
"409": { | |||
"$ref": "#/responses/error" | |||
}, | |||
"422": { | |||
"$ref": "#/responses/validationError" | |||
} | |||
} | |||
} | |||
}, | |||
"/repos/{owner}/{repo}/raw/{filepath}": { | |||
"get": { | |||
"produces": [ | |||