From adc1ce082c144e0966b010d1dbcb1c0bf2080481 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sun, 18 Feb 2024 15:52:42 +0100 Subject: [PATCH 1/5] Add API to get merged PR of a commit --- models/issues/pull.go | 24 ++++++++++++++++ routers/api/v1/api.go | 1 + routers/api/v1/repo/commits.go | 51 ++++++++++++++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 43 ++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/models/issues/pull.go b/models/issues/pull.go index 2cb1e1b971e9c..980a296da4699 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -1093,3 +1093,27 @@ func InsertPullRequests(ctx context.Context, prs ...*PullRequest) error { } return committer.Commit() } + +// GetPullRequestByMergedCommit returns a merged pull request by the given commit +func GetPullRequestByMergedCommit(ctx context.Context, repoID int64, sha string) (*PullRequest, error) { + pr := &PullRequest{ + BaseRepoID: repoID, + MergedCommitID: sha, + } + + has, err := db.GetEngine(ctx).Get(pr) + if err != nil { + return nil, err + } else if !has { + return nil, ErrPullRequestNotExist{0, 0, 0, repoID, "", ""} + } + + if err = pr.LoadAttributes(ctx); err != nil { + return nil, err + } + if err = pr.LoadIssue(ctx); err != nil { + return nil, err + } + + return pr, nil +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 3fafb96b8ed82..e7bdef1489c6d 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1235,6 +1235,7 @@ func Routes() *web.Route { m.Group("/{ref}", func() { m.Get("/status", repo.GetCombinedCommitStatusByRef) m.Get("/statuses", repo.GetCommitStatusesByRef) + m.Get("/pull", repo.GetCommitPullRequest) }, context.ReferencesGitRepo()) }, reqRepoReader(unit.TypeCode)) m.Group("/git", func() { diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 43b6400009875..883ae9813d791 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -10,6 +10,7 @@ import ( "net/http" "strconv" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -323,3 +324,53 @@ func DownloadCommitDiffOrPatch(ctx *context.APIContext) { return } } + +// GetPullRequest returns the pull request of the commit +func GetCommitPullRequest(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/commits/{sha}/pull repository repoGetCommitPullRequest + // --- + // summary: Get the pull request of the commit + // 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: sha + // in: path + // description: SHA of the commit to get + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/PullRequest" + // "404": + // "$ref": "#/responses/notFound" + + pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.Params(":sha")) + if err != nil { + if issues_model.IsErrPullRequestNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + } + return + } + + if err = pr.LoadBaseRepo(ctx); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) + return + } + if err = pr.LoadHeadRepo(ctx); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + return + } + ctx.JSON(http.StatusOK, convert.ToAPIPullRequest(ctx, pr, ctx.Doer)) +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index d26bed53aaee7..eaa1448b2bb36 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -4565,6 +4565,49 @@ } } }, + "/repos/{owner}/{repo}/commits/{sha}/pull": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Get the pull request of the commit", + "operationId": "repoGetCommitPullRequest", + "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": "string", + "description": "SHA of the commit to get", + "name": "sha", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullRequest" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, "/repos/{owner}/{repo}/contents": { "get": { "produces": [ From d474dfbced4a7787807341fd96e0198bbaf3b25d Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Sun, 18 Feb 2024 15:58:52 +0100 Subject: [PATCH 2/5] make fmt --- models/issues/pull.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issues/pull.go b/models/issues/pull.go index 980a296da4699..7d1fb2958981a 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -1097,7 +1097,7 @@ func InsertPullRequests(ctx context.Context, prs ...*PullRequest) error { // GetPullRequestByMergedCommit returns a merged pull request by the given commit func GetPullRequestByMergedCommit(ctx context.Context, repoID int64, sha string) (*PullRequest, error) { pr := &PullRequest{ - BaseRepoID: repoID, + BaseRepoID: repoID, MergedCommitID: sha, } From 00be5d2cec1f814f7aebbf140f2035833739b952 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Thu, 22 Feb 2024 20:24:00 +0100 Subject: [PATCH 3/5] Use `Where` --- models/issues/pull.go | 3 +-- routers/api/v1/repo/commits.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/models/issues/pull.go b/models/issues/pull.go index 7d1fb2958981a..3cd4e5f41d86c 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -1098,10 +1098,9 @@ func InsertPullRequests(ctx context.Context, prs ...*PullRequest) error { func GetPullRequestByMergedCommit(ctx context.Context, repoID int64, sha string) (*PullRequest, error) { pr := &PullRequest{ BaseRepoID: repoID, - MergedCommitID: sha, } - has, err := db.GetEngine(ctx).Get(pr) + has, err := db.GetEngine(ctx).Where("merged_commit_id = ?", sha).Get(pr) if err != nil { return nil, err } else if !has { diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 883ae9813d791..80e55d58e0fdc 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -325,7 +325,7 @@ func DownloadCommitDiffOrPatch(ctx *context.APIContext) { } } -// GetPullRequest returns the pull request of the commit +// GetCommitPullRequest returns the pull request of the commit func GetCommitPullRequest(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/commits/{sha}/pull repository repoGetCommitPullRequest // --- From df0ecd37fde9bc14a6358c3a6dd5f08de3c21f00 Mon Sep 17 00:00:00 2001 From: qwerty287 <80460567+qwerty287@users.noreply.github.com> Date: Thu, 22 Feb 2024 20:24:20 +0100 Subject: [PATCH 4/5] Update routers/api/v1/repo/commits.go Co-authored-by: 6543 <6543@obermui.de> --- routers/api/v1/repo/commits.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 80e55d58e0fdc..d01cf6b8bcdfd 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -357,7 +357,7 @@ func GetCommitPullRequest(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.Params(":sha")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.Error(http.StatusNotFound, "GetPullRequestByMergedCommit", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) } From f86b8e5436498f6adafd9df139d84cf735e0dda9 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 22 Feb 2024 20:47:15 +0100 Subject: [PATCH 5/5] add unittest --- models/fixtures/pull_request.yml | 1 + models/issues/pull.go | 7 ++----- models/issues/pull_test.go | 12 ++++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/models/fixtures/pull_request.yml b/models/fixtures/pull_request.yml index 560674c370b81..54590fb830f90 100644 --- a/models/fixtures/pull_request.yml +++ b/models/fixtures/pull_request.yml @@ -9,6 +9,7 @@ head_branch: branch1 base_branch: master merge_base: 4a357436d925b5c974181ff12a994538ddc5a269 + merged_commit_id: 1a8823cd1a9549fde083f992f6b9b87a7ab74fb3 has_merged: true merger_id: 2 diff --git a/models/issues/pull.go b/models/issues/pull.go index 3cd4e5f41d86c..18e6b2776d3d1 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -1096,11 +1096,8 @@ func InsertPullRequests(ctx context.Context, prs ...*PullRequest) error { // GetPullRequestByMergedCommit returns a merged pull request by the given commit func GetPullRequestByMergedCommit(ctx context.Context, repoID int64, sha string) (*PullRequest, error) { - pr := &PullRequest{ - BaseRepoID: repoID, - } - - has, err := db.GetEngine(ctx).Where("merged_commit_id = ?", sha).Get(pr) + pr := new(PullRequest) + has, err := db.GetEngine(ctx).Where("base_repo_id = ? AND merged_commit_id = ?", repoID, sha).Get(pr) if err != nil { return nil, err } else if !has { diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 173417136c242..3a30b2f3de0fa 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -339,6 +339,18 @@ func TestGetApprovers(t *testing.T) { assert.EqualValues(t, expected, approvers) } +func TestGetPullRequestByMergedCommit(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + pr, err := issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") + assert.NoError(t, err) + assert.EqualValues(t, 1, pr.ID) + + _, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 0, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") + assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{}) + _, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "") + assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{}) +} + func TestMigrate_InsertPullRequests(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) reponame := "repo1"