feat: [PIPE-22618]: API to fetch PR with the source and target branch (#2838)

* fixed go lint error
* fixed swagger endpoint
* feat: [PIPE-22618]: API to fetch PRs with the source and target branch
pull/3576/head
Karan Saraswat 2024-10-22 11:45:10 +00:00 committed by Harness
parent 5af278c2bb
commit 9a12d72a10
5 changed files with 123 additions and 1 deletions

View File

@ -58,3 +58,50 @@ func (c *Controller) Find(
return pr, nil
}
// Find returns a pull request from the provided repository.
func (c *Controller) FindByBranches(
ctx context.Context,
session *auth.Session,
repoRef,
sourceRepoRef,
sourceBranch,
targetBranch string,
) (*types.PullReq, error) {
if sourceBranch == "" || targetBranch == "" {
return nil, usererror.BadRequest("A valid source/target branch must be provided.")
}
targetRepo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView)
if err != nil {
return nil, fmt.Errorf("failed to acquire access to the repo: %w", err)
}
sourceRepo := targetRepo
if sourceRepoRef != repoRef {
sourceRepo, err = c.getRepoCheckAccess(ctx, session, sourceRepoRef, enum.PermissionRepoPush)
if err != nil {
return nil, fmt.Errorf("failed to acquire access to source repo: %w", err)
}
}
prs, err := c.pullreqStore.List(ctx, &types.PullReqFilter{
SourceRepoID: sourceRepo.ID,
SourceBranch: sourceBranch,
TargetRepoID: targetRepo.ID,
TargetBranch: targetBranch,
States: []enum.PullReqState{enum.PullReqStateOpen},
Size: 1,
Sort: enum.PullReqSortNumber,
Order: enum.OrderAsc,
})
if err != nil {
return nil, fmt.Errorf("failed to fetch existing pull request: %w", err)
}
if len(prs) == 0 {
return nil, usererror.ErrNotFound
}
return prs[0], nil
}

View File

