This is an automated email from the ASF dual-hosted git repository.

abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 4fc799e7e feat: provide an API to query dev panel commits URLs (#5364)
4fc799e7e is described below

commit 4fc799e7e7af3b58d2559c41a8136db41bf51206
Author: Liang Zhang <[email protected]>
AuthorDate: Mon Jun 5 19:54:36 2023 +0800

    feat: provide an API to query dev panel commits URLs (#5364)
---
 backend/plugins/jira/api/scope_config.go | 104 +++++++++++++++++++++++++++++--
 backend/plugins/jira/impl/impl.go        |   5 +-
 backend/plugins/jira/tasks/task_data.go  |   3 +
 3 files changed, 106 insertions(+), 6 deletions(-)

diff --git a/backend/plugins/jira/api/scope_config.go 
b/backend/plugins/jira/api/scope_config.go
index 05723d3a6..e2746e2df 100644
--- a/backend/plugins/jira/api/scope_config.go
+++ b/backend/plugins/jira/api/scope_config.go
@@ -44,7 +44,7 @@ import (
 // @Success 200  {object} tasks.JiraScopeConfig
 // @Failure 400  {object} shared.ApiBody "Bad Request"
 // @Failure 500  {object} shared.ApiBody "Internal Error"
-// @Router /plugins/jira/connections/{connectionId}/scope_configs [POST]
+// @Router /plugins/jira/connections/{connectionId}/scope-configs [POST]
 func CreateScopeConfig(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, errors.Error) {
        rule, err := makeDbScopeConfigFromInput(input)
        if err != nil {
@@ -70,7 +70,7 @@ func CreateScopeConfig(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutpu
 // @Success 200  {object} tasks.JiraScopeConfig
 // @Failure 400  {object} shared.ApiBody "Bad Request"
 // @Failure 500  {object} shared.ApiBody "Internal Error"
-// @Router /plugins/jira/connections/{connectionId}/scope_configs/{id} [PATCH]
+// @Router /plugins/jira/connections/{connectionId}/scope-configs/{id} [PATCH]
 func UpdateScopeConfig(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, errors.Error) {
        connectionId, e := strconv.ParseUint(input.Params["connectionId"], 10, 
64)
        if e != nil || connectionId == 0 {
@@ -136,7 +136,7 @@ func makeDbScopeConfigFromInput(input 
*plugin.ApiResourceInput) (*models.JiraSco
 // @Success 200  {object} tasks.JiraScopeConfig
 // @Failure 400  {object} shared.ApiBody "Bad Request"
 // @Failure 500  {object} shared.ApiBody "Internal Error"
-// @Router /plugins/jira/connections/{connectionId}/scope_configs/{id} [GET]
+// @Router /plugins/jira/connections/{connectionId}/scope-configs/{id} [GET]
 func GetScopeConfig(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, errors.Error) {
        return scHelper.Get(input)
 }
@@ -151,7 +151,7 @@ func GetScopeConfig(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput,
 // @Success 200  {object} []tasks.JiraScopeConfig
 // @Failure 400  {object} shared.ApiBody "Bad Request"
 // @Failure 500  {object} shared.ApiBody "Internal Error"
-// @Router /plugins/jira/connections/{connectionId}/scope_configs [GET]
+// @Router /plugins/jira/connections/{connectionId}/scope-configs [GET]
 func GetScopeConfigList(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, errors.Error) {
        return scHelper.List(input)
 }
@@ -165,7 +165,7 @@ func GetScopeConfigList(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutp
 // @Success 200  {object} []string
 // @Failure 400  {object} shared.ApiBody "Bad Request"
 // @Failure 500  {object} shared.ApiBody "Internal Error"
-// @Router /plugins/jira/connections/{connectionId}/application_types [GET]
+// @Router /plugins/jira/connections/{connectionId}/application-types [GET]
 func GetApplicationTypes(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, errors.Error) {
        var connection models.JiraConnection
        err := connectionHelper.First(&connection, input.Params)
@@ -219,3 +219,97 @@ func GetApplicationTypes(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOut
        sort.Strings(types)
        return &plugin.ApiResourceOutput{Body: types, Status: http.StatusOK}, 
nil
 }
+
+// GetCommitsURLs return some commits URLs
+// @Summary return some commits URLs, at most 5
+// @Description return some commits URLs, at most 5
+// @Tags plugins/jira
+// @Param connectionId path int true "connectionId"
+// @Param key query string true "issue key"
+// @Param applicationType query string true "application type"
+// @Success 200  {object} []string
+// @Failure 400  {object} shared.ApiBody "Bad Request"
+// @Failure 500  {object} shared.ApiBody "Internal Error"
+// @Router /plugins/jira/connections/{connectionId}/dev-panel-commits [GET]
+func GetCommitsURLs(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, errors.Error) {
+       var connection models.JiraConnection
+       err := connectionHelper.First(&connection, input.Params)
+       if err != nil {
+               return nil, err
+       }
+       // get issue key
+       key := input.Query.Get("key")
+       if key == "" {
+               return nil, errors.BadInput.New("key is empty")
+       }
+       // get application types
+       applicationType := input.Query.Get("applicationType")
+       if applicationType == "" {
+               return nil, errors.BadInput.New("applicationType is empty")
+       }
+       // get issue ID from issue key
+       apiClient, err := api.NewApiClientFromConnection(context.TODO(), 
basicRes, &connection)
+       if err != nil {
+               return nil, err
+       }
+
+       var res *http.Response
+       res, err = apiClient.Get(fmt.Sprintf("api/2/issue/%s", key), nil, nil)
+       if err != nil {
+               return nil, err
+       }
+       var issue struct {
+               Id string `json:"id"`
+       }
+       err = api.UnmarshalResponse(res, &issue)
+       if err != nil {
+               return nil, err
+       }
+       // get commits
+       query := url.Values{}
+       query.Set("issueId", issue.Id)
+       query.Set("applicationType", applicationType)
+       query.Set("dataType", "repository")
+       res, err = apiClient.Get("dev-status/1.0/issue/detail", query, nil)
+       if err != nil {
+               return nil, err
+       }
+       type commit struct {
+               ID              string          `json:"id"`
+               DisplayID       string          `json:"displayId"`
+               AuthorTimestamp api.Iso8601Time `json:"authorTimestamp"`
+               URL             string          `json:"url"`
+       }
+       var detail struct {
+               Detail []struct {
+                       Repositories []struct {
+                               Commits []commit `json:"commits"`
+                       } `json:"repositories"`
+               } `json:"detail"`
+       }
+
+       err = api.UnmarshalResponse(res, &detail)
+       if err != nil {
+               return nil, err
+       }
+       var commits []commit
+       for _, item := range detail.Detail {
+               for _, repo := range item.Repositories {
+                       commits = append(commits, repo.Commits...)
+               }
+       }
+
+       // sort by authorTimestamp
+       sort.Slice(commits, func(i, j int) bool {
+               return 
commits[i].AuthorTimestamp.ToTime().After(commits[j].AuthorTimestamp.ToTime())
+       })
+       // return at most 5 commits
+       var commitURLs []string
+       for i, cmt := range commits {
+               if i >= 5 {
+                       break
+               }
+               commitURLs = append(commitURLs, cmt.URL)
+       }
+       return &plugin.ApiResourceOutput{Body: commitURLs, Status: 
http.StatusOK}, nil
+}
diff --git a/backend/plugins/jira/impl/impl.go 
b/backend/plugins/jira/impl/impl.go
index 57cc0a03c..1b0cba2ce 100644
--- a/backend/plugins/jira/impl/impl.go
+++ b/backend/plugins/jira/impl/impl.go
@@ -302,9 +302,12 @@ func (p Jira) ApiResources() 
map[string]map[string]plugin.ApiResourceHandler {
                        "PATCH": api.UpdateScopeConfig,
                        "GET":   api.GetScopeConfig,
                },
-               "connections/:connectionId/application_types": {
+               "connections/:connectionId/application-types": {
                        "GET": api.GetApplicationTypes,
                },
+               "connections/:connectionId/dev-panel-commits": {
+                       "GET": api.GetCommitsURLs,
+               },
        }
 }
 
diff --git a/backend/plugins/jira/tasks/task_data.go 
b/backend/plugins/jira/tasks/task_data.go
index 6a8c00e08..68a3f67c5 100644
--- a/backend/plugins/jira/tasks/task_data.go
+++ b/backend/plugins/jira/tasks/task_data.go
@@ -57,6 +57,9 @@ func (r *JiraScopeConfig) ToDb() (*models.JiraScopeConfig, 
errors.Error) {
        if err != nil {
                return nil, errors.Default.Wrap(err, "error marshaling 
TypeMappings")
        }
+       if r.ApplicationType != "" && len(r.RemotelinkRepoPattern) == 0 {
+               return nil, errors.Default.New("error remotelinkRepoPattern is 
empty")
+       }
        remotelinkRepoPattern, err := json.Marshal(r.RemotelinkRepoPattern)
        if err != nil {
                return nil, errors.Default.Wrap(err, "error marshaling 
RemotelinkRepoPattern")

Reply via email to