mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Add API to update pr headBranch (#12419)
* [API] Add update pr headBranch api Signed-off-by: a1012112796 <1012112796@qq.com>
This commit is contained in:
		| @@ -5,7 +5,7 @@ | |||||||
| package integrations | package integrations | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -19,7 +19,7 @@ import ( | |||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestPullUpdate(t *testing.T) { | func TestAPIPullUpdate(t *testing.T) { | ||||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||||
| 		//Create PR to test | 		//Create PR to test | ||||||
| 		user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | 		user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | ||||||
| @@ -31,17 +31,19 @@ func TestPullUpdate(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.EqualValues(t, 1, diffCount.Behind) | 		assert.EqualValues(t, 1, diffCount.Behind) | ||||||
| 		assert.EqualValues(t, 1, diffCount.Ahead) | 		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) | 		session := loginUser(t, "user2") | ||||||
| 		err = pull_service.Update(pr, user, message) | 		token := getTokenForLoggedInUser(t, session) | ||||||
| 		assert.NoError(t, err) | 		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 | 		//Test GetDiverging after update | ||||||
| 		diffCount, err = pull_service.GetDiverging(pr) | 		diffCount, err = pull_service.GetDiverging(pr) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.EqualValues(t, 0, diffCount.Behind) | 		assert.EqualValues(t, 0, diffCount.Behind) | ||||||
| 		assert.EqualValues(t, 2, diffCount.Ahead) | 		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) | 							Patch(reqToken(), reqRepoWriter(models.UnitTypePullRequests), bind(api.EditPullRequestOption{}), repo.EditPullRequest) | ||||||
| 						m.Get(".diff", repo.DownloadPullDiff) | 						m.Get(".diff", repo.DownloadPullDiff) | ||||||
| 						m.Get(".patch", repo.DownloadPullPatch) | 						m.Get(".patch", repo.DownloadPullPatch) | ||||||
|  | 						m.Post("/update", reqToken(), repo.UpdatePullRequest) | ||||||
| 						m.Combo("/merge").Get(repo.IsPullRequestMerged). | 						m.Combo("/merge").Get(repo.IsPullRequestMerged). | ||||||
| 							Post(reqToken(), mustNotBeArchived, bind(auth.MergePullRequestForm{}), repo.MergePullRequest) | 							Post(reqToken(), mustNotBeArchived, bind(auth.MergePullRequestForm{}), repo.MergePullRequest) | ||||||
| 						m.Group("/reviews", func() { | 						m.Group("/reviews", func() { | ||||||
|   | |||||||
| @@ -968,3 +968,99 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) | |||||||
|  |  | ||||||
| 	return headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch | 	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) | 	ctx.HTML(200, tplPullFiles) | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdatePullRequest merge master into PR | // UpdatePullRequest merge PR's baseBranch into headBranch | ||||||
| func UpdatePullRequest(ctx *context.Context) { | func UpdatePullRequest(ctx *context.Context) { | ||||||
| 	issue := checkPullInfo(ctx) | 	issue := checkPullInfo(ctx) | ||||||
| 	if ctx.Written() { | 	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}": { |     "/repos/{owner}/{repo}/raw/{filepath}": { | ||||||
|       "get": { |       "get": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user