This is an automated email from the ASF dual-hosted git repository.
warren 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 905ba803c Extract repo from Jira issue remotelink (#4526)
905ba803c is described below
commit 905ba803cf99ec436cbd86151598d9ac84b89e1c
Author: mindlesscloud <[email protected]>
AuthorDate: Tue Feb 28 13:25:34 2023 +0800
Extract repo from Jira issue remotelink (#4526)
* feat: extract repo from renotelink
* refactor: change the type of JiraTransformationRule.RemotelinkRepoPattern
to json.RawMessage
* fix: remove some debug code
---
.../domainlayer/crossdomain/issue_repo_commits.go | 3 +
.../20230222_add_host_namespace_reponame.go | 55 +++++++++
backend/core/models/migrationscripts/register.go | 1 +
backend/plugins/jira/api/transformation_rule.go | 4 +
backend/plugins/jira/e2e/issue_repo_commit_test.go | 63 ++++++++++
...ra_board_issues_for_ConvertIssueRepoCommits.csv | 29 +++++
...a_issue_commits_for_ConvertIssueRepoCommits.csv | 80 +++++++++++++
.../e2e/snapshot_tables/issue_repo_commits.csv | 80 +++++++++++++
.../migrationscripts/20230223_add_repo_pattern.go | 48 ++++++++
.../jira/models/migrationscripts/register.go | 1 +
.../plugins/jira/models/transformation_rules.go | 28 ++++-
.../jira/tasks/issue_repo_commit_convertor.go | 44 ++++++-
.../jira/tasks/issue_repo_commit_convertor_test.go | 131 +++++++++++++++++++++
backend/plugins/jira/tasks/task_data.go | 33 +++---
14 files changed, 579 insertions(+), 21 deletions(-)
diff --git a/backend/core/models/domainlayer/crossdomain/issue_repo_commits.go
b/backend/core/models/domainlayer/crossdomain/issue_repo_commits.go
index 8f864ba47..911c984c3 100644
--- a/backend/core/models/domainlayer/crossdomain/issue_repo_commits.go
+++ b/backend/core/models/domainlayer/crossdomain/issue_repo_commits.go
@@ -26,6 +26,9 @@ type IssueRepoCommit struct {
IssueId string `gorm:"primaryKey;type:varchar(255)"`
RepoUrl string `gorm:"primaryKey;type:varchar(255)"`
CommitSha string `gorm:"primaryKey;type:varchar(255)"`
+ Host string `gorm:"type:varchar(255)"`
+ Namespace string `gorm:"type:varchar(255)"`
+ RepoName string `gorm:"type:varchar(255)"`
}
func (IssueRepoCommit) TableName() string {
diff --git
a/backend/core/models/migrationscripts/20230222_add_host_namespace_reponame.go
b/backend/core/models/migrationscripts/20230222_add_host_namespace_reponame.go
new file mode 100644
index 000000000..b1f9c122b
--- /dev/null
+++
b/backend/core/models/migrationscripts/20230222_add_host_namespace_reponame.go
@@ -0,0 +1,55 @@
+/*
+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 migrationscripts
+
+import (
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/helpers/migrationhelper"
+)
+
+var _ plugin.MigrationScript = (*addHostNamespaceRepoName)(nil)
+
+type IssueRepoCommit20220222 struct {
+ Host string `gorm:"type:varchar(255)"`
+ Namespace string `gorm:"type:varchar(255)"`
+ RepoName string `gorm:"type:varchar(255)"`
+}
+
+func (IssueRepoCommit20220222) TableName() string {
+ return "issue_repo_commits"
+}
+
+type addHostNamespaceRepoName struct{}
+
+func (script *addHostNamespaceRepoName) Up(basicRes context.BasicRes)
errors.Error {
+
+ return migrationhelper.AutoMigrateTables(
+ basicRes,
+ &IssueRepoCommit20220222{},
+ )
+}
+
+func (*addHostNamespaceRepoName) Version() uint64 {
+ return 20230222153154
+}
+
+func (*addHostNamespaceRepoName) Name() string {
+ return "add host, namespace, repo_name to issue_repo_commits"
+}
diff --git a/backend/core/models/migrationscripts/register.go
b/backend/core/models/migrationscripts/register.go
index c779d44a7..a09acdbeb 100644
--- a/backend/core/models/migrationscripts/register.go
+++ b/backend/core/models/migrationscripts/register.go
@@ -74,5 +74,6 @@ func All() []plugin.MigrationScript {
new(modifyIssueStorypointToFloat64),
new(addCommitShaIndex),
new(removeCreatedDateAfterFromCollectorMeta20230223),
+ new(addHostNamespaceRepoName),
}
}
diff --git a/backend/plugins/jira/api/transformation_rule.go
b/backend/plugins/jira/api/transformation_rule.go
index 72717b15b..5121b3474 100644
--- a/backend/plugins/jira/api/transformation_rule.go
+++ b/backend/plugins/jira/api/transformation_rule.go
@@ -79,6 +79,10 @@ func UpdateTransformationRule(input
*plugin.ApiResourceInput) (*plugin.ApiResour
return nil, errors.Default.Wrap(err, "error decoding map into
transformationRule")
}
old.ID = transformationRuleId
+ err = old.VerifyRegexp()
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error verify the regexps
of transformationRule")
+ }
err = basicRes.GetDal().Update(&old, dal.Where("id = ?",
transformationRuleId))
if err != nil {
if basicRes.GetDal().IsDuplicationError(err) {
diff --git a/backend/plugins/jira/e2e/issue_repo_commit_test.go
b/backend/plugins/jira/e2e/issue_repo_commit_test.go
new file mode 100644
index 000000000..3535aeaec
--- /dev/null
+++ b/backend/plugins/jira/e2e/issue_repo_commit_test.go
@@ -0,0 +1,63 @@
+/*
+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 e2e
+
+import (
+
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
+ "github.com/apache/incubator-devlake/helpers/e2ehelper"
+ "github.com/apache/incubator-devlake/plugins/jira/impl"
+ "github.com/apache/incubator-devlake/plugins/jira/models"
+ "github.com/apache/incubator-devlake/plugins/jira/tasks"
+ "testing"
+)
+
+func TestConvertIssueRepoCommitsDataFlow(t *testing.T) {
+ var plugin impl.Jira
+ dataflowTester := e2ehelper.NewDataFlowTester(t, "jira", plugin)
+
+ taskData := &tasks.JiraTaskData{
+ Options: &tasks.JiraOptions{
+ ConnectionId: 2,
+ BoardId: 8,
+ TransformationRules: &tasks.JiraTransformationRule{
+ RemotelinkCommitShaPattern: `.*/commit/(.*)`,
+ RemotelinkRepoPattern: []string{
+
`https://bitbucket.org/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commits/(?P<commit_sha>\w{40})`,
+
`https://gitlab.com/(?P<namespace>\S+)/(?P<repo_name>\S+)/-/commit/(?P<commit_sha>\w{40})`,
+
`https://github.com/(?P<namespace>[^/]+)/(?P<repo_name>[^/]+)/commit/(?P<commit_sha>\w{40})`,
+ },
+ },
+ },
+ }
+ dataflowTester.FlushTabler(&crossdomain.IssueRepoCommit{})
+
dataflowTester.ImportCsvIntoTabler("./snapshot_tables/_tool_jira_issue_commits_for_ConvertIssueRepoCommits.csv",
&models.JiraIssueCommit{})
+
dataflowTester.ImportCsvIntoTabler("./snapshot_tables/_tool_jira_board_issues_for_ConvertIssueRepoCommits.csv",
&models.JiraBoardIssue{})
+ dataflowTester.Subtask(tasks.ConvertIssueRepoCommitsMeta, taskData)
+ dataflowTester.VerifyTable(
+ crossdomain.IssueRepoCommit{},
+ "./snapshot_tables/issue_repo_commits.csv",
+ e2ehelper.ColumnWithRawData(
+ "issue_id",
+ "repo_url",
+ "commit_sha",
+ "host",
+ "namespace",
+ "repo_name",
+ ),
+ )
+}
diff --git
a/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues_for_ConvertIssueRepoCommits.csv
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues_for_ConvertIssueRepoCommits.csv
new file mode 100644
index 000000000..5ea7371b0
--- /dev/null
+++
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues_for_ConvertIssueRepoCommits.csv
@@ -0,0 +1,29 @@
+connection_id,board_id,issue_id,_raw_data_params,_raw_data_table,_raw_data_id,_raw_data_remark
+2,8,10063,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12441,
+2,8,10064,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12442,
+2,8,10065,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12444,
+2,8,10066,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12445,
+2,8,10139,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12446,
+2,8,10145,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12447,
+2,8,10159,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12450,
+2,8,10202,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12451,
+2,8,10203,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12452,
+2,8,10204,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12453,
+2,8,10205,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12454,
+2,8,10206,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12455,
+2,8,10207,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12456,
+2,8,10213,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12457,
+2,8,10218,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12458,
+2,8,10220,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12460,
+2,8,10222,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12461,
+2,8,10225,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12462,
+2,8,10228,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12463,
+2,8,10229,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12464,
+2,8,10233,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12465,
+2,8,10236,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12466,
+2,8,10240,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12467,
+2,8,10244,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12468,
+2,8,10245,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12469,
+2,8,10254,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12470,
+2,8,10255,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12471,
+2,8,10258,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12472,
diff --git
a/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_issue_commits_for_ConvertIssueRepoCommits.csv
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_issue_commits_for_ConvertIssueRepoCommits.csv
new file mode 100644
index 000000000..d4555dbb2
--- /dev/null
+++
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_issue_commits_for_ConvertIssueRepoCommits.csv
@@ -0,0 +1,80 @@
+"created_at","updated_at","_raw_data_params","_raw_data_table","_raw_data_id","_raw_data_remark","connection_id","issue_id","commit_sha","commit_url"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",1,"",2,10063,"8748a066cbaf67b15e86f2c636f9931347e987cf","https://gitlab.com/meri.co/vdev.co/-/commit/8748a066cbaf67b15e86f2c636f9931347e987cf"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",2,"",2,10064,"abc0892edaee00dd7ee268dbee71620407a29bca","https://gitlab.com/meri.co/vdev.co/-/commit/abc0892edaee00dd7ee268dbee71620407a29bca"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":3,""BoardId"":8}","_raw_jira_api_remotelinks",3,"",2,10064,"e6bde456807818c5c78d7b265964d6d48b653af6","https://gitlab.com/meri.co/vdev.co/-/commit/e6bde456807818c5c78d7b265964d6d48b653af6"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",4,"",2,10065,"8f91020bcf684c6ad07adfafa3d8a2f826686c42","https://gitlab.com/meri.co/vdev.co/-/commit/8f91020bcf684c6ad07adfafa3d8a2f826686c42"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",5,"",2,10066,"0dfe2e9ed88ad4e27f825d9b67d4d56ac983c5ef","https://gitlab.com/meri.co/vdev.co/-/commit/0dfe2e9ed88ad4e27f825d9b67d4d56ac983c5ef"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":1,""BoardId"":8}","_raw_jira_api_remotelinks",13,"",2,10139,"8993c04249e9d549e8950daec86717548c53c423","https://gitlab.com/meri.co/vdev.co/-/commit/8993c04249e9d549e8950daec86717548c53c423"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",19,"",2,10145,"07aa2ebed68e286dc51a7e0082031196a6135f74","https://gitlab.com/meri.co/vdev.co/-/commit/07aa2ebed68e286dc51a7e0082031196a6135f74"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":3}","_raw_jira_api_remotelinks",20,"",2,10145,"d70d6687e06304d9b6e0cb32b3f8c0f0928400f7","https://gitlab.com/meri.co/vdev.co/-/commit/d70d6687e06304d9b6e0cb32b3f8c0f0928400f7"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",21,"",2,10145,"ef5ab26111744f65f5191b247767a473c70d6c95","https://gitlab.com/meri.co/vdev.co/-/commit/ef5ab26111744f65f5191b247767a473c70d6c95"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":5}","_raw_jira_api_remotelinks",36,"",2,10159,"d28785ff09229ac9e3c6734f0c97466ab00eb4da","https://gitlab.com/meri.co/vdev.co/-/commit/d28785ff09229ac9e3c6734f0c97466ab00eb4da"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",38,"",2,10202,"0ab12c4d4064003602edceed900d1456b6209894","https://gitlab.com/meri.co/vdev.co/-/commit/0ab12c4d4064003602edceed900d1456b6209894"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",39,"",2,10203,"980e9fe7bc3e22a0409f7241a024eaf9c53680dd","https://gitlab.com/meri.co/vdev.co/-/commit/980e9fe7bc3e22a0409f7241a024eaf9c53680dd"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",40,"",2,10204,"f399421652f6ce0495d2c6bae66406cbeb68501f","https://gitlab.com/meri.co/vdev.co/-/commit/f399421652f6ce0495d2c6bae66406cbeb68501f"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",41,"",2,10205,"149ed453d5353850dee5c6112178f77480dcadfd","https://gitlab.com/meri.co/vdev.co/-/commit/149ed453d5353850dee5c6112178f77480dcadfd"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",42,"",2,10206,"8e95965d9aae9622b2ec8e5bd0ed5a30238d400e","https://gitlab.com/meri.co/vdev.co/-/commit/8e95965d9aae9622b2ec8e5bd0ed5a30238d400e"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",43,"",2,10207,"a65c311ee04f002840e22c8f9c8fcdfe00c792ee","https://gitlab.com/meri.co/vdev.co/-/commit/a65c311ee04f002840e22c8f9c8fcdfe00c792ee"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",44,"",2,10213,"f33cbc960a80075b30efe2daa32555f8bccfdc23","https://gitlab.com/meri.co/vdev.co/-/commit/f33cbc960a80075b30efe2daa32555f8bccfdc23"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",45,"",2,10218,"02e31edfe6036baf91a4924e77b83dc276c9fab6","https://gitlab.com/meri.co/vdev.co/-/commit/02e31edfe6036baf91a4924e77b83dc276c9fab6"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",46,"",2,10218,"34cf50c449a390754002df1e6942b485ef6f0211","https://gitlab.com/meri.co/vdev.co/-/commit/34cf50c449a390754002df1e6942b485ef6f0211"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",47,"",2,10220,"a148367d7987597b11386cd8e70ae3d721190ff3","https://gitlab.com/meri.co/vdev.co/-/commit/a148367d7987597b11386cd8e70ae3d721190ff3"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",48,"",2,10222,"fba5215ae3cf712e2bf282341a497ba4650f24eb","https://gitlab.com/meri.co/vdev.co/-/commit/fba5215ae3cf712e2bf282341a497ba4650f24eb"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",50,"",2,10225,"f53e78b4a3615d33bf8a8f60d9eaef18ac1364ba","https://gitlab.com/meri.co/vdev.co/-/commit/f53e78b4a3615d33bf8a8f60d9eaef18ac1364ba"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",51,"",2,10228,"59f7687f0206ce13071ba185ec506c2a8872ac64","https://gitlab.com/meri.co/vdev.co/-/commit/59f7687f0206ce13071ba185ec506c2a8872ac64"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",52,"",2,10229,"671af58d588adf6f9cf6ba80057b1488cc3021bd","https://gitlab.com/meri.co/vdev.co/-/commit/671af58d588adf6f9cf6ba80057b1488cc3021bd"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",60,"",2,10233,"14b62ef2c2b9f9a45d4d00ec489babfa88e8cfd5","https://gitlab.com/meri.co/vdev.co/-/commit/14b62ef2c2b9f9a45d4d00ec489babfa88e8cfd5"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",62,"",2,10233,"3748c4aaf1eabe8127a94d6b3c72365c594d6b72","https://gitlab.com/meri.co/vdev.co/-/commit/3748c4aaf1eabe8127a94d6b3c72365c594d6b72"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",58,"",2,10233,"3b23c7006da255946bd7ef08c854cde089160939","https://gitlab.com/meri.co/vdev.co/-/commit/3b23c7006da255946bd7ef08c854cde089160939"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",53,"",2,10233,"58e5c84befc02505477a142c56b501310af9408a","https://gitlab.com/meri.co/vdev.co/-/commit/58e5c84befc02505477a142c56b501310af9408a"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",55,"",2,10233,"60ba46213cc0ab0e3f02d7bb15bea47c13adfa80","https://gitlab.com/meri.co/vdev.co/-/commit/60ba46213cc0ab0e3f02d7bb15bea47c13adfa80"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",57,"",2,10233,"64fd3d264ddc9b84d927ef1ebad70386a4aa200a","https://gitlab.com/meri.co/vdev.co/-/commit/64fd3d264ddc9b84d927ef1ebad70386a4aa200a"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",59,"",2,10233,"b4c5198ecb3295599ff7390939a3428a12acad5f","https://gitlab.com/meri.co/vdev.co/-/commit/b4c5198ecb3295599ff7390939a3428a12acad5f"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",56,"",2,10233,"e2a829f16a9659bf88c5abf750873f083513bc02","https://gitlab.com/meri.co/vdev.co/-/commit/e2a829f16a9659bf88c5abf750873f083513bc02"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",54,"",2,10233,"f55cc8a695302ec5faa18ecc422b4c1c2b27bb6b","https://gitlab.com/meri.co/vdev.co/-/commit/f55cc8a695302ec5faa18ecc422b4c1c2b27bb6b"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",65,"",2,10236,"27d83e6f7d45a820b449555386374cd6af2b4a5d","https://gitlab.com/meri.co/vdev.co/-/commit/27d83e6f7d45a820b449555386374cd6af2b4a5d"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",66,"",2,10236,"2f0044cc78a62bcbf5f8f0e69cde1255cc6ab8bc","https://gitlab.com/meri.co/vdev.co/-/commit/2f0044cc78a62bcbf5f8f0e69cde1255cc6ab8bc"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",63,"",2,10236,"6c44dd89f6a9826dc6f832ce7c5707e8b3537e72","https://gitlab.com/meri.co/vdev.co/-/commit/6c44dd89f6a9826dc6f832ce7c5707e8b3537e72"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",64,"",2,10236,"b9922dba05eb24c8cf5f30a50d31aa2d1544e37c","https://gitlab.com/meri.co/vdev.co/-/commit/b9922dba05eb24c8cf5f30a50d31aa2d1544e37c"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",67,"",2,10240,"eb5985b7583a8de5bbb9defae79c29be20e246c9","https://gitlab.com/meri.co/vdev.co/-/commit/eb5985b7583a8de5bbb9defae79c29be20e246c9"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",68,"",2,10244,"9448fc7f7d89e36c8e9d5bc15070a0cc88f610eb","https://gitlab.com/meri.co/vdev.co/-/commit/9448fc7f7d89e36c8e9d5bc15070a0cc88f610eb"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",81,"",2,10245,"0c8003d3244509ca77b02f7806ccce2105a34235","https://gitlab.com/meri.co/vdev.co/-/commit/0c8003d3244509ca77b02f7806ccce2105a34235"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",83,"",2,10245,"15d98b3f066c667bdc533a42e0b88433a94f6306","https://gitlab.com/meri.co/vdev.co/-/commit/15d98b3f066c667bdc533a42e0b88433a94f6306"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",69,"",2,10245,"1a48756d4d9f23ad3e1d1175c31767c4c3501f7a","https://gitlab.com/meri.co/vdev.co/-/commit/1a48756d4d9f23ad3e1d1175c31767c4c3501f7a"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",85,"",2,10245,"22307892a6cddaafc40bd129b559bcb731beeabe","https://gitlab.com/meri.co/vdev.co/-/commit/22307892a6cddaafc40bd129b559bcb731beeabe"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",75,"",2,10245,"2307b8e839b38e5a1b4cb989320cfef9f36eb120","https://gitlab.com/meri.co/vdev.co/-/commit/2307b8e839b38e5a1b4cb989320cfef9f36eb120"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",90,"",2,10245,"23cf67b7b3b9352941094f77710935443cd85724","https://gitlab.com/meri.co/vdev.co/-/commit/23cf67b7b3b9352941094f77710935443cd85724"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",78,"",2,10245,"3fa323caafb7861402489e3055c57ed4558ffeb6","https://gitlab.com/meri.co/vdev.co/-/commit/3fa323caafb7861402489e3055c57ed4558ffeb6"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",72,"",2,10245,"5a5bfdbc5ed92dfecc7141f29dc7c077a5c68f0d","https://gitlab.com/meri.co/vdev.co/-/commit/5a5bfdbc5ed92dfecc7141f29dc7c077a5c68f0d"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",82,"",2,10245,"61b0bd3c2ef25aa6392717ab07a8b407654650f1","https://gitlab.com/meri.co/vdev.co/-/commit/61b0bd3c2ef25aa6392717ab07a8b407654650f1"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",86,"",2,10245,"6b1d2bb920d2a55ea9eda242d61cf31d8f831078","https://gitlab.com/meri.co/vdev.co/-/commit/6b1d2bb920d2a55ea9eda242d61cf31d8f831078"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",88,"",2,10245,"90574eecd6d016b070b21a0ae370bf78acc71aea","https://gitlab.com/meri.co/vdev.co/-/commit/90574eecd6d016b070b21a0ae370bf78acc71aea"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",73,"",2,10245,"91a1dde3b40a2e364aaa0230ac9771805ae51b13","https://gitlab.com/meri.co/vdev.co/-/commit/91a1dde3b40a2e364aaa0230ac9771805ae51b13"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",79,"",2,10245,"a61cb79f68a95e46ad625b949d7cda5c6b8f23f9","https://gitlab.com/meri.co/vdev.co/-/commit/a61cb79f68a95e46ad625b949d7cda5c6b8f23f9"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",89,"",2,10245,"b4a222c589fd7585d1337fecb3f841dfa575df34","https://gitlab.com/meri.co/vdev.co/-/commit/b4a222c589fd7585d1337fecb3f841dfa575df34"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",74,"",2,10245,"c1aae3eb5fddc2bcec27e1a7f0a7d0cc58532d9b","https://gitlab.com/meri.co/vdev.co/-/commit/c1aae3eb5fddc2bcec27e1a7f0a7d0cc58532d9b"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",87,"",2,10245,"cccc754c7fd22ba5b5d384b50ca13fb848760693","https://gitlab.com/meri.co/vdev.co/-/commit/cccc754c7fd22ba5b5d384b50ca13fb848760693"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",84,"",2,10245,"cf5352eabbf9054f82934f71699afc3afd19f49b","https://gitlab.com/meri.co/vdev.co/-/commit/cf5352eabbf9054f82934f71699afc3afd19f49b"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",80,"",2,10245,"dce6cce39f5db84223fbefd5898fb5bb3dee0872","https://gitlab.com/meri.co/vdev.co/-/commit/dce6cce39f5db84223fbefd5898fb5bb3dee0872"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",77,"",2,10245,"e51801c323245eb4ffa06cd6840885a3e875f998","https://gitlab.com/meri.co/vdev.co/-/commit/e51801c323245eb4ffa06cd6840885a3e875f998"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",70,"",2,10245,"f0123e5de6dc1f832adfcace6f2882fd7b42a7eb","https://gitlab.com/meri.co/vdev.co/-/commit/f0123e5de6dc1f832adfcace6f2882fd7b42a7eb"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",71,"",2,10245,"f6cc2639a9ca65045448eb2ad4434f09bfc956a2","https://gitlab.com/meri.co/vdev.co/-/commit/f6cc2639a9ca65045448eb2ad4434f09bfc956a2"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",76,"",2,10245,"fa9eacc59249179d1e88e6917673c3f8f3c1be4d","https://gitlab.com/meri.co/vdev.co/-/commit/fa9eacc59249179d1e88e6917673c3f8f3c1be4d"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",97,"",2,10254,"207bd0ad7e526354a3ccf01fc49c6d46631635ab","https://gitlab.com/meri.co/vdev.co/-/commit/207bd0ad7e526354a3ccf01fc49c6d46631635ab"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",92,"",2,10254,"48e2b22c92e53a92925930619cc2c7d9a3164b6b","https://gitlab.com/meri.co/vdev.co/-/commit/48e2b22c92e53a92925930619cc2c7d9a3164b6b"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",95,"",2,10254,"5d974f16941a4141fc204201bf44312b90ae4efc","https://gitlab.com/meri.co/vdev.co/-/commit/5d974f16941a4141fc204201bf44312b90ae4efc"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",93,"",2,10254,"846a273648d3aa3a358d76c0ee5a6f77c43b8833","https://gitlab.com/meri.co/vdev.co/-/commit/846a273648d3aa3a358d76c0ee5a6f77c43b8833"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",96,"",2,10254,"976bd42fbc2ccb9f0a464660926d0694998e1343","https://gitlab.com/meri.co/vdev.co/-/commit/976bd42fbc2ccb9f0a464660926d0694998e1343"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",98,"",2,10254,"dc33c42a35370a91bdccd207ba9821f430a0f0df","https://gitlab.com/meri.co/vdev.co/-/commit/dc33c42a35370a91bdccd207ba9821f430a0f0df"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",91,"",2,10254,"dc55075222445b8cd6bcc090179c7825fe5f8cf5","https://gitlab.com/meri.co/vdev.co/-/commit/dc55075222445b8cd6bcc090179c7825fe5f8cf5"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",94,"",2,10254,"fc26876aea9e9658ae10214bac94508b85ef41ce","https://gitlab.com/meri.co/vdev.co/-/commit/fc26876aea9e9658ae10214bac94508b85ef41ce"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",104,"",2,10255,"2bf4c9723d0e7e899c205c2f5e107f29df754f9b","https://gitlab.com/meri.co/vdev.co/-/commit/2bf4c9723d0e7e899c205c2f5e107f29df754f9b"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",103,"",2,10255,"5c45f15376d303f5b3b4577471d06b1139ce32e7","https://gitlab.com/meri.co/vdev.co/-/commit/5c45f15376d303f5b3b4577471d06b1139ce32e7"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",100,"",2,10255,"6d3592a0a70225a62af3152b4623e4b2caf7d85e","https://gitlab.com/meri.co/vdev.co/-/commit/6d3592a0a70225a62af3152b4623e4b2caf7d85e"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",99,"",2,10255,"73eddda7e14eceeabd98dd768ee37d19a0fbb80a","https://gitlab.com/meri.co/vdev.co/-/commit/73eddda7e14eceeabd98dd768ee37d19a0fbb80a"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",106,"",2,10255,"a802d5edf833b8fa70189783ebe21174ff333c69","https://gitlab.com/meri.co/vdev.co/-/commit/a802d5edf833b8fa70189783ebe21174ff333c69"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",102,"",2,10255,"a8cffff240ae813495d0fcf229664ff4d5661efa","https://gitlab.com/meri.co/vdev.co/-/commit/a8cffff240ae813495d0fcf229664ff4d5661efa"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",101,"",2,10255,"d7b0f04186e2f5aba14b9c543d4b02be2a6dd5c2","https://gitlab.com/meri.co/vdev.co/-/commit/d7b0f04186e2f5aba14b9c543d4b02be2a6dd5c2"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",105,"",2,10255,"dad016718d6a1f629b98df95b9021932e03a2877","https://gitlab.com/meri.co/vdev.co/-/commit/dad016718d6a1f629b98df95b9021932e03a2877"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",108,"",2,10258,"25988d15d2a977cbf440c6728e90b3cbfa667ad2","https://gitlab.com/meri.co/vdev.co/-/commit/25988d15d2a977cbf440c6728e90b3cbfa667ad2"
+"2022-10-25 08:36:38.628","2022-10-25
08:36:38.628","{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_remotelinks",107,"",2,10258,"29380320f47ca4d687d29c8395931ca5d8a606e7","https://gitlab.com/meri.co/vdev.co/-/commit/29380320f47ca4d687d29c8395931ca5d8a606e7"
diff --git a/backend/plugins/jira/e2e/snapshot_tables/issue_repo_commits.csv
b/backend/plugins/jira/e2e/snapshot_tables/issue_repo_commits.csv
new file mode 100644
index 000000000..7227a7d54
--- /dev/null
+++ b/backend/plugins/jira/e2e/snapshot_tables/issue_repo_commits.csv
@@ -0,0 +1,80 @@
+issue_id,repo_url,commit_sha,host,namespace,repo_name,_raw_data_params,_raw_data_table,_raw_data_id,_raw_data_remark
+jira:JiraIssue:2:10063,https://gitlab.com/meri.co/vdev.co.git,8748a066cbaf67b15e86f2c636f9931347e987cf,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,1,
+jira:JiraIssue:2:10064,https://gitlab.com/meri.co/vdev.co.git,abc0892edaee00dd7ee268dbee71620407a29bca,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,2,
+jira:JiraIssue:2:10064,https://gitlab.com/meri.co/vdev.co.git,e6bde456807818c5c78d7b265964d6d48b653af6,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":3,""BoardId"":8}",_raw_jira_api_remotelinks,3,
+jira:JiraIssue:2:10065,https://gitlab.com/meri.co/vdev.co.git,8f91020bcf684c6ad07adfafa3d8a2f826686c42,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,4,
+jira:JiraIssue:2:10066,https://gitlab.com/meri.co/vdev.co.git,0dfe2e9ed88ad4e27f825d9b67d4d56ac983c5ef,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,5,
+jira:JiraIssue:2:10139,https://gitlab.com/meri.co/vdev.co.git,8993c04249e9d549e8950daec86717548c53c423,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":1,""BoardId"":8}",_raw_jira_api_remotelinks,13,
+jira:JiraIssue:2:10145,https://gitlab.com/meri.co/vdev.co.git,07aa2ebed68e286dc51a7e0082031196a6135f74,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,19,
+jira:JiraIssue:2:10145,https://gitlab.com/meri.co/vdev.co.git,d70d6687e06304d9b6e0cb32b3f8c0f0928400f7,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":3}",_raw_jira_api_remotelinks,20,
+jira:JiraIssue:2:10145,https://gitlab.com/meri.co/vdev.co.git,ef5ab26111744f65f5191b247767a473c70d6c95,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,21,
+jira:JiraIssue:2:10159,https://gitlab.com/meri.co/vdev.co.git,d28785ff09229ac9e3c6734f0c97466ab00eb4da,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":5}",_raw_jira_api_remotelinks,36,
+jira:JiraIssue:2:10202,https://gitlab.com/meri.co/vdev.co.git,0ab12c4d4064003602edceed900d1456b6209894,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,38,
+jira:JiraIssue:2:10203,https://gitlab.com/meri.co/vdev.co.git,980e9fe7bc3e22a0409f7241a024eaf9c53680dd,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,39,
+jira:JiraIssue:2:10204,https://gitlab.com/meri.co/vdev.co.git,f399421652f6ce0495d2c6bae66406cbeb68501f,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,40,
+jira:JiraIssue:2:10205,https://gitlab.com/meri.co/vdev.co.git,149ed453d5353850dee5c6112178f77480dcadfd,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,41,
+jira:JiraIssue:2:10206,https://gitlab.com/meri.co/vdev.co.git,8e95965d9aae9622b2ec8e5bd0ed5a30238d400e,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,42,
+jira:JiraIssue:2:10207,https://gitlab.com/meri.co/vdev.co.git,a65c311ee04f002840e22c8f9c8fcdfe00c792ee,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,43,
+jira:JiraIssue:2:10213,https://gitlab.com/meri.co/vdev.co.git,f33cbc960a80075b30efe2daa32555f8bccfdc23,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,44,
+jira:JiraIssue:2:10218,https://gitlab.com/meri.co/vdev.co.git,02e31edfe6036baf91a4924e77b83dc276c9fab6,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,45,
+jira:JiraIssue:2:10218,https://gitlab.com/meri.co/vdev.co.git,34cf50c449a390754002df1e6942b485ef6f0211,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,46,
+jira:JiraIssue:2:10220,https://gitlab.com/meri.co/vdev.co.git,a148367d7987597b11386cd8e70ae3d721190ff3,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,47,
+jira:JiraIssue:2:10222,https://gitlab.com/meri.co/vdev.co.git,fba5215ae3cf712e2bf282341a497ba4650f24eb,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,48,
+jira:JiraIssue:2:10225,https://gitlab.com/meri.co/vdev.co.git,f53e78b4a3615d33bf8a8f60d9eaef18ac1364ba,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,50,
+jira:JiraIssue:2:10228,https://gitlab.com/meri.co/vdev.co.git,59f7687f0206ce13071ba185ec506c2a8872ac64,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,51,
+jira:JiraIssue:2:10229,https://gitlab.com/meri.co/vdev.co.git,671af58d588adf6f9cf6ba80057b1488cc3021bd,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,52,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,14b62ef2c2b9f9a45d4d00ec489babfa88e8cfd5,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,60,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,3748c4aaf1eabe8127a94d6b3c72365c594d6b72,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,62,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,3b23c7006da255946bd7ef08c854cde089160939,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,58,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,58e5c84befc02505477a142c56b501310af9408a,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,53,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,60ba46213cc0ab0e3f02d7bb15bea47c13adfa80,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,55,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,64fd3d264ddc9b84d927ef1ebad70386a4aa200a,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,57,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,b4c5198ecb3295599ff7390939a3428a12acad5f,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,59,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,e2a829f16a9659bf88c5abf750873f083513bc02,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,56,
+jira:JiraIssue:2:10233,https://gitlab.com/meri.co/vdev.co.git,f55cc8a695302ec5faa18ecc422b4c1c2b27bb6b,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,54,
+jira:JiraIssue:2:10236,https://gitlab.com/meri.co/vdev.co.git,27d83e6f7d45a820b449555386374cd6af2b4a5d,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,65,
+jira:JiraIssue:2:10236,https://gitlab.com/meri.co/vdev.co.git,2f0044cc78a62bcbf5f8f0e69cde1255cc6ab8bc,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,66,
+jira:JiraIssue:2:10236,https://gitlab.com/meri.co/vdev.co.git,6c44dd89f6a9826dc6f832ce7c5707e8b3537e72,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,63,
+jira:JiraIssue:2:10236,https://gitlab.com/meri.co/vdev.co.git,b9922dba05eb24c8cf5f30a50d31aa2d1544e37c,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,64,
+jira:JiraIssue:2:10240,https://gitlab.com/meri.co/vdev.co.git,eb5985b7583a8de5bbb9defae79c29be20e246c9,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,67,
+jira:JiraIssue:2:10244,https://gitlab.com/meri.co/vdev.co.git,9448fc7f7d89e36c8e9d5bc15070a0cc88f610eb,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,68,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,0c8003d3244509ca77b02f7806ccce2105a34235,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,81,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,15d98b3f066c667bdc533a42e0b88433a94f6306,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,83,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,1a48756d4d9f23ad3e1d1175c31767c4c3501f7a,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,69,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,22307892a6cddaafc40bd129b559bcb731beeabe,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,85,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,2307b8e839b38e5a1b4cb989320cfef9f36eb120,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,75,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,23cf67b7b3b9352941094f77710935443cd85724,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,90,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,3fa323caafb7861402489e3055c57ed4558ffeb6,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,78,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,5a5bfdbc5ed92dfecc7141f29dc7c077a5c68f0d,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,72,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,61b0bd3c2ef25aa6392717ab07a8b407654650f1,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,82,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,6b1d2bb920d2a55ea9eda242d61cf31d8f831078,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,86,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,90574eecd6d016b070b21a0ae370bf78acc71aea,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,88,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,91a1dde3b40a2e364aaa0230ac9771805ae51b13,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,73,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,a61cb79f68a95e46ad625b949d7cda5c6b8f23f9,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,79,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,b4a222c589fd7585d1337fecb3f841dfa575df34,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,89,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,c1aae3eb5fddc2bcec27e1a7f0a7d0cc58532d9b,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,74,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,cccc754c7fd22ba5b5d384b50ca13fb848760693,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,87,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,cf5352eabbf9054f82934f71699afc3afd19f49b,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,84,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,dce6cce39f5db84223fbefd5898fb5bb3dee0872,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,80,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,e51801c323245eb4ffa06cd6840885a3e875f998,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,77,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,f0123e5de6dc1f832adfcace6f2882fd7b42a7eb,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,70,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,f6cc2639a9ca65045448eb2ad4434f09bfc956a2,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,71,
+jira:JiraIssue:2:10245,https://gitlab.com/meri.co/vdev.co.git,fa9eacc59249179d1e88e6917673c3f8f3c1be4d,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,76,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,207bd0ad7e526354a3ccf01fc49c6d46631635ab,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,97,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,48e2b22c92e53a92925930619cc2c7d9a3164b6b,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,92,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,5d974f16941a4141fc204201bf44312b90ae4efc,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,95,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,846a273648d3aa3a358d76c0ee5a6f77c43b8833,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,93,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,976bd42fbc2ccb9f0a464660926d0694998e1343,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,96,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,dc33c42a35370a91bdccd207ba9821f430a0f0df,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,98,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,dc55075222445b8cd6bcc090179c7825fe5f8cf5,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,91,
+jira:JiraIssue:2:10254,https://gitlab.com/meri.co/vdev.co.git,fc26876aea9e9658ae10214bac94508b85ef41ce,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,94,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,2bf4c9723d0e7e899c205c2f5e107f29df754f9b,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,104,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,5c45f15376d303f5b3b4577471d06b1139ce32e7,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,103,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,6d3592a0a70225a62af3152b4623e4b2caf7d85e,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,100,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,73eddda7e14eceeabd98dd768ee37d19a0fbb80a,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,99,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,a802d5edf833b8fa70189783ebe21174ff333c69,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,106,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,a8cffff240ae813495d0fcf229664ff4d5661efa,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,102,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,d7b0f04186e2f5aba14b9c543d4b02be2a6dd5c2,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,101,
+jira:JiraIssue:2:10255,https://gitlab.com/meri.co/vdev.co.git,dad016718d6a1f629b98df95b9021932e03a2877,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,105,
+jira:JiraIssue:2:10258,https://gitlab.com/meri.co/vdev.co.git,25988d15d2a977cbf440c6728e90b3cbfa667ad2,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,108,
+jira:JiraIssue:2:10258,https://gitlab.com/meri.co/vdev.co.git,29380320f47ca4d687d29c8395931ca5d8a606e7,gitlab.com,meri.co,vdev.co,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_remotelinks,107,
diff --git
a/backend/plugins/jira/models/migrationscripts/20230223_add_repo_pattern.go
b/backend/plugins/jira/models/migrationscripts/20230223_add_repo_pattern.go
new file mode 100644
index 000000000..9c4365f19
--- /dev/null
+++ b/backend/plugins/jira/models/migrationscripts/20230223_add_repo_pattern.go
@@ -0,0 +1,48 @@
+/*
+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 migrationscripts
+
+import (
+ "encoding/json"
+
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/helpers/migrationhelper"
+)
+
+type JiraTransformationRule20230223 struct {
+ RemotelinkRepoPattern json.RawMessage
`mapstructure:"remotelinkRepoPattern,omitempty" json:"remotelinkRepoPattern"`
+}
+
+func (JiraTransformationRule20230223) TableName() string {
+ return "_tool_jira_transformation_rules"
+}
+
+type addCommitRepoPattern struct{}
+
+func (script *addCommitRepoPattern) Up(basicRes context.BasicRes) errors.Error
{
+ return migrationhelper.AutoMigrateTables(basicRes,
&JiraTransformationRule20230223{})
+}
+
+func (*addCommitRepoPattern) Version() uint64 {
+ return 20230223112532
+}
+
+func (*addCommitRepoPattern) Name() string {
+ return "add remotelink_repo_pattern to _tool_jira_transformation_rules"
+}
diff --git a/backend/plugins/jira/models/migrationscripts/register.go
b/backend/plugins/jira/models/migrationscripts/register.go
index be622cf81..780822d40 100644
--- a/backend/plugins/jira/models/migrationscripts/register.go
+++ b/backend/plugins/jira/models/migrationscripts/register.go
@@ -31,5 +31,6 @@ func All() []plugin.MigrationScript {
new(addProjectName20221215),
new(addJiraMultiAuth20230129),
new(removeIssueStdStoryPoint),
+ new(addCommitRepoPattern),
}
}
diff --git a/backend/plugins/jira/models/transformation_rules.go
b/backend/plugins/jira/models/transformation_rules.go
index f98ce4f4a..7e18dabe8 100644
--- a/backend/plugins/jira/models/transformation_rules.go
+++ b/backend/plugins/jira/models/transformation_rules.go
@@ -19,6 +19,9 @@ package models
import (
"encoding/json"
+ "regexp"
+
+ "github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/models/common"
)
@@ -28,9 +31,32 @@ type JiraTransformationRule struct {
EpicKeyField string
`mapstructure:"epicKeyField,omitempty" json:"epicKeyField"
gorm:"type:varchar(255)"`
StoryPointField string
`mapstructure:"storyPointField,omitempty" json:"storyPointField"
gorm:"type:varchar(255)"`
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"`
}
-func (JiraTransformationRule) TableName() string {
+func (r *JiraTransformationRule) TableName() string {
return "_tool_jira_transformation_rules"
}
+
+func (r *JiraTransformationRule) VerifyRegexp() errors.Error {
+ var err error
+ if r.RemotelinkCommitShaPattern != "" {
+ _, err = regexp.Compile(r.RemotelinkCommitShaPattern)
+ if err != nil {
+ return errors.Convert(err)
+ }
+ }
+ var repoPatterns []string
+ err = json.Unmarshal(r.RemotelinkRepoPattern, &repoPatterns)
+ if err != nil {
+ return errors.Convert(err)
+ }
+ for _, pattern := range repoPatterns {
+ _, err = regexp.Compile(pattern)
+ if err != nil {
+ return errors.Convert(err)
+ }
+ }
+ return nil
+}
diff --git a/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
b/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
index d9222939a..08695ec89 100644
--- a/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
+++ b/backend/plugins/jira/tasks/issue_repo_commit_convertor.go
@@ -18,6 +18,11 @@ limitations under the License.
package tasks
import (
+ "net/url"
+ "path"
+ "reflect"
+ "regexp"
+
"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
@@ -25,8 +30,6 @@ import (
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/jira/models"
- "reflect"
- "regexp"
)
var ConvertIssueRepoCommitsMeta = plugin.SubTaskMeta{
@@ -53,6 +56,16 @@ func ConvertIssueRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
if err != nil {
return errors.Default.Wrap(err, "regexp Compile
commitRepoUrlPattern failed")
}
+ var commitRepoUrlRegexps []*regexp.Regexp
+ if tr := data.Options.TransformationRules; tr != nil {
+ for _, s := range tr.RemotelinkRepoPattern {
+ pattern, e := regexp.Compile(s)
+ if e != nil {
+ return errors.Convert(e)
+ }
+ commitRepoUrlRegexps = append(commitRepoUrlRegexps,
pattern)
+ }
+ }
clause := []dal.Clause{
dal.From("_tool_jira_issue_commits jic"),
@@ -83,7 +96,6 @@ func ConvertIssueRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.JiraIssueCommit{}),
Input: cursor,
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
- var result []interface{}
issueCommit := inputRow.(*models.JiraIssueCommit)
item := &crossdomain.IssueRepoCommit{
IssueId:
issueIdGenerator.Generate(connectionId, issueCommit.IssueId),
@@ -95,8 +107,8 @@ func ConvertIssueRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
item.RepoUrl = groups[1]
}
}
- result = append(result, item)
- return result, nil
+ refineIssueRepoCommit(item, commitRepoUrlRegexps,
issueCommit.CommitUrl)
+ return []interface{}{item}, nil
},
})
if err != nil {
@@ -105,3 +117,25 @@ 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]
+ item.CommitSha = group[3]
+ 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/plugins/jira/tasks/issue_repo_commit_convertor_test.go
new file mode 100644
index 000000000..c9310ea56
--- /dev/null
+++ b/backend/plugins/jira/tasks/issue_repo_commit_convertor_test.go
@@ -0,0 +1,131 @@
+/*
+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 (
+
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
+ "reflect"
+ "regexp"
+ "testing"
+)
+
+func Test_refineIssueRepoCommit(t *testing.T) {
+ type args struct {
+ item *crossdomain.IssueRepoCommit
+ repoPatterns []*regexp.Regexp
+ commitUrl string
+ }
+ tests := []struct {
+ name string
+ args args
+ want *crossdomain.IssueRepoCommit
+ }{
+ {
+ "bitbucket server",
+ args{
+ item:
&crossdomain.IssueRepoCommit{IssueId: "abc123", CommitSha:
"1e23e7f1a0cb539c7408c38e5a37de3bc836bc94"},
+ 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",
+ },
+ &crossdomain.IssueRepoCommit{
+ IssueId: "abc123",
+ CommitSha:
"1e23e7f1a0cb539c7408c38e5a37de3bc836bc94",
+ RepoUrl:
"https://example.com/PROJECTNAME/ui_jira.git",
+ Host: "example.com",
+ Namespace: "PROJECTNAME",
+ RepoName: "ui_jira",
+ },
+ },
+ {
+ "bitbucket cloud",
+ args{
+ item:
&crossdomain.IssueRepoCommit{IssueId: "abc123", CommitSha:
"fef8d697fbb9a2b336be6fa2e2848f585c86a622"},
+ 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",
+ },
+ &crossdomain.IssueRepoCommit{
+ IssueId: "abc123",
+ CommitSha:
"fef8d697fbb9a2b336be6fa2e2848f585c86a622",
+ RepoUrl:
"https://bitbucket.org/mynamespace/incubator-devlake.git",
+ Host: "bitbucket.org",
+ Namespace: "mynamespace",
+ RepoName: "incubator-devlake",
+ },
+ },
+ {
+ "GitHub",
+ args{
+ item:
&crossdomain.IssueRepoCommit{IssueId: "abc123", CommitSha:
"a7c6550b6a273af36e9850291a52601d3dca367c"},
+ 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",
+ },
+ &crossdomain.IssueRepoCommit{
+ IssueId: "abc123",
+ CommitSha:
"a7c6550b6a273af36e9850291a52601d3dca367c",
+ RepoUrl:
"https://github.com/apache/incubator-devlake.git",
+ Host: "github.com",
+ Namespace: "apache",
+ RepoName: "incubator-devlake",
+ },
+ },
+ {
+ "GitLab cloud",
+ args{
+ item:
&crossdomain.IssueRepoCommit{IssueId: "abc123", CommitSha:
"050baf4575caf069275f5fa14db9ad4a21a79883"},
+ 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",
+ },
+ &crossdomain.IssueRepoCommit{
+ IssueId: "abc123",
+ CommitSha:
"050baf4575caf069275f5fa14db9ad4a21a79883",
+ RepoUrl:
"https://gitlab.com/namespace1/namespace2/myrepo.git",
+ Host: "gitlab.com",
+ Namespace: "namespace1/namespace2",
+ RepoName: "myrepo",
+ },
+ },
+ {
+ "GitLab cloud",
+ args{
+ item: &crossdomain.IssueRepoCommit{IssueId:
"abc123", CommitSha: "a802d5edf833b8fa70189783ebe21174ff333c69"},
+ 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",
+ },
+ &crossdomain.IssueRepoCommit{
+ IssueId: "abc123",
+ CommitSha:
"a802d5edf833b8fa70189783ebe21174ff333c69",
+ RepoUrl:
"https://gitlab.com/meri.co/vdev.co.git",
+ Host: "gitlab.com",
+ Namespace: "meri.co",
+ RepoName: "vdev.co",
+ },
+ },
+ }
+ 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) {
+ t.Logf("%+v", got)
+ t.Errorf("refineIssueRepoCommit() = %v, want
%v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/backend/plugins/jira/tasks/task_data.go
b/backend/plugins/jira/tasks/task_data.go
index 5ac5a9d13..d58a680a8 100644
--- a/backend/plugins/jira/tasks/task_data.go
+++ b/backend/plugins/jira/tasks/task_data.go
@@ -45,34 +45,31 @@ type JiraTransformationRule struct {
EpicKeyField string `json:"epicKeyField"`
StoryPointField string `json:"storyPointField"`
RemotelinkCommitShaPattern string
`json:"remotelinkCommitShaPattern"`
+ RemotelinkRepoPattern []string `json:"remotelinkRepoPattern"`
TypeMappings TypeMappings `json:"typeMappings"`
}
-func (r *JiraTransformationRule) ToDb() (rule *models.JiraTransformationRule,
error2 errors.Error) {
+func (r *JiraTransformationRule) ToDb() (*models.JiraTransformationRule,
errors.Error) {
blob, err := json.Marshal(r.TypeMappings)
if err != nil {
return nil, errors.Default.Wrap(err, "error marshaling
TypeMappings")
}
- return &models.JiraTransformationRule{
+ remotelinkRepoPattern, err := json.Marshal(r.RemotelinkRepoPattern)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error marshaling
RemotelinkRepoPattern")
+ }
+ rule := &models.JiraTransformationRule{
Name: r.Name,
EpicKeyField: r.EpicKeyField,
StoryPointField: r.StoryPointField,
RemotelinkCommitShaPattern: r.RemotelinkCommitShaPattern,
+ RemotelinkRepoPattern: remotelinkRepoPattern,
TypeMappings: blob,
- }, nil
-}
-func (r *JiraTransformationRule) FromDb(rule *models.JiraTransformationRule)
(*JiraTransformationRule, errors.Error) {
- mappings := make(map[string]TypeMapping)
- err := json.Unmarshal(rule.TypeMappings, &mappings)
- if err != nil {
- return nil, errors.Default.Wrap(err, "error marshaling
TypeMappings")
}
- r.Name = rule.Name
- r.EpicKeyField = rule.EpicKeyField
- r.StoryPointField = rule.StoryPointField
- r.RemotelinkCommitShaPattern = rule.RemotelinkCommitShaPattern
- r.TypeMappings = mappings
- return r, nil
+ if err1 := rule.VerifyRegexp(); err1 != nil {
+ return nil, err1
+ }
+ return rule, nil
}
func MakeTransformationRules(rule models.JiraTransformationRule)
(*JiraTransformationRule, errors.Error) {
@@ -81,11 +78,17 @@ func MakeTransformationRules(rule
models.JiraTransformationRule) (*JiraTransform
if err != nil {
return nil, errors.Default.Wrap(err, "unable to unmarshal the
typeMapping")
}
+ var remotelinkRepoPattern []string
+ err = json.Unmarshal(rule.RemotelinkRepoPattern, &remotelinkRepoPattern)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error unMarshaling
RemotelinkRepoPattern")
+ }
result := &JiraTransformationRule{
Name: rule.Name,
EpicKeyField: rule.EpicKeyField,
StoryPointField: rule.StoryPointField,
RemotelinkCommitShaPattern: rule.RemotelinkCommitShaPattern,
+ RemotelinkRepoPattern: remotelinkRepoPattern,
TypeMappings: typeMapping,
}
return result, nil