cherry-pic fix(zentao): update zentao plugin, do lots of fixes (#5963)
* fix(zentao): fix zentao's bug collector, add project and execution's bugs, remove product's bugs
* fix(zentao): fix ci error
* fix(zentao): add story_point when issue's type story
* fix(zentao): update project's url
* fix(zentao): fix project's url
* fix(zentao): fix e2e test
* fix(zentao): extract all task/bug/story ids from log comment
diff --git a/backend/plugins/zentao/e2e/snapshot_tables/issues_story.csv b/backend/plugins/zentao/e2e/snapshot_tables/issues_story.csv
index e3c1099..564f63f 100644
--- a/backend/plugins/zentao/e2e/snapshot_tables/issues_story.csv
+++ b/backend/plugins/zentao/e2e/snapshot_tables/issues_story.csv
@@ -1,10 +1,10 @@
id,url,icon_url,issue_key,title,description,epic_key,type,original_type,status,original_status,story_point,resolution_date,created_date,updated_date,lead_time_minutes,parent_issue_id,priority,original_estimate_minutes,time_spent_minutes,time_remaining_minutes,creator_id,creator_name,assignee_id,assignee_name,severity,component
-zentao:ZentaoStory:1:1,http://iwater.red:8000/story-view-1.html,,1,首页设计和开发,,,REQUIREMENT,story,DONE,active,0,,2012-06-05T02:09:49.000+00:00,2012-06-05T02:25:19.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:2,http://iwater.red:8000/story-view-2.html,,2,新闻中心的设计和开发。,,,REQUIREMENT,story,DONE,active,0,,2012-06-05T02:16:37.000+00:00,2012-06-05T02:25:33.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:1,http://iwater.red:8000/story-view-1.html,,1,首页设计和开发,,,REQUIREMENT,story,DONE,active,1,,2012-06-05T02:09:49.000+00:00,2012-06-05T02:25:19.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:2,http://iwater.red:8000/story-view-2.html,,2,新闻中心的设计和开发。,,,REQUIREMENT,story,DONE,active,1,,2012-06-05T02:16:37.000+00:00,2012-06-05T02:25:33.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
zentao:ZentaoStory:1:3,http://iwater.red:8000/story-view-3.html,,3,成果展示的设计和开发,,,REQUIREMENT,story,DONE,active,0,,2012-06-05T02:18:10.000+00:00,2012-06-05T02:25:38.000+00:00,0,,1,0,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:4,http://iwater.red:8000/story-view-4.html,,4,售后服务的设计和开发,,,REQUIREMENT,story,DONE,active,0,,2012-06-05T02:20:16.000+00:00,2012-06-05T02:25:42.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:5,http://iwater.red:8000/story-view-5.html,,5,诚聘英才的设计和开发,,,REQUIREMENT,story,reviewing,reviewing,0,,2012-06-05T02:21:39.000+00:00,,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:6,http://iwater.red:8000/story-view-6.html,,6,合作洽谈的设计和开发,,,REQUIREMENT,story,reviewing,reviewing,0,,2012-06-05T02:23:11.000+00:00,,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:7,http://iwater.red:8000/story-view-7.html,,7,关于我们的设计和开发,,,REQUIREMENT,story,reviewing,reviewing,0,,2012-06-05T02:24:19.000+00:00,,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:8,http://iwater.red:8000/story-view-8.html,,8,新闻中心的设计和开发。,,,REQUIREMENT,story,DONE,active,0,,2012-06-05T02:16:37.000+00:00,2012-06-05T02:25:33.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
-zentao:ZentaoStory:1:9,http://iwater.red:8000/story-view-9.html,,9,首页设计和开发,,,REQUIREMENT,story,DONE,active,0,,2012-06-05T02:09:49.000+00:00,2012-06-05T02:25:19.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:4,http://iwater.red:8000/story-view-4.html,,4,售后服务的设计和开发,,,REQUIREMENT,story,DONE,active,1,,2012-06-05T02:20:16.000+00:00,2012-06-05T02:25:42.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:5,http://iwater.red:8000/story-view-5.html,,5,诚聘英才的设计和开发,,,REQUIREMENT,story,reviewing,reviewing,1,,2012-06-05T02:21:39.000+00:00,,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:6,http://iwater.red:8000/story-view-6.html,,6,合作洽谈的设计和开发,,,REQUIREMENT,story,reviewing,reviewing,1,,2012-06-05T02:23:11.000+00:00,,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:7,http://iwater.red:8000/story-view-7.html,,7,关于我们的设计和开发,,,REQUIREMENT,story,reviewing,reviewing,1,,2012-06-05T02:24:19.000+00:00,,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:8,http://iwater.red:8000/story-view-8.html,,8,新闻中心的设计和开发。,,,REQUIREMENT,story,DONE,active,1,,2012-06-05T02:16:37.000+00:00,2012-06-05T02:25:33.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
+zentao:ZentaoStory:1:9,http://iwater.red:8000/story-view-9.html,,9,首页设计和开发,,,REQUIREMENT,story,DONE,active,1,,2012-06-05T02:09:49.000+00:00,2012-06-05T02:25:19.000+00:00,0,,1,60,0,0,zentao:ZentaoAccount:1:2,产品经理,zentao:ZentaoAccount:1:2,产品经理,,
diff --git a/backend/plugins/zentao/tasks/bug_collector.go b/backend/plugins/zentao/tasks/bug_collector.go
index 6ecd44b..17b5675 100644
--- a/backend/plugins/zentao/tasks/bug_collector.go
+++ b/backend/plugins/zentao/tasks/bug_collector.go
@@ -32,23 +32,53 @@
var _ plugin.SubTaskEntryPoint = CollectBug
+var CollectBugMeta = plugin.SubTaskMeta{
+ Name: "collectBug",
+ EntryPoint: CollectBug,
+ EnabledByDefault: true,
+ Description: "Collect Bug data from Zentao api",
+ DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
+}
+
+type collectBugInput struct {
+ Path string
+ ProjectId int64
+ ProductId int64
+ ExecutionId int64
+}
+
func CollectBug(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- cursor, iterator, err := getProductIterator(taskCtx)
+ // project bug iterator
+ projectBugsIter := newIteratorFromSlice([]interface{}{
+ collectBugInput{
+ ProjectId: data.Options.ProjectId,
+ Path: fmt.Sprintf("/projects/%d", data.Options.ProjectId),
+ },
+ })
+ // execution bug iterator
+ executionCursor, executionIterator, err := getExecutionIterator(taskCtx)
if err != nil {
return err
}
- defer cursor.Close()
+ defer executionCursor.Close()
+ executionBugIter := newIteratorWrapper(executionIterator, func(arg interface{}) interface{} {
+ return &collectBugInput{
+ ExecutionId: arg.(*input).Id,
+ Path: fmt.Sprintf("/executions/%d", arg.(*input).Id),
+ }
+ })
+
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
Ctx: taskCtx,
Options: data.Options,
Table: RAW_BUG_TABLE,
},
- Input: iterator,
+ Input: newIteratorConcator(projectBugsIter, executionBugIter),
ApiClient: data.ApiClient,
PageSize: 100,
- UrlTemplate: "/products/{{ .Input.Id }}/bugs",
+ UrlTemplate: "{{ .Input.Path }}/bugs",
Query: func(reqData *api.RequestData) (url.Values, errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
@@ -77,11 +107,3 @@
return collector.Execute()
}
-
-var CollectBugMeta = plugin.SubTaskMeta{
- Name: "collectBug",
- EntryPoint: CollectBug,
- EnabledByDefault: true,
- Description: "Collect Bug data from Zentao api",
- DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
-}
diff --git a/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go b/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
index 53b9215..7afbb4d 100644
--- a/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
@@ -19,8 +19,6 @@
import (
"encoding/json"
- "regexp"
-
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
@@ -39,9 +37,6 @@
func ExtractBugRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
-
- re := regexp.MustCompile(`(\d+)(?:,\s*(\d+))*`)
-
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
Ctx: taskCtx,
@@ -60,19 +55,20 @@
return nil, errors.Default.WrapRaw(err)
}
results := make([]interface{}, 0)
- match := re.FindStringSubmatch(res.Log.Comment)
- for i := 1; i < len(match); i++ {
- if match[i] != "" {
- bugRepoCommits := &models.ZentaoBugRepoCommit{
- ConnectionId: data.Options.ConnectionId,
- Product: input.Product,
- Project: data.Options.ProjectId,
- RepoUrl: res.Repo.CodePath,
- CommitSha: res.Revision,
- IssueId: match[i], // bug id
- }
- results = append(results, bugRepoCommits)
+ issueIds, err := extractIdFromLogComment("bug", res.Log.Comment)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "extractIdFromLogComment")
+ }
+ for _, issueId := range issueIds {
+ bugRepoCommits := &models.ZentaoBugRepoCommit{
+ ConnectionId: data.Options.ConnectionId,
+ Product: input.Product,
+ Project: data.Options.ProjectId,
+ RepoUrl: res.Repo.CodePath,
+ CommitSha: res.Revision,
+ IssueId: issueId,
}
+ results = append(results, bugRepoCommits)
}
return results, nil
diff --git a/backend/plugins/zentao/tasks/project_convertor.go b/backend/plugins/zentao/tasks/project_convertor.go
index 3f217a9..2c39285 100644
--- a/backend/plugins/zentao/tasks/project_convertor.go
+++ b/backend/plugins/zentao/tasks/project_convertor.go
@@ -19,6 +19,7 @@
import (
"fmt"
+ "net/url"
"reflect"
"github.com/apache/incubator-devlake/core/dal"
@@ -46,6 +47,7 @@
func ConvertProjects(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
+ logger := taskCtx.GetLogger()
boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProject{})
cursor, err := db.Cursor(
dal.From(&models.ZentaoProject{}),
@@ -55,6 +57,17 @@
return err
}
defer cursor.Close()
+ var protocol, host string
+ endpoint := data.ApiClient.ApiClient.GetEndpoint()
+ if endpoint != "" {
+ endpointURL, err := url.Parse(endpoint)
+ if err != nil {
+ logger.Error(err, "parse: %s", endpoint)
+ } else {
+ protocol = endpointURL.Scheme
+ host = endpointURL.Host
+ }
+ }
convertor, err := api.NewDataConverter(api.DataConverterArgs{
InputRowType: reflect.TypeOf(models.ZentaoProject{}),
Input: cursor,
@@ -74,7 +87,7 @@
Description: toolProject.Description,
CreatedDate: toolProject.OpenedDate.ToNullableTime(),
Type: "scrum",
- Url: fmt.Sprintf("/project-index-%d.html", data.Options.ProjectId),
+ Url: fmt.Sprintf("%s://%s/project-index-%d.html", protocol, host, data.Options.ProjectId),
}
results := make([]interface{}, 0)
results = append(results, domainBoard)
diff --git a/backend/plugins/zentao/tasks/shared.go b/backend/plugins/zentao/tasks/shared.go
index c4fd10d..f02c7f8 100644
--- a/backend/plugins/zentao/tasks/shared.go
+++ b/backend/plugins/zentao/tasks/shared.go
@@ -23,6 +23,7 @@
"net/url"
"path"
"reflect"
+ "regexp"
"strings"
"github.com/apache/incubator-devlake/core/dal"
@@ -179,29 +180,29 @@
return nil
}
-func getProductIterator(taskCtx plugin.SubTaskContext) (dal.Rows, *api.DalCursorIterator, errors.Error) {
- data := taskCtx.GetData().(*ZentaoTaskData)
- db := taskCtx.GetDal()
- clauses := []dal.Clause{
- dal.Select("id"),
- dal.From(&models.ZentaoProductSummary{}),
- dal.Where(
- "project_id = ? AND connection_id = ?",
- data.Options.ProjectId, data.Options.ConnectionId,
- ),
- }
-
- cursor, err := db.Cursor(clauses...)
- if err != nil {
- return nil, nil, err
- }
- iterator, err := api.NewDalCursorIterator(db, cursor, reflect.TypeOf(input{}))
- if err != nil {
- cursor.Close()
- return nil, nil, err
- }
- return cursor, iterator, nil
-}
+//func getProductIterator(taskCtx plugin.SubTaskContext) (dal.Rows, *api.DalCursorIterator, errors.Error) {
+// data := taskCtx.GetData().(*ZentaoTaskData)
+// db := taskCtx.GetDal()
+// clauses := []dal.Clause{
+// dal.Select("id"),
+// dal.From(&models.ZentaoProductSummary{}),
+// dal.Where(
+// "project_id = ? AND connection_id = ?",
+// data.Options.ProjectId, data.Options.ConnectionId,
+// ),
+// }
+//
+// cursor, err := db.Cursor(clauses...)
+// if err != nil {
+// return nil, nil, err
+// }
+// iterator, err := api.NewDalCursorIterator(db, cursor, reflect.TypeOf(input{}))
+// if err != nil {
+// cursor.Close()
+// return nil, nil, err
+// }
+// return cursor, iterator, nil
+//}
func getExecutionIterator(taskCtx plugin.SubTaskContext) (dal.Rows, *api.DalCursorIterator, errors.Error) {
data := taskCtx.GetData().(*ZentaoTaskData)
@@ -305,3 +306,36 @@
u.Path = path.Join(before, fmt.Sprintf("/%s-view-%d.html", issueType, id))
return u.String()
}
+
+func extractIdFromLogComment(logCommentType string, comment string) ([]string, error) {
+ if logCommentType != "task" && logCommentType != "bug" && logCommentType != "story" {
+ return nil, errors.Default.New(fmt.Sprintf("unsupportted log comment type: %s", logCommentType))
+ }
+ regexpStr := fmt.Sprintf("(%s-view-\\d+\\.json)+", logCommentType)
+ re := regexp.MustCompile(regexpStr)
+ results := re.FindAllString(comment, -1)
+ var ret []string
+
+ convertMatchedString := func(s string) string {
+ if s == "" {
+ return s
+ }
+ s = strings.Replace(s, "-", " ", -1)
+ s = strings.Replace(s, ".", " ", -1)
+ return s
+ }
+
+ for _, matched := range results {
+ var id string
+ format := fmt.Sprintf("%s view %%s json", logCommentType)
+ n, err := fmt.Sscanf(convertMatchedString(matched), format, &id)
+ if err != nil {
+ return nil, err
+ }
+ if n < 1 {
+ return nil, errors.Default.New("unexpected comment")
+ }
+ ret = append(ret, id)
+ }
+ return ret, nil
+}
diff --git a/backend/plugins/zentao/tasks/shared_test.go b/backend/plugins/zentao/tasks/shared_test.go
index bd9aacc..3dfc5d8 100644
--- a/backend/plugins/zentao/tasks/shared_test.go
+++ b/backend/plugins/zentao/tasks/shared_test.go
@@ -17,7 +17,10 @@
package tasks
-import "testing"
+import (
+ "reflect"
+ "testing"
+)
func Test_convertIssueURL(t *testing.T) {
type args struct {
@@ -69,3 +72,83 @@
})
}
}
+
+func Test_extractIdFromLogComment(t *testing.T) {
+ type args struct {
+ logCommentType string
+ comment string
+ }
+ tests := []struct {
+ name string
+ args args
+ want []string
+ wantErr bool
+ }{
+ {
+ name: "common-1",
+ args: args{
+ logCommentType: "something-wrong",
+ comment: "random strings",
+ },
+ want: nil,
+ wantErr: true,
+ },
+ {
+ name: "story-1",
+ args: args{
+ logCommentType: "story",
+ comment: "story #<a href='\\/story-view-4590.json' >4590<\\/a>\\n,<a href='\\/story-view-4572.json' >4572<\\/a>\\n",
+ },
+ want: []string{"4590", "4572"},
+ wantErr: false,
+ },
+ {
+ name: "story-2",
+ args: args{
+ logCommentType: "story",
+ comment: "story #<a href='\\/story-view-4572.json' >4572<\\/a>\\n,<a href='\\/story-view-4591.json' >4591<\\/a>\\n \\u6d4b\\u8bd5\\u4e24\\u4e2a\\u5173\\u8054\\u5173\\u7cfb\\u662f\\u5426\\u90fd\\u5199\\u8fdbissuerepocommit\\u8868",
+ },
+ want: []string{"4572", "4591"},
+ wantErr: false,
+ },
+ {
+ name: "story-3",
+ args: args{
+ logCommentType: "story",
+ comment: "story #<a href='\\/story-view-4590.json' >4590<\\/a>",
+ },
+ want: []string{"4590"},
+ wantErr: false,
+ },
+ {
+ name: "bug-1",
+ args: args{
+ logCommentType: "bug",
+ comment: "\"bug #<a href='\\/bug-view-6119.json' >6119<\\/a>\\n,<a href='\\/bug-view-6118.json' >6118<\\/a>\\n,<a href='\\/bug-view-6117.json' >6117<\\/a>\\n,<a href='\\/bug-view-6121.json' >6121<\\/a>\\n",
+ },
+ want: []string{"6119", "6118", "6117", "6121"},
+ wantErr: false,
+ },
+ {
+ name: "task-1",
+ args: args{
+ logCommentType: "task",
+ comment: "task #<a href='\\/task-view-004.json' >004<\\/a>\\n\\uff0c\\u7985\\u9053\\u4efb\\u52a1\\u6d4b\\u8bd5",
+ },
+ want: []string{"004"},
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := extractIdFromLogComment(tt.args.logCommentType, tt.args.comment)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("extractIdFromLogComment() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("extractIdFromLogComment() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/backend/plugins/zentao/tasks/story_convertor.go b/backend/plugins/zentao/tasks/story_convertor.go
index 3d32d91..d0d67e6 100644
--- a/backend/plugins/zentao/tasks/story_convertor.go
+++ b/backend/plugins/zentao/tasks/story_convertor.go
@@ -90,6 +90,7 @@
OriginalProject: getOriginalProject(data),
Status: toolEntity.StdStatus,
OriginalEstimateMinutes: int64(toolEntity.Estimate) * 60,
+ StoryPoint: toolEntity.Estimate,
}
if mappingType, ok := stdTypeMappings[domainEntity.OriginalType]; ok && mappingType != "" {
domainEntity.Type = mappingType
diff --git a/backend/plugins/zentao/tasks/story_repo_commits_extractor.go b/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
index 3176d8e..7e1b69d 100644
--- a/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
@@ -19,8 +19,6 @@
import (
"encoding/json"
- "regexp"
-
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
@@ -39,8 +37,6 @@
func ExtractStoryRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
-
- re := regexp.MustCompile(`(\d+)(?:,\s*(\d+))*`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
Ctx: taskCtx,
@@ -55,18 +51,19 @@
}
results := make([]interface{}, 0)
- match := re.FindStringSubmatch(res.Log.Comment)
- for i := 1; i < len(match); i++ {
- if match[i] != "" {
- storyRepoCommits := &models.ZentaoStoryRepoCommit{
- ConnectionId: data.Options.ConnectionId,
- Project: data.Options.ProjectId,
- RepoUrl: res.Repo.CodePath,
- CommitSha: res.Revision,
- IssueId: match[i], // story id
- }
- results = append(results, storyRepoCommits)
+ issueIds, err := extractIdFromLogComment("story", res.Log.Comment)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "extractIdFromLogComment")
+ }
+ for _, issueId := range issueIds {
+ storyRepoCommits := &models.ZentaoStoryRepoCommit{
+ ConnectionId: data.Options.ConnectionId,
+ Project: data.Options.ProjectId,
+ RepoUrl: res.Repo.CodePath,
+ CommitSha: res.Revision,
+ IssueId: issueId,
}
+ results = append(results, storyRepoCommits)
}
return results, nil
diff --git a/backend/plugins/zentao/tasks/task_repo_commits_extractor.go b/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
index e601abe..9174239 100644
--- a/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
@@ -19,8 +19,6 @@
import (
"encoding/json"
- "regexp"
-
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
@@ -39,8 +37,6 @@
func ExtractTaskRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
-
- re := regexp.MustCompile(`(\d+)(?:,\s*(\d+))*`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
Ctx: taskCtx,
@@ -55,18 +51,19 @@
}
results := make([]interface{}, 0)
- match := re.FindStringSubmatch(res.Log.Comment)
- for i := 1; i < len(match); i++ {
- if match[i] != "" {
- taskRepoCommits := &models.ZentaoTaskRepoCommit{
- ConnectionId: data.Options.ConnectionId,
- Project: data.Options.ProjectId,
- RepoUrl: res.Repo.CodePath,
- CommitSha: res.Revision,
- IssueId: match[i], // task id
- }
- results = append(results, taskRepoCommits)
+ issueIds, err := extractIdFromLogComment("task", res.Log.Comment)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "extractIdFromLogComment")
+ }
+ for _, issueId := range issueIds {
+ taskRepoCommits := &models.ZentaoTaskRepoCommit{
+ ConnectionId: data.Options.ConnectionId,
+ Project: data.Options.ProjectId,
+ RepoUrl: res.Repo.CodePath,
+ CommitSha: res.Revision,
+ IssueId: issueId,
}
+ results = append(results, taskRepoCommits)
}
return results, nil