@ -49,3 +49,39 @@ func HandleFind(pullreqCtrl *pullreq.Controller) http.HandlerFunc {
render.JSON(w, http.StatusOK, pr)
}
}
// HandleFind returns a http.HandlerFunc that finds a pull request.
func HandleFindByBranches(pullreqCtrl *pullreq.Controller) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session, _ := request.AuthSessionFrom(ctx)
repoRef, err := request.GetRepoRefFromPath(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
sourceRepoRef := request.GetSourceRepoRefFromQueryOrDefault(r, repoRef)
sourceBranch, err := request.GetPullReqSourceBranchFromPath(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
targetBranch, err := request.GetPullReqTargetBranchFromPath(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
pr, err := pullreqCtrl.FindByBranches(ctx, session, repoRef, sourceRepoRef, sourceBranch, targetBranch)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
render.JSON(w, http.StatusOK, pr)
}
}

View File

@ -47,6 +47,12 @@ type getPullReqRequest struct {
pullReqRequest
}
type getPullReqByBranchesRequest struct {
repoRequest
SourceBranch string `path:"source_branch"`
TargetBranch string `path:"target_branch"`
}
type updatePullReqRequest struct {
pullReqRequest
pullreq.UpdateInput
@ -163,7 +169,7 @@ var queryParameterQueryPullRequest = openapi3.ParameterOrRef{
var queryParameterSourceRepoRefPullRequest = openapi3.ParameterOrRef{
Parameter: &openapi3.Parameter{
Name: "source_repo_ref",
Name: request.QueryParamSourceRepoRef,
In: openapi3.ParameterInQuery,
Description: ptr.String("Source repository ref of the pull requests."),
Required: ptr.Bool(false),
@ -518,6 +524,20 @@ func pullReqOperations(reflector *openapi3.Reflector) {
_ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusForbidden)
_ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repo_ref}/pullreq/{pullreq_number}", getPullReq)
getPullReqByBranches := openapi3.Operation{}
getPullReqByBranches.WithTags("pullreq")
getPullReqByBranches.WithMapOfAnything(map[string]interface{}{"operationId": "getPullReqByBranches"})
getPullReqByBranches.WithParameters(queryParameterSourceRepoRefPullRequest)
_ = reflector.SetRequest(&getPullReqByBranches, new(getPullReqByBranchesRequest), http.MethodGet)
_ = reflector.SetJSONResponse(&getPullReqByBranches, new(types.PullReq), http.StatusOK)
_ = reflector.SetJSONResponse(&getPullReqByBranches, new(usererror.Error), http.StatusBadRequest)
_ = reflector.SetJSONResponse(&getPullReqByBranches, new(usererror.Error), http.StatusUnauthorized)
_ = reflector.SetJSONResponse(&getPullReqByBranches, new(usererror.Error), http.StatusForbidden)
_ = reflector.SetJSONResponse(&getPullReqByBranches, new(usererror.Error), http.StatusNotFound)
_ = reflector.SetJSONResponse(&getPullReqByBranches, new(usererror.Error), http.StatusInternalServerError)
_ = reflector.Spec.AddOperation(http.MethodGet,
"/repos/{repo_ref}/pullreq/{target_branch}...{source_branch}", getPullReqByBranches)
putPullReq := openapi3.Operation{}
putPullReq.WithTags("pullreq")
putPullReq.WithMapOfAnything(map[string]interface{}{"operationId": "updatePullReq"})

View File

@ -28,6 +28,8 @@ const (
PathParamPullReqCommentID = "pullreq_comment_id"
PathParamReviewerID = "pullreq_reviewer_id"
PathParamUserGroupID = "user_group_id"
PathParamSourceBranch = "source_branch"
PathParamTargetBranch = "target_branch"
QueryParamAuthorID = "author_id"
QueryParamCommenterID = "commenter_id"
@ -35,6 +37,7 @@ const (
QueryParamReviewDecision = "review_decision"
QueryParamMentionedID = "mentioned_id"
QueryParamExcludeDescription = "exclude_description"
QueryParamSourceRepoRef = "source_repo_ref"
)
func GetPullReqNumberFromPath(r *http.Request) (int64, error) {
@ -52,6 +55,18 @@ func GetPullReqCommentIDPath(r *http.Request) (int64, error) {
return PathParamAsPositiveInt64(r, PathParamPullReqCommentID)
}
func GetPullReqSourceBranchFromPath(r *http.Request) (string, error) {
return PathParamOrError(r, PathParamSourceBranch)
}
func GetPullReqTargetBranchFromPath(r *http.Request) (string, error) {
return PathParamOrError(r, PathParamTargetBranch)
}
func GetSourceRepoRefFromQueryOrDefault(r *http.Request, deflt string) string {
return QueryParamOrDefault(r, QueryParamSourceRepoRef, deflt)
}
// ParseSortPullReq extracts the pull request sort parameter from the url.
func ParseSortPullReq(r *http.Request) enum.PullReqSort {
result, _ := enum.PullReqSort(r.URL.Query().Get(QueryParamSort)).Sanitize()

View File

@ -638,6 +638,10 @@ func SetupPullReq(r chi.Router, pullreqCtrl *pullreq.Controller) {
r.Route("/pullreq", func(r chi.Router) {
r.Post("/", handlerpullreq.HandleCreate(pullreqCtrl))
r.Get("/", handlerpullreq.HandleList(pullreqCtrl))
r.Get(
fmt.Sprintf("/{%s}...{%s}", request.PathParamTargetBranch, request.PathParamSourceBranch),
handlerpullreq.HandleFindByBranches(pullreqCtrl),
)
r.Route(fmt.Sprintf("/{%s}", request.PathParamPullReqNumber), func(r chi.Router) {
r.Get("/", handlerpullreq.HandleFind(pullreqCtrl))