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

likyh 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 5070b2aed feat: convert issue_repo_commit for tapd (#4824)
5070b2aed is described below

commit 5070b2aedaf05ea8f9511754aaa7dae0f7b9de6a
Author: Likyh <[email protected]>
AuthorDate: Fri Mar 31 15:00:17 2023 +0800

    feat: convert issue_repo_commit for tapd (#4824)
    
    * feat: convert issue_repo_commit for tapd
    
    * fix: for ci
    
    * fix: delete in config-ui
---
 .../api/issue_repo_commit_convertor.go             | 60 ++++++++++++++
 .../api}/issue_repo_commit_convertor_test.go       | 77 ++++++++++++++++-
 .../jira/tasks/issue_repo_commit_convertor.go      | 36 ++------
 backend/plugins/jira/tasks/remotelink_extractor.go | 39 ++-------
 .../jira/tasks/remotelink_extractor_test.go        | 96 ----------------------
 backend/plugins/tapd/impl/impl.go                  |  2 -
 .../20230323_add_transformation.go                 |  3 +-
 .../{register.go => 20230330_delete_issue.go}      | 28 +++++--
 .../archived/transformation_rule.go}               | 20 +++--
 .../tapd/models/migrationscripts/register.go       |  1 +
 backend/plugins/tapd/models/sub_workspace.go       | 43 ----------
 backend/plugins/tapd/models/transformation_rule.go | 12 ++-
 backend/plugins/tapd/tasks/bug_commit_converter.go | 29 ++++++-
 .../plugins/tapd/tasks/story_commit_converter.go   | 29 ++++++-
 .../plugins/tapd/tasks/task_commit_converter.go    | 29 ++++++-
 backend/plugins/tapd/tasks/task_data.go            | 19 +----
 config-ui/src/plugins/register/tapd/config.tsx     |  1 -
 .../src/plugins/register/tapd/transformation.tsx   | 41 ---------
 config-ui/src/plugins/register/zentao/config.ts    |  2 +-
 19 files changed, 270 insertions(+), 297 deletions(-)

diff --git a/backend/helpers/pluginhelper/api/issue_repo_commit_convertor.go 
b/backend/helpers/pluginhelper/api/issue_repo_commit_convertor.go
new file mode 100644
index 000000000..d5d6e2763
--- /dev/null
+++ b/backend/helpers/pluginhelper/api/issue_repo_commit_convertor.go
@@ -0,0 +1,60 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package api
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
+       "net/url"
+       "path"
+       "regexp"
+)
+
+// ExtractCommitSha extracts commit sha from commit url
+func ExtractCommitSha(repoPatterns []*regexp.Regexp, commitUrl string) string {
+       for _, pattern := range repoPatterns {
+               if pattern.MatchString(commitUrl) {
+                       group := pattern.FindStringSubmatch(commitUrl)
+                       if len(group) == 4 {
+                               return group[3]
+                       }
+               }
+       }
+       return ""
+}
+
+// RefineIssueRepoCommit refines issue repo commit
+func RefineIssueRepoCommit(item *crossdomain.IssueRepoCommit, repoPatterns 
[]*regexp.Regexp, commitUrl string) *crossdomain.IssueRepoCommit {
+       u, err := url.Parse(commitUrl)
+       if err != nil {
+               return item
+       }
+       item.Host = u.Host
+       for _, pattern := range repoPatterns {
+               if pattern.MatchString(commitUrl) {
+                       group := pattern.FindStringSubmatch(commitUrl)
+                       if len(group) == 4 {
+                               item.Namespace = group[1]
+                               item.RepoName = group[2]
+                               u.Path = path.Join(item.Namespace, 
item.RepoName+".git")
+                               item.RepoUrl = u.String()
+                               break
+                       }
+               }
+       }
+       return item
+}
diff --git a/backend/plugins/jira/tasks/issue_repo_commit_convertor_test.go 
b/backend/helpers/pluginhelper/api/issue_repo_commit_convertor_test.go
similarity index 64%
rename from backend/plugins/jira/tasks/issue_repo_commit_convertor_test.go
rename to backend/helpers/pluginhelper/api/issue_repo_commit_convertor_test.go
index c9310ea56..183080b7f 100644
--- a/backend/plugins/jira/tasks/issue_repo_commit_convertor_test.go
+++ b/backend/helpers/pluginhelper/api/issue_repo_commit_convertor_test.go
@@ -15,7 +15,7 @@ See the License for the specific language governing 
permissions and
 limitations under the License.
 */
 
