--- /dev/null
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package integrations
+
+import (
+ "net/http"
+ "testing"
+
+ "code.gitea.io/gitea/models"
+ api "code.gitea.io/gitea/modules/structs"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAPIPullCommits(t *testing.T) {
+ defer prepareTestEnv(t)()
+ pullIssue := models.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest)
+ assert.NoError(t, pullIssue.LoadIssue())
+ repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: pullIssue.HeadRepoID}).(*models.Repository)
+
+ session := loginUser(t, "user2")
+ req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/commits", repo.OwnerName, repo.Name, pullIssue.Index)
+ resp := session.MakeRequest(t, req, http.StatusOK)
+
+ var commits []*api.Commit
+ DecodeJSON(t, resp, &commits)
+
+ if !assert.Len(t, commits, 2) {
+ return
+ }
+
+ assert.Equal(t, "5f22f7d0d95d614d25a5b68592adb345a4b5c7fd", commits[0].SHA)
+ assert.Equal(t, "4a357436d925b5c974181ff12a994538ddc5a269", commits[1].SHA)
+}
+
+// TODO add tests for already merged PR and closed PR
import (
"fmt"
+ "math"
"net/http"
+ "strconv"
"strings"
"time"
ctx.Status(http.StatusOK)
}
+
+// GetPullRequestCommits gets all commits associated with a given PR
+func GetPullRequestCommits(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/pulls/{index}/commits repository repoGetPullRequestCommits
+ // ---
+ // summary: Get commits for a pull request
+ // 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
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/CommitList"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ 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 err := pr.LoadBaseRepo(); err != nil {
+ ctx.InternalServerError(err)
+ return
+ }
+
+ var prInfo *git.CompareInfo
+ baseGitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
+ if err != nil {
+ ctx.ServerError("OpenRepository", err)
+ return
+ }
+ defer baseGitRepo.Close()
+ if pr.HasMerged {
+ prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName())
+ } else {
+ prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName())
+ }
+ if err != nil {
+ ctx.ServerError("GetCompareInfo", err)
+ return
+ }
+ commits := prInfo.Commits
+
+ listOptions := utils.GetListOptions(ctx)
+
+ totalNumberOfCommits := commits.Len()
+ totalNumberOfPages := int(math.Ceil(float64(totalNumberOfCommits) / float64(listOptions.PageSize)))
+
+ userCache := make(map[string]*models.User)
+
+ start, end := listOptions.GetStartEnd()
+
+ if end > totalNumberOfCommits {
+ end = totalNumberOfCommits
+ }
+
+ apiCommits := make([]*api.Commit, end-start)
+
+ i := 0
+ addedCommitsCount := 0
+ for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
+ if i < start {
+ i++
+ continue
+ }
+ if i >= end {
+ break
+ }
+
+ commit := commitPointer.Value.(*git.Commit)
+
+ // Create json struct
+ apiCommits[addedCommitsCount], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache)
+ addedCommitsCount++
+ if err != nil {
+ ctx.ServerError("toCommit", err)
+ return
+ }
+ i++
+ }
+
+ ctx.SetLinkHeader(int(totalNumberOfCommits), listOptions.PageSize)
+
+ ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page))
+ ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize))
+ ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", totalNumberOfCommits))
+ ctx.Header().Set("X-PageCount", strconv.Itoa(totalNumberOfPages))
+ ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < totalNumberOfPages))
+ ctx.JSON(http.StatusOK, &apiCommits)
+}
}
}
},
+ "/repos/{owner}/{repo}/pulls/{index}/commits": {
+ "get": {
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "repository"
+ ],
+ "summary": "Get commits for a pull request",
+ "operationId": "repoGetPullRequestCommits",
+ "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
+ },
+ {
+ "type": "integer",
+ "description": "page number of results to return (1-based)",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "page size of results",
+ "name": "limit",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/CommitList"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
"/repos/{owner}/{repo}/pulls/{index}/merge": {
"get": {
"produces": [