-package tasks
+package api
 
 import (
        
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
@@ -24,6 +24,79 @@ import (
        "testing"
 )
 
+func Test_extractCommitSha(t *testing.T) {
+       type args struct {
+               repoPatterns []*regexp.Regexp
+               commitUrl    string
+       }
+       tests := []struct {
+               name string
+               args args
+               want string
+       }{
+               {
+                       "bitbucket server",
+                       args{
+                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile("https://example.com/bitbucket/projects/(?P<namespace>[^/]+)/repos/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\\w{40})")},
+                               commitUrl:    
"https://example.com/bitbucket/projects/PROJECTNAME/repos/ui_jira/commits/1e23e7f1a0cb539c7408c38e5a37de3bc836bc94";,
+                       },
+                       "1e23e7f1a0cb539c7408c38e5a37de3bc836bc94",
+               },
+
+               {
+                       "bitbucket cloud",
+                       args{
+                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://bitbucket.org/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\w{40})`)},
+                               commitUrl:    
"https://bitbucket.org/mynamespace/incubator-devlake/commits/fef8d697fbb9a2b336be6fa2e2848f585c86a622";,
+                       },
+                       "fef8d697fbb9a2b336be6fa2e2848f585c86a622",
+               },
+               {
+                       "GitHub",
+                       args{
+                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://github.com/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commit/(?P<commit_sha>\w{40})`)},
+                               commitUrl:    
"https://github.com/apache/incubator-devlake/commit/a7c6550b6a273af36e9850291a52601d3dca367c";,
+                       },
+                       "a7c6550b6a273af36e9850291a52601d3dca367c",
+               },
+               {
+                       "GitLab cloud",
+                       args{
+                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://gitlab.com/(?P<namespace>\S+/\S+)/(?P<repo_name>\w+)/-/commit/(?P<commit_sha>\w{40})`)},
+                               commitUrl:    
"https://gitlab.com/namespace1/namespace2/myrepo/-/commit/050baf4575caf069275f5fa14db9ad4a21a79883";,
+                       },
+                       "050baf4575caf069275f5fa14db9ad4a21a79883",
+               },
+               {
+                       "GitLab cloud",
+                       args{
+                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://gitlab.com/(?P<namespace>\S+)/(?P<repo_name>\S+)/-/commit/(?P<commit_sha>\w{40})`)},
+                               commitUrl:    
"https://gitlab.com/meri.co/vdev.co/-/commit/0c564ef4c14584599ed733383477fb2bf8eeecf7";,
+                       },
+                       "0c564ef4c14584599ed733383477fb2bf8eeecf7",
+               },
+               {
+                       "GitLab cloud",
+                       args{
+                               repoPatterns: []*regexp.Regexp{
+                                       
//regexp.MustCompile(`https://bitbucket.org/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\w{40})`),
+                                       
regexp.MustCompile(`https://gitlab.com/(?P<namespace>\S+)/(?P<repo_name>\S+)/-/commit/(?P<commit_sha>\w{40})`),
+                                       
//regexp.MustCompile(`https://github.com/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commit/(?P<commit_sha>\w{40})`),
+                               },
+                               commitUrl: 
"https://gitlab.com/meri.co/vdev.co/-/commit/a802d5edf833b8fa70189783ebe21174ff333c69";,
+                       },
+                       "a802d5edf833b8fa70189783ebe21174ff333c69",
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       if got := ExtractCommitSha(tt.args.repoPatterns, 
tt.args.commitUrl); got != tt.want {
+                               t.Errorf("extractCommitSha() = %v, want %v", 
got, tt.want)
+                       }
+               })
+       }
+}
+
 func Test_refineIssueRepoCommit(t *testing.T) {
        type args struct {
                item         *crossdomain.IssueRepoCommit
@@ -122,7 +195,7 @@ func Test_refineIssueRepoCommit(t *testing.T) {
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
-                       if got := refineIssueRepoCommit(tt.args.item, 
tt.args.repoPatterns, tt.args.commitUrl); !reflect.DeepEqual(got, tt.want) {
+                       if got := RefineIssueRepoCommit(tt.args.item, 
tt.args.repoPatterns, tt.args.commitUrl); !reflect.DeepEqual(got, tt.want) {
                                t.Logf("%+v", got)
                                t.Errorf("refineIssueRepoCommit() = %v, want 
%v", got, tt.want)
                        }
diff --git a/backend/plugins/jira/tasks/issue_repo_commit_convertor.go 
b/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
index d4822656c..17b4800be 100644
--- a/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
+++ b/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
@@ -18,8 +18,6 @@ limitations under the License.
 package tasks
 
 import (
-       "net/url"
-       "path"
        "reflect"
        "regexp"
 
@@ -50,9 +48,8 @@ func ConvertIssueRepoCommits(taskCtx plugin.SubTaskContext) 
errors.Error {
        logger := taskCtx.GetLogger()
        logger.Info("convert issue repo commits")
        var commitRepoUrlRegex *regexp.Regexp
-       var err error
        commitRepoUrlPattern := `(.*)\-\/commit`
-       commitRepoUrlRegex, err = regexp.Compile(commitRepoUrlPattern)
+       commitRepoUrlRegex, err := 
errors.Convert01(regexp.Compile(commitRepoUrlPattern))
        if err != nil {
                return errors.Default.Wrap(err, "regexp Compile 
commitRepoUrlPattern failed")
        }
@@ -67,19 +64,19 @@ func ConvertIssueRepoCommits(taskCtx plugin.SubTaskContext) 
errors.Error {
                }
        }
 
-       clause := []dal.Clause{
+       clauses := []dal.Clause{
+               dal.Select("jic.*"),
                dal.From("_tool_jira_issue_commits jic"),
                dal.Join(`left join _tool_jira_board_issues jbi on (
                        jbi.connection_id = jic.connection_id
                        AND jbi.issue_id = jic.issue_id
                )`),
-               dal.Select("jic.*"),
                dal.Where("jbi.connection_id = ? AND jbi.board_id = ?", 
connectionId, boardId),
                dal.Orderby("jbi.connection_id, jbi.issue_id"),
        }
-       cursor, err := db.Cursor(clause...)
+       cursor, err := db.Cursor(clauses...)
        if err != nil {
-               return errors.Convert(err)
+               return err
        }
        defer cursor.Close()
 
@@ -107,7 +104,7 @@ func ConvertIssueRepoCommits(taskCtx plugin.SubTaskContext) 
errors.Error {
                                        item.RepoUrl = groups[1]
                                }
                        }
-                       refineIssueRepoCommit(item, commitRepoUrlRegexps, 
issueCommit.CommitUrl)
+                       api.RefineIssueRepoCommit(item, commitRepoUrlRegexps, 
issueCommit.CommitUrl)
                        return []interface{}{item}, nil
                },
        })
@@ -117,24 +114,3 @@ func ConvertIssueRepoCommits(taskCtx 
plugin.SubTaskContext) errors.Error {
 
        return converter.Execute()
 }
-
-func refineIssueRepoCommit(item *crossdomain.IssueRepoCommit, repoPatterns 
[]*regexp.Regexp, commitUrl string) *crossdomain.IssueRepoCommit {
-       u, err := url.Parse(commitUrl)
-       if err != nil {
-               return item
-       }
-       item.Host = u.Host
-       for _, pattern := range repoPatterns {
-               if pattern.MatchString(commitUrl) {
-                       group := pattern.FindStringSubmatch(commitUrl)
-                       if len(group) == 4 {
-                               item.Namespace = group[1]
-                               item.RepoName = group[2]
-                               u.Path = path.Join(item.Namespace, 
item.RepoName+".git")
-                               item.RepoUrl = u.String()
-                               break
-                       }
-               }
-       }
-       return item
-}
diff --git a/backend/plugins/jira/tasks/remotelink_extractor.go 
b/backend/plugins/jira/tasks/remotelink_extractor.go
index 22896e906..d8bd6a029 100644
--- a/backend/plugins/jira/tasks/remotelink_extractor.go
+++ b/backend/plugins/jira/tasks/remotelink_extractor.go
@@ -19,7 +19,6 @@ package tasks
 
 import (
        "encoding/json"
-       "github.com/apache/incubator-devlake/core/dal"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/core/plugin"
        "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
@@ -41,13 +40,13 @@ func ExtractRemotelinks(taskCtx plugin.SubTaskContext) 
errors.Error {
        connectionId := data.Options.ConnectionId
        boardId := data.Options.BoardId
        logger := taskCtx.GetLogger()
-       db := taskCtx.GetDal()
        logger.Info("extract remote links")
+
+       var err errors.Error
        var commitShaRegex *regexp.Regexp
-       var err error
        if data.Options.TransformationRules != nil && 
data.Options.TransformationRules.RemotelinkCommitShaPattern != "" {
                pattern := 
data.Options.TransformationRules.RemotelinkCommitShaPattern
-               commitShaRegex, err = regexp.Compile(pattern)
+               commitShaRegex, err = errors.Convert01(regexp.Compile(pattern))
                if err != nil {
                        return errors.Default.Wrap(err, "regexp Compile pattern 
failed")
                }
@@ -62,18 +61,6 @@ func ExtractRemotelinks(taskCtx plugin.SubTaskContext) 
errors.Error {
                        commitRepoUrlRegexps = append(commitRepoUrlRegexps, 
pattern)
                }
        }
-       // select all remotelinks belongs to the board, cursor is important for 
low memory footprint
-       clauses := []dal.Clause{
-               dal.From(&models.JiraRemotelink{}),
-               dal.Select("*"),
-               dal.Join("left join _tool_jira_board_issues on 
_tool_jira_board_issues.issue_id = _tool_jira_remotelinks.issue_id"),
-               dal.Where("_tool_jira_board_issues.board_id = ? AND 
_tool_jira_board_issues.connection_id = ?", boardId, connectionId),
-       }
-       cursor, err := db.Cursor(clauses...)
-       if err != nil {
-               return errors.Convert(err)
-       }
-       defer cursor.Close()
 
        extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
                RawDataSubTaskArgs: api.RawDataSubTaskArgs{
@@ -118,29 +105,17 @@ func ExtractRemotelinks(taskCtx plugin.SubTaskContext) 
errors.Error {
                                }
                        }
                        if issueCommit.CommitSha == "" {
-                               issueCommit.CommitSha = 
extractCommitSha(commitRepoUrlRegexps, remotelink.Url)
+                               issueCommit.CommitSha = 
api.ExtractCommitSha(commitRepoUrlRegexps, remotelink.Url)
                        }
                        if issueCommit.CommitSha != "" {
                                result = append(result, issueCommit)
                        }
                        return result, nil
-               }})
-
+               },
+       })
        if err != nil {
-               return errors.Convert(err)
+               return err
        }
 
        return extractor.Execute()
 }
-
-func extractCommitSha(repoPatterns []*regexp.Regexp, commitUrl string) string {
-       for _, pattern := range repoPatterns {
-               if pattern.MatchString(commitUrl) {
-                       group := pattern.FindStringSubmatch(commitUrl)
-                       if len(group) == 4 {
-                               return group[3]
-                       }
-               }
-       }
-       return ""
-}
diff --git a/backend/plugins/jira/tasks/remotelink_extractor_test.go 
b/backend/plugins/jira/tasks/remotelink_extractor_test.go
deleted file mode 100644
index de346607c..000000000
--- a/backend/plugins/jira/tasks/remotelink_extractor_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package tasks
-
-import (
-       "regexp"
-       "testing"
-)
-
-func Test_extractCommitSha(t *testing.T) {
-       type args struct {
-               repoPatterns []*regexp.Regexp
-               commitUrl    string
-       }
-       tests := []struct {
-               name string
-               args args
-               want string
-       }{
-               {
-                       "bitbucket server",
-                       args{
-                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile("https://example.com/bitbucket/projects/(?P<namespace>[^/]+)/repos/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\\w{40})")},
-                               commitUrl:    
"https://example.com/bitbucket/projects/PROJECTNAME/repos/ui_jira/commits/1e23e7f1a0cb539c7408c38e5a37de3bc836bc94";,
-                       },
-                       "1e23e7f1a0cb539c7408c38e5a37de3bc836bc94",
-               },
-
-               {
-                       "bitbucket cloud",
-                       args{
-                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://bitbucket.org/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\w{40})`)},
-                               commitUrl:    
"https://bitbucket.org/mynamespace/incubator-devlake/commits/fef8d697fbb9a2b336be6fa2e2848f585c86a622";,
-                       },
-                       "fef8d697fbb9a2b336be6fa2e2848f585c86a622",
-               },
-               {
-                       "GitHub",
-                       args{
-                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://github.com/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commit/(?P<commit_sha>\w{40})`)},
-                               commitUrl:    
"https://github.com/apache/incubator-devlake/commit/a7c6550b6a273af36e9850291a52601d3dca367c";,
-                       },
-                       "a7c6550b6a273af36e9850291a52601d3dca367c",
-               },
-               {
-                       "GitLab cloud",
-                       args{
-                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://gitlab.com/(?P<namespace>\S+/\S+)/(?P<repo_name>\w+)/-/commit/(?P<commit_sha>\w{40})`)},
-                               commitUrl:    
"https://gitlab.com/namespace1/namespace2/myrepo/-/commit/050baf4575caf069275f5fa14db9ad4a21a79883";,
-                       },
-                       "050baf4575caf069275f5fa14db9ad4a21a79883",
-               },
-               {
-                       "GitLab cloud",
-                       args{
-                               repoPatterns: 
[]*regexp.Regexp{regexp.MustCompile(`https://gitlab.com/(?P<namespace>\S+)/(?P<repo_name>\S+)/-/commit/(?P<commit_sha>\w{40})`)},
-                               commitUrl:    
"https://gitlab.com/meri.co/vdev.co/-/commit/0c564ef4c14584599ed733383477fb2bf8eeecf7";,
-                       },
-                       "0c564ef4c14584599ed733383477fb2bf8eeecf7",
-               },
-               {
-                       "GitLab cloud",
-                       args{
-                               repoPatterns: []*regexp.Regexp{
-                                       
//regexp.MustCompile(`https://bitbucket.org/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\w{40})`),
-                                       
regexp.MustCompile(`https://gitlab.com/(?P<namespace>\S+)/(?P<repo_name>\S+)/-/commit/(?P<commit_sha>\w{40})`),
-                                       
//regexp.MustCompile(`https://github.com/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commit/(?P<commit_sha>\w{40})`),
-                               },
-                               commitUrl: 
"https://gitlab.com/meri.co/vdev.co/-/commit/a802d5edf833b8fa70189783ebe21174ff333c69";,
-                       },
-                       "a802d5edf833b8fa70189783ebe21174ff333c69",
-               },
-       }
-       for _, tt := range tests {
-               t.Run(tt.name, func(t *testing.T) {
-                       if got := extractCommitSha(tt.args.repoPatterns, 
tt.args.commitUrl); got != tt.want {
-                               t.Errorf("extractCommitSha() = %v, want %v", 
got, tt.want)
-                       }
-               })
-       }
-}
diff --git a/backend/plugins/tapd/impl/impl.go 
b/backend/plugins/tapd/impl/impl.go
index 7cfe929cf..5ead1ddc0 100644
--- a/backend/plugins/tapd/impl/impl.go
+++ b/backend/plugins/tapd/impl/impl.go
@@ -58,7 +58,6 @@ func (p Tapd) GetTablesInfo() []dal.Tabler {
                &models.TapdBugLabel{},
                &models.TapdBugStatus{},
                &models.TapdConnection{},
-               &models.TapdIssue{},
                &models.TapdIteration{},
                &models.TapdIterationBug{},
                &models.TapdIterationStory{},
@@ -72,7 +71,6 @@ func (p Tapd) GetTablesInfo() []dal.Tabler {
                &models.TapdStoryCustomFields{},
                &models.TapdStoryLabel{},
                &models.TapdStoryStatus{},
-               &models.TapdSubWorkspace{},
                &models.TapdTask{},
                &models.TapdTaskChangelog{},
                &models.TapdTaskChangelogItem{},
diff --git 
a/backend/plugins/tapd/models/migrationscripts/20230323_add_transformation.go 
b/backend/plugins/tapd/models/migrationscripts/20230323_add_transformation.go
index d70a99652..94e584d8a 100644
--- 
a/backend/plugins/tapd/models/migrationscripts/20230323_add_transformation.go
+++ 
b/backend/plugins/tapd/models/migrationscripts/20230323_add_transformation.go
@@ -22,7 +22,6 @@ import (
        "github.com/apache/incubator-devlake/core/dal"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/helpers/migrationhelper"
-       "github.com/apache/incubator-devlake/plugins/tapd/models"
        
"github.com/apache/incubator-devlake/plugins/tapd/models/migrationscripts/archived"
 )
 
@@ -122,7 +121,7 @@ func (*addTransformation) Up(basicRes context.BasicRes) 
errors.Error {
 
        return migrationhelper.AutoMigrateTables(
                basicRes,
-               &models.TapdTransformationRule{},
+               &archived.TapdTransformationRule{},
                &TapdWorkspace20230323{},
        )
 }
diff --git a/backend/plugins/tapd/models/migrationscripts/register.go 
b/backend/plugins/tapd/models/migrationscripts/20230330_delete_issue.go
similarity index 54%
copy from backend/plugins/tapd/models/migrationscripts/register.go
copy to backend/plugins/tapd/models/migrationscripts/20230330_delete_issue.go
index 70cb0003e..a6130a5f9 100644
--- a/backend/plugins/tapd/models/migrationscripts/register.go
+++ b/backend/plugins/tapd/models/migrationscripts/20230330_delete_issue.go
@@ -18,14 +18,28 @@ limitations under the License.
 package migrationscripts
 
 import (
-       "github.com/apache/incubator-devlake/core/plugin"
+       "github.com/apache/incubator-devlake/core/context"
+       "github.com/apache/incubator-devlake/core/errors"
+       
"github.com/apache/incubator-devlake/plugins/tapd/models/migrationscripts/archived"
 )
 
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
-       return []plugin.MigrationScript{
-               new(addInitTables),
-               new(encodeConnToken),
-               new(addTransformation),
+type deleteIssue struct{}
+
+func (*deleteIssue) Up(basicRes context.BasicRes) errors.Error {
+       db := basicRes.GetDal()
+       err := db.DropTables(archived.TapdIssue{})
+       if err != nil {
+               return err
        }
+       // drop if exist
+       _ = db.DropColumns(`_tool_tapd_transformation_rules`, 
`remotelink_commit_sha_pattern`, `remotelink_repo_pattern`)
+       return nil
+}
+
+func (*deleteIssue) Version() uint64 {
+       return 20230323000004
+}
+
+func (*deleteIssue) Name() string {
+       return "Tapd delete issue and remote link"
 }
diff --git a/backend/plugins/tapd/models/issue.go 
b/backend/plugins/tapd/models/migrationscripts/archived/transformation_rule.go
similarity index 52%
rename from backend/plugins/tapd/models/issue.go
rename to 
backend/plugins/tapd/models/migrationscripts/archived/transformation_rule.go
index 4c51d2650..3adb67905 100644
--- a/backend/plugins/tapd/models/issue.go
+++ 
b/backend/plugins/tapd/models/migrationscripts/archived/transformation_rule.go
@@ -15,13 +15,21 @@ See the License for the specific language governing 
permissions and
 limitations under the License.
 */
 
-package models
+package archived
 
-type TapdIssue struct {
-       ConnectionId uint64 `gorm:"primaryKey"`
-       Id           uint64 `gorm:"primaryKey;type:BIGINT" json:"id,string"`
+import (
+       "encoding/json"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+)
+
+type TapdTransformationRule struct {
+       archived.NoPKModel
+       ConnectionId   uint64          `mapstructure:"connectionId" 
json:"connectionId"`
+       Name           string          
`gorm:"type:varchar(255);index:idx_name_tapd,unique" validate:"required" 
mapstructure:"name" json:"name"`
+       TypeMappings   json.RawMessage `mapstructure:"typeMappings,omitempty" 
json:"typeMappings"`
+       StatusMappings json.RawMessage `mapstructure:"statusMappings,omitempty" 
json:"statusMappings"`
 }
 
-func (TapdIssue) TableName() string {
-       return "_tool_tapd_issues"
+func (t TapdTransformationRule) TableName() string {
+       return "_tool_tapd_transformation_rules"
 }
diff --git a/backend/plugins/tapd/models/migrationscripts/register.go 
b/backend/plugins/tapd/models/migrationscripts/register.go
index 70cb0003e..04461d050 100644
--- a/backend/plugins/tapd/models/migrationscripts/register.go
+++ b/backend/plugins/tapd/models/migrationscripts/register.go
@@ -27,5 +27,6 @@ func All() []plugin.MigrationScript {
                new(addInitTables),
                new(encodeConnToken),
                new(addTransformation),
+               new(deleteIssue),
        }
 }
diff --git a/backend/plugins/tapd/models/sub_workspace.go 
b/backend/plugins/tapd/models/sub_workspace.go
deleted file mode 100644
index c4ab2a476..000000000
--- a/backend/plugins/tapd/models/sub_workspace.go
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package models
-
-import (
-       "github.com/apache/incubator-devlake/core/models/common"
-       helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
-)
-
-type TapdSubWorkspace struct {
-       ConnectionId uint64          `gorm:"primaryKey;type:BIGINT  NOT NULL"`
-       Id           uint64          `gorm:"primaryKey;type:BIGINT" 
json:"id,string"`
-       Name         string          `gorm:"type:varchar(255)" json:"name"`
-       PrettyName   string          `gorm:"type:varchar(255)" 
json:"pretty_name"`
-       Category     string          `gorm:"type:varchar(255)" json:"category"`
-       Status       string          `gorm:"type:varchar(255)" json:"status"`
-       Description  string          `json:"description"`
-       BeginDate    *helper.CSTTime `json:"begin_date"`
-       EndDate      *helper.CSTTime `json:"end_date"`
-       ExternalOn   string          `gorm:"type:varchar(255)" 
json:"external_on"`
-       ParentId     uint64          `gorm:"type:BIGINT" 
json:"parent_id,string"`
-       Creator      string          `gorm:"type:varchar(255)" json:"creator"`
-       common.NoPKModel
-}
-
-func (TapdSubWorkspace) TableName() string {
-       return "_tool_tapd_sub_workspaces"
-}
diff --git a/backend/plugins/tapd/models/transformation_rule.go 
b/backend/plugins/tapd/models/transformation_rule.go
index 00622b1b7..f1b9095d7 100644
--- a/backend/plugins/tapd/models/transformation_rule.go
+++ b/backend/plugins/tapd/models/transformation_rule.go
@@ -23,13 +23,11 @@ import (
 )
 
 type TapdTransformationRule struct {
-       common.Model               `mapstructure:"-"`
-       ConnectionId               uint64          `mapstructure:"connectionId" 
json:"connectionId"`
-       Name                       string          
`gorm:"type:varchar(255);index:idx_name_tapd,unique" validate:"required" 
mapstructure:"name" json:"name"`
-       RemotelinkCommitShaPattern string          
`mapstructure:"remotelinkCommitShaPattern,omitempty" 
json:"remotelinkCommitShaPattern" gorm:"type:varchar(255)"`
-       RemotelinkRepoPattern      json.RawMessage 
`mapstructure:"remotelinkRepoPattern,omitempty" json:"remotelinkRepoPattern"`
-       TypeMappings               json.RawMessage 
`mapstructure:"typeMappings,omitempty" json:"typeMappings"`
-       StatusMappings             json.RawMessage 
`mapstructure:"statusMappings,omitempty" json:"statusMappings"`
+       common.Model   `mapstructure:"-"`
+       ConnectionId   uint64          `mapstructure:"connectionId" 
json:"connectionId"`
+       Name           string          
`gorm:"type:varchar(255);index:idx_name_tapd,unique" validate:"required" 
mapstructure:"name" json:"name"`
+       TypeMappings   json.RawMessage `mapstructure:"typeMappings,omitempty" 
json:"typeMappings"`
+       StatusMappings json.RawMessage `mapstructure:"statusMappings,omitempty" 
json:"statusMappings"`
 }
 
 func (t TapdTransformationRule) TableName() string {
diff --git a/backend/plugins/tapd/tasks/bug_commit_converter.go 
b/backend/plugins/tapd/tasks/bug_commit_converter.go
index 24816b244..2586bb400 100644
--- a/backend/plugins/tapd/tasks/bug_commit_converter.go
+++ b/backend/plugins/tapd/tasks/bug_commit_converter.go
@@ -25,7 +25,9 @@ import (
        "github.com/apache/incubator-devlake/core/plugin"
        helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
        "github.com/apache/incubator-devlake/plugins/tapd/models"
+       "net/url"
        "reflect"
+       "strings"
 )
 
 func ConvertBugCommit(taskCtx plugin.SubTaskContext) errors.Error {
@@ -49,14 +51,33 @@ func ConvertBugCommit(taskCtx plugin.SubTaskContext) 
errors.Error {
                Input:              cursor,
                Convert: func(inputRow interface{}) ([]interface{}, 
errors.Error) {
                        toolL := inputRow.(*models.TapdBugCommit)
-                       domainL := &crossdomain.IssueCommit{
+                       results := make([]interface{}, 0, 2)
+                       issueCommit := &crossdomain.IssueCommit{
                                IssueId:   
issueIdGen.Generate(data.Options.ConnectionId, toolL.BugId),
                                CommitSha: toolL.CommitId,
                        }
+                       results = append(results, issueCommit)
+                       if toolL.WebURL != `` {
+                               u, err := 
errors.Convert01(url.Parse(toolL.WebURL))
+                               if err != nil {
+                                       return nil, err
+                               }
+                               repoUrl := toolL.WebURL
+                               if !strings.HasSuffix(repoUrl, `.git`) {
+                                       repoUrl = repoUrl + `.git`
+                               }
+                               issueRepoCommit := &crossdomain.IssueRepoCommit{
+                                       IssueId:   
issueIdGen.Generate(data.Options.ConnectionId, toolL.BugId),
+                                       RepoUrl:   repoUrl,
+                                       CommitSha: toolL.CommitId,
+                                       Host:      u.Host,
+                                       Namespace: strings.Split(u.Path, 
`/`)[1],
+                                       RepoName:  toolL.HookProjectName,
+                               }
+                               results = append(results, issueRepoCommit)
+                       }
 
-                       return []interface{}{
-                               domainL,
-                       }, nil
+                       return results, nil
                },
        })
        if err != nil {
diff --git a/backend/plugins/tapd/tasks/story_commit_converter.go 
b/backend/plugins/tapd/tasks/story_commit_converter.go
index c9cf8a6d3..c06a201fc 100644
--- a/backend/plugins/tapd/tasks/story_commit_converter.go
+++ b/backend/plugins/tapd/tasks/story_commit_converter.go
@@ -25,7 +25,9 @@ import (
        "github.com/apache/incubator-devlake/core/plugin"
        helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
        "github.com/apache/incubator-devlake/plugins/tapd/models"
+       "net/url"
        "reflect"
+       "strings"
 )
 
 func ConvertStoryCommit(taskCtx plugin.SubTaskContext) errors.Error {
@@ -47,14 +49,33 @@ func ConvertStoryCommit(taskCtx plugin.SubTaskContext) 
errors.Error {
                Input:              cursor,
                Convert: func(inputRow interface{}) ([]interface{}, 
errors.Error) {
                        toolL := inputRow.(*models.TapdStoryCommit)
-                       domainL := &crossdomain.IssueCommit{
+                       results := make([]interface{}, 0, 2)
+                       issueCommit := &crossdomain.IssueCommit{
                                IssueId:   
issueIdGen.Generate(data.Options.ConnectionId, toolL.StoryId),
                                CommitSha: toolL.CommitId,
                        }
+                       results = append(results, issueCommit)
+                       if toolL.WebURL != `` {
+                               u, err := 
errors.Convert01(url.Parse(toolL.WebURL))
+                               if err != nil {
+                                       return nil, err
+                               }
+                               repoUrl := toolL.WebURL
+                               if !strings.HasSuffix(repoUrl, `.git`) {
+                                       repoUrl = repoUrl + `.git`
+                               }
+                               issueRepoCommit := &crossdomain.IssueRepoCommit{
+                                       IssueId:   
issueIdGen.Generate(data.Options.ConnectionId, toolL.StoryId),
+                                       RepoUrl:   repoUrl,
+                                       CommitSha: toolL.CommitId,
+                                       Host:      u.Host,
+                                       Namespace: strings.Split(u.Path, 
`/`)[1],
+                                       RepoName:  toolL.HookProjectName,
+                               }
+                               results = append(results, issueRepoCommit)
+                       }
 
-                       return []interface{}{
-                               domainL,
-                       }, nil
+                       return results, nil
                },
        })
        if err != nil {
diff --git a/backend/plugins/tapd/tasks/task_commit_converter.go 
b/backend/plugins/tapd/tasks/task_commit_converter.go
index 42c53d987..bdf93cf42 100644
--- a/backend/plugins/tapd/tasks/task_commit_converter.go
+++ b/backend/plugins/tapd/tasks/task_commit_converter.go
@@ -25,7 +25,9 @@ import (
        "github.com/apache/incubator-devlake/core/plugin"
        helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
        "github.com/apache/incubator-devlake/plugins/tapd/models"
+       "net/url"
        "reflect"
+       "strings"
 )
 
 func ConvertTaskCommit(taskCtx plugin.SubTaskContext) errors.Error {
@@ -50,14 +52,33 @@ func ConvertTaskCommit(taskCtx plugin.SubTaskContext) 
errors.Error {
                Input:              cursor,
                Convert: func(inputRow interface{}) ([]interface{}, 
errors.Error) {
                        toolL := inputRow.(*models.TapdTaskCommit)
-                       domainL := &crossdomain.IssueCommit{
+                       results := make([]interface{}, 0, 2)
+                       issueCommit := &crossdomain.IssueCommit{
                                IssueId:   
issueIdGen.Generate(data.Options.ConnectionId, toolL.TaskId),
                                CommitSha: toolL.CommitId,
                        }
+                       results = append(results, issueCommit)
+                       if toolL.WebURL != `` {
+                               u, err := 
errors.Convert01(url.Parse(toolL.WebURL))
+                               if err != nil {
+                                       return nil, err
+                               }
+                               repoUrl := toolL.WebURL
+                               if !strings.HasSuffix(repoUrl, `.git`) {
+                                       repoUrl = repoUrl + `.git`
+                               }
+                               issueRepoCommit := &crossdomain.IssueRepoCommit{
+                                       IssueId:   
issueIdGen.Generate(data.Options.ConnectionId, toolL.TaskId),
+                                       RepoUrl:   repoUrl,
+                                       CommitSha: toolL.CommitId,
+                                       Host:      u.Host,
+                                       Namespace: strings.Split(u.Path, 
`/`)[1],
+                                       RepoName:  toolL.HookProjectName,
+                               }
+                               results = append(results, issueRepoCommit)
+                       }
 
-                       return []interface{}{
-                               domainL,
-                       }, nil
+                       return results, nil
                },
        })
        if err != nil {
diff --git a/backend/plugins/tapd/tasks/task_data.go 
b/backend/plugins/tapd/tasks/task_data.go
index 7b2322ca0..f2b3c84fd 100644
--- a/backend/plugins/tapd/tasks/task_data.go
+++ b/backend/plugins/tapd/tasks/task_data.go
@@ -52,18 +52,9 @@ func MakeTransformationRules(rule 
models.TapdTransformationRule) (*Transformatio
                        return nil, errors.Default.Wrap(err, "unable to 
unmarshal the statusMapping")
                }
        }
-       var remotelinkRepoPattern []string
-       if len(rule.RemotelinkRepoPattern) > 0 {
-               err = json.Unmarshal(rule.RemotelinkRepoPattern, 
&remotelinkRepoPattern)
-               if err != nil {
-                       return nil, errors.Default.Wrap(err, "error 
unMarshaling RemotelinkRepoPattern")
-               }
-       }
        result := &TransformationRules{
-               RemotelinkCommitShaPattern: rule.RemotelinkCommitShaPattern,
-               RemotelinkRepoPattern:      remotelinkRepoPattern,
-               StatusMappings:             statusMapping,
-               TypeMappings:               typeMapping,
+               StatusMappings: statusMapping,
+               TypeMappings:   typeMapping,
        }
        return result, nil
 }
@@ -112,8 +103,6 @@ type StatusMappings map[string]string
 type TypeMappings map[string]string
 
 type TransformationRules struct {
-       RemotelinkCommitShaPattern string         
`mapstructure:"remotelinkCommitShaPattern,omitempty" 
json:"remotelinkCommitShaPattern" gorm:"type:varchar(255)"`
-       RemotelinkRepoPattern      []string       
`mapstructure:"remotelinkRepoPattern,omitempty" json:"remotelinkRepoPattern"`
-       TypeMappings               TypeMappings   `json:"typeMappings"`
-       StatusMappings             StatusMappings `json:"statusMappings"`
+       TypeMappings   TypeMappings   `json:"typeMappings"`
+       StatusMappings StatusMappings `json:"statusMappings"`
 }
diff --git a/config-ui/src/plugins/register/tapd/config.tsx 
b/config-ui/src/plugins/register/tapd/config.tsx
index c09576633..cd1fb77ad 100644
--- a/config-ui/src/plugins/register/tapd/config.tsx
+++ b/config-ui/src/plugins/register/tapd/config.tsx
@@ -77,6 +77,5 @@ export const TAPDConfig: PluginConfigType = {
   transformation: {
     typeMappings: {},
     statusMappings: {},
-    remotelinkCommitShaPattern: '/commit/([0-9a-f]{40})$/',
   },
 };
diff --git a/config-ui/src/plugins/register/tapd/transformation.tsx 
b/config-ui/src/plugins/register/tapd/transformation.tsx
index d9ce06055..5f52408fe 100644
--- a/config-ui/src/plugins/register/tapd/transformation.tsx
+++ b/config-ui/src/plugins/register/tapd/transformation.tsx
@@ -291,47 +291,6 @@ export const TapdTransformation = ({ connectionId, 
scopeId, transformation, setT
           </div>
         </div>
       </div>
-      <Divider />
-      {/* Cross-domain */}
-      <div>
-        <h2>Cross-domain</h2>
-        <p>
-          Connect `commits` and `issues` to measure metrics such as{' '}
-          <ExternalLink 
link="https://devlake.apache.org/docs/Metrics/BugCountPer1kLinesOfCode";>
-            Bug Count per 1k Lines of Code
-          </ExternalLink>{' '}
-          or man hour distribution on different work types.
-        </p>
-        <FormGroup
-          inline
-          label={
-            <>
-              <span>Connect Commits and Tapd Issues</span>
-              <HelpTooltip
-                content={
-                  <div>
-                    If you are using remote links to connect commits and 
issues, you can specify the commit SHA pattern.
-                    DevLake will parse the commit_sha from your tapd issues’ 
remote/web links and store the relationship
-                    in the table `issue_commits`.
-                  </div>
-                }
-              />
-            </>
-          }
-        >
-          <InputGroup
-            fill
-            placeholder="/commit/([0-9a-f]{40})$"
-            value={transformation.remotelinkCommitShaPattern ?? ''}
-            onChange={(e) =>
-              setTransformation({
-                ...transformation,
-                remotelinkCommitShaPattern: e.target.value,
-              })
-            }
-          />
-        </FormGroup>
-      </div>
     </S.TransformationWrapper>
   );
 };
diff --git a/config-ui/src/plugins/register/zentao/config.ts 
b/config-ui/src/plugins/register/zentao/config.ts
index eb900df05..a97e4bc0b 100644
--- a/config-ui/src/plugins/register/zentao/config.ts
+++ b/config-ui/src/plugins/register/zentao/config.ts
@@ -33,7 +33,7 @@ export const ZenTaoConfig: PluginConfigType = {
       'name',
       {
         key: 'endpoint',
-        subLabel: 'Provide the Zentao instance API endpoint (Opensource v16+). 
E.g. http://<host>:<port>/api.php/v1',
+        subLabel: 'Provide the Zentao instance API endpoint (Opensource v16+). 
E.g. http://<host>:<port>/api.php/v1 or http://<host>:<port>/zentao/api.php/v1',
       },
       'username',
       'password',


Reply via email to