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 11b6b5581 fix(github): modify bp v200 (#3892)
11b6b5581 is described below

commit 11b6b5581ba55ad4c6e81a763a998acb786e6fb9
Author: Warren Chen <[email protected]>
AuthorDate: Fri Dec 9 16:25:40 2022 +0800

    fix(github): modify bp v200 (#3892)
---
 models/domainlayer/code/repo.go           |  2 +-
 plugins/bitbucket/tasks/repo_convertor.go |  2 +-
 plugins/gitee/tasks/repo_convertor.go     |  2 +-
 plugins/github/api/blueprint.go           |  6 ++--
 plugins/github/api/blueprint_V200_test.go | 13 ++-----
 plugins/github/api/blueprint_test.go      | 47 ++++++++++++++++---------
 plugins/github/api/blueprint_v200.go      | 37 ++++++++++----------
 plugins/github/impl/impl.go               | 23 ++++---------
 plugins/github/tasks/repo_convertor.go    |  2 +-
 plugins/github/tasks/task_data.go         | 23 ++++++++-----
 plugins/github_graphql/impl/impl.go       | 57 +++++++++++++++++++++++++++----
 plugins/gitlab/tasks/project_convertor.go |  2 +-
 plugins/jenkins/api/blueprint_v200.go     |  5 ++-
 plugins/jira/api/blueprint_v200.go        |  5 ++-
 services/blueprint_makeplan_v200.go       |  8 +++--
 services/pipeline_helper.go               |  2 ++
 16 files changed, 146 insertions(+), 90 deletions(-)

diff --git a/models/domainlayer/code/repo.go b/models/domainlayer/code/repo.go
index afa8be3c7..ffc1038a1 100644
--- a/models/domainlayer/code/repo.go
+++ b/models/domainlayer/code/repo.go
@@ -34,7 +34,7 @@ type Repo struct {
        OwnerId     string     `json:"ownerId" gorm:"type:varchar(255)"`
        Language    string     `json:"language" gorm:"type:varchar(255)"`
        ForkedFrom  string     `json:"forkedFrom"`
-       CreatedDate time.Time  `json:"createdDate"`
+       CreatedDate *time.Time `json:"createdDate"`
        UpdatedDate *time.Time `json:"updatedDate"`
        Deleted     bool       `json:"deleted"`
 }
diff --git a/plugins/bitbucket/tasks/repo_convertor.go 
b/plugins/bitbucket/tasks/repo_convertor.go
index 5285154cf..237d59d9a 100644
--- a/plugins/bitbucket/tasks/repo_convertor.go
+++ b/plugins/bitbucket/tasks/repo_convertor.go
@@ -79,7 +79,7 @@ func ConvertRepo(taskCtx core.SubTaskContext) errors.Error {
                                Url:         repository.HTMLUrl,
                                Description: repository.Description,
                                Language:    repository.Language,
-                               CreatedDate: repository.CreatedDate,
+                               CreatedDate: &repository.CreatedDate,
                                UpdatedDate: repository.UpdatedDate,
                        }
 
diff --git a/plugins/gitee/tasks/repo_convertor.go 
b/plugins/gitee/tasks/repo_convertor.go
index b3abca0f0..27670daa1 100644
--- a/plugins/gitee/tasks/repo_convertor.go
+++ b/plugins/gitee/tasks/repo_convertor.go
@@ -73,7 +73,7 @@ func ConvertRepo(taskCtx core.SubTaskContext) errors.Error {
                                Description: repository.Description,
                                ForkedFrom:  repository.ParentHTMLUrl,
                                Language:    repository.Language,
-                               CreatedDate: repository.CreatedDate,
+                               CreatedDate: &repository.CreatedDate,
                                UpdatedDate: repository.UpdatedDate,
                        }
 
diff --git a/plugins/github/api/blueprint.go b/plugins/github/api/blueprint.go
index 4dc771712..55622d218 100644
--- a/plugins/github/api/blueprint.go
+++ b/plugins/github/api/blueprint.go
@@ -226,7 +226,7 @@ func addGithub(subtaskMetas []core.SubTaskMeta, connection 
*models.GithubConnect
 }
 
 func getApiRepo(op *tasks.GithubOptions, apiClient helper.ApiClientGetter) 
(*tasks.GithubApiRepo, errors.Error) {
-       apiRepo := &tasks.GithubApiRepo{}
+       repoRes := &tasks.GithubApiRepo{}
        res, err := apiClient.Get(fmt.Sprintf("repos/%s/%s", op.Owner, 
op.Repo), nil, nil)
        if err != nil {
                return nil, err
@@ -239,11 +239,11 @@ func getApiRepo(op *tasks.GithubOptions, apiClient 
helper.ApiClientGetter) (*tas
        if err != nil {
                return nil, err
        }
-       err = errors.Convert(json.Unmarshal(body, apiRepo))
+       err = errors.Convert(json.Unmarshal(body, repoRes))
        if err != nil {
                return nil, err
        }
-       return apiRepo, nil
+       return repoRes, nil
 }
 
 func memorizedGetApiRepo(repo *tasks.GithubApiRepo, op *tasks.GithubOptions, 
apiClient helper.ApiClientGetter) (*tasks.GithubApiRepo, errors.Error) {
diff --git a/plugins/github/api/blueprint_V200_test.go 
b/plugins/github/api/blueprint_V200_test.go
index c0472fed9..19db95b22 100644
--- a/plugins/github/api/blueprint_V200_test.go
+++ b/plugins/github/api/blueprint_V200_test.go
@@ -93,14 +93,8 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
                                Subtasks:   []string{},
                                SkipOnFail: false,
                                Options: map[string]interface{}{
-                                       "connectionId":         uint64(1),
-                                       "transformationRuleId": uint64(1),
-                                       "owner":                "test",
-                                       "repo":                 "testRepo",
-                                       "transformationRules": 
map[string]interface{}{
-                                               "name":   "github 
transformation rule",
-                                               "prType": "hey,man,wasup",
-                                       },
+                                       "connectionId": uint64(1),
+                                       "scopeId":      "1",
                                },
                        },
                        {
@@ -154,8 +148,7 @@ func NewMockBasicRes() *mocks.BasicRes {
        testGithubRepo := &models.GithubRepo{
                ConnectionId:         1,
                GithubId:             12345,
-               Name:                 "testRepo",
-               OwnerLogin:           "test",
+               Name:                 "test/testRepo",
                TransformationRuleId: 1,
                CreatedDate:          time.Time{},
        }
diff --git a/plugins/github/api/blueprint_test.go 
b/plugins/github/api/blueprint_test.go
index 8bb4f3df3..54ae4cbd2 100644
--- a/plugins/github/api/blueprint_test.go
+++ b/plugins/github/api/blueprint_test.go
@@ -34,13 +34,20 @@ import (
        "testing"
 )
 
-var bs = &core.BlueprintScopeV100{
-       Entities: []string{"CODE"},
-       Options: json.RawMessage(`{
+var repo = &tasks.GithubApiRepo{
+       GithubId:  12345,
+       CloneUrl:  "https://this_is_cloneUrl";,
+       CreatedAt: helper.Iso8601Time{},
+}
+
+func TestMakePipelinePlan(t *testing.T) {
+       var bs = &core.BlueprintScopeV100{
+               Entities: []string{"CODE"},
+               Options: json.RawMessage(`{
               "owner": "test",
               "repo": "testRepo"
             }`),
-       Transformation: json.RawMessage(`{
+               Transformation: json.RawMessage(`{
               "prType": "hey,man,wasup",
               "refdiff": {
                 "tagsPattern": "pattern",
@@ -49,15 +56,7 @@ var bs = &core.BlueprintScopeV100{
               },
               "productionPattern": "xxxx"
             }`),
-}
-
-var repo = &tasks.GithubApiRepo{
-       GithubId:  12345,
-       CloneUrl:  "https://this_is_cloneUrl";,
-       CreatedAt: helper.Iso8601Time{},
-}
-
-func TestMakePipelinePlan(t *testing.T) {
+       }
        prepareMockMeta(t)
        mockApiClient := prepareMockClient(t, repo)
        connection := &models.GithubConnection{
@@ -131,7 +130,7 @@ func TestMakePipelinePlan(t *testing.T) {
 }
 
 func TestMemorizedGetApiRepo(t *testing.T) {
-       op := prepareOptions(t, bs)
+       op := prepareOptions(t)
        expect := repo
        repo1, err := memorizedGetApiRepo(repo, op, nil)
        assert.Nil(t, err)
@@ -143,7 +142,7 @@ func TestMemorizedGetApiRepo(t *testing.T) {
 }
 
 func TestGetApiRepo(t *testing.T) {
-       op := prepareOptions(t, bs)
+       op := prepareOptions(t)
        mockClient := prepareMockClient(t, repo)
        repo1, err := getApiRepo(op, mockClient)
        assert.Nil(t, err)
@@ -168,7 +167,23 @@ func prepareMockClient(t *testing.T, repo 
*tasks.GithubApiRepo) *mocks.ApiClient
        return mockApiCLient
 }
 
-func prepareOptions(t *testing.T, bs *core.BlueprintScopeV100) 
*tasks.GithubOptions {
+func prepareOptions(t *testing.T) *tasks.GithubOptions {
+       var bs = &core.BlueprintScopeV100{
+               Entities: []string{"CODE"},
+               Options: json.RawMessage(`{
+              "owner": "test",
+              "repo": "testRepo"
+            }`),
+               Transformation: json.RawMessage(`{
+              "prType": "hey,man,wasup",
+              "refdiff": {
+                "tagsPattern": "pattern",
+                "tagsLimit": 10,
+                "tagsOrder": "reverse semver"
+              },
+              "productionPattern": "xxxx"
+            }`),
+       }
        options := make(map[string]interface{})
        err := errors.Convert(json.Unmarshal(bs.Options, &options))
        assert.Nil(t, err)
diff --git a/plugins/github/api/blueprint_v200.go 
b/plugins/github/api/blueprint_v200.go
index cf277fd9e..14e47369a 100644
--- a/plugins/github/api/blueprint_v200.go
+++ b/plugins/github/api/blueprint_v200.go
@@ -31,7 +31,6 @@ import (
        "github.com/apache/incubator-devlake/plugins/github/tasks"
        "github.com/apache/incubator-devlake/utils"
        "github.com/go-playground/validator/v10"
-       "github.com/mitchellh/mapstructure"
        "gorm.io/gorm"
        "strings"
        "time"
@@ -86,9 +85,12 @@ func makeDataSourcePipelinePlanV200(
        apiClient helper.ApiClientGetter,
 ) (core.PipelinePlan, errors.Error) {
        var err errors.Error
-       var stage core.PipelineStage
-       var repo *tasks.GithubApiRepo
+       var repoRes *tasks.GithubApiRepo
        for i, bpScope := range bpScopes {
+               stage := plan[i]
+               if stage == nil {
+                       stage = core.PipelineStage{}
+               }
                githubRepo := &models.GithubRepo{}
                // get repo from db
                err = basicRes.GetDal().First(githubRepo, 
dal.Where(`connection_id = ? AND github_id = ?`, connection.ID, bpScope.Id))
@@ -123,33 +125,30 @@ func makeDataSourcePipelinePlanV200(
 
                // construct task options for github
                op := &tasks.GithubOptions{
-                       ConnectionId:         githubRepo.ConnectionId,
-                       TransformationRuleId: githubRepo.TransformationRuleId,
-                       Owner:                githubRepo.OwnerLogin,
-                       Repo:                 githubRepo.Name,
-               }
-               options, err := tasks.ValidateAndEncodeTaskOptions(op)
-               if err != nil {
-                       return nil, err
+                       ConnectionId: githubRepo.ConnectionId,
+                       ScopeId:      bpScope.Id,
                }
-
-               var transformationRuleMap map[string]interface{}
-               err = errors.Convert(mapstructure.Decode(transformationRule, 
&transformationRuleMap))
+               options, err := tasks.EncodeTaskOptions(op)
                if err != nil {
                        return nil, err
                }
-               options["transformationRules"] = transformationRuleMap
                stage, err = addGithub(subtaskMetas, connection, 
bpScope.Entities, stage, options)
                if err != nil {
                        return nil, err
                }
+               ownerRepo := strings.Split(githubRepo.Name, "/")
+               if len(ownerRepo) != 2 {
+                       return nil, errors.Default.New("Fail to parse 
githubRepo.Name")
+               }
+               op.Owner = ownerRepo[0]
+               op.Repo = ownerRepo[1]
                // add gitex stage and add repo to scopes
                if utils.StringsContains(bpScope.Entities, 
core.DOMAIN_TYPE_CODE) {
-                       repo, err = memorizedGetApiRepo(repo, op, apiClient)
+                       repoRes, err = memorizedGetApiRepo(repoRes, op, 
apiClient)
                        if err != nil {
                                return nil, err
                        }
-                       stage, err = addGitex(bpScope.Entities, connection, 
repo, stage)
+                       stage, err = addGitex(bpScope.Entities, connection, 
repoRes, stage)
                        if err != nil {
                                return nil, err
                        }
@@ -182,7 +181,7 @@ func makeScopesV200(bpScopes []*core.BlueprintScopeV200, 
connection *models.Gith
                                DomainEntity: domainlayer.DomainEntity{
                                        Id: 
didgen.NewDomainIdGenerator(&models.GithubRepo{}).Generate(connection.ID, 
githubRepo.GithubId),
                                },
-                               Name: fmt.Sprintf("%s/%s", 
githubRepo.OwnerLogin, githubRepo.Name),
+                               Name: githubRepo.Name,
                        }
                        if githubRepo.ParentHTMLUrl != "" {
                                scopeRepo.ForkedFrom = githubRepo.ParentHTMLUrl
@@ -205,7 +204,7 @@ func makeScopesV200(bpScopes []*core.BlueprintScopeV200, 
connection *models.Gith
                                DomainEntity: domainlayer.DomainEntity{
                                        Id: 
didgen.NewDomainIdGenerator(&models.GithubRepo{}).Generate(connection.ID, 
githubRepo.GithubId),
                                },
-                               Name: fmt.Sprintf("%s/%s", 
githubRepo.OwnerLogin, githubRepo.Name),
+                               Name: githubRepo.Name,
                        }
                        scopes = append(scopes, scopeTicket)
                }
diff --git a/plugins/github/impl/impl.go b/plugins/github/impl/impl.go
index 931204dba..231daccc1 100644
--- a/plugins/github/impl/impl.go
+++ b/plugins/github/impl/impl.go
@@ -19,11 +19,11 @@ package impl
 
 import (
        "fmt"
+       "github.com/apache/incubator-devlake/plugins/github_graphql/impl"
        "time"
 
        "github.com/apache/incubator-devlake/errors"
        "github.com/apache/incubator-devlake/plugins/core"
-       "github.com/apache/incubator-devlake/plugins/core/dal"
        "github.com/apache/incubator-devlake/plugins/github/api"
        "github.com/apache/incubator-devlake/plugins/github/models"
        
"github.com/apache/incubator-devlake/plugins/github/models/migrationscripts"
@@ -146,7 +146,7 @@ func (plugin Github) SubTaskMetas() []core.SubTaskMeta {
 func (plugin Github) PrepareTaskData(taskCtx core.TaskContext, options 
map[string]interface{}) (interface{}, errors.Error) {
        logger := taskCtx.GetLogger()
        logger.Debug("%v", options)
-       op, err := tasks.DecodeAndValidateTaskOptions(options)
+       op, err := tasks.DecodeTaskOptions(options)
        if err != nil {
                return nil, err
        }
@@ -159,6 +159,10 @@ func (plugin Github) PrepareTaskData(taskCtx 
core.TaskContext, options map[strin
        if err != nil {
                return nil, errors.Default.Wrap(err, "unable to get github 
connection by the given connection ID")
        }
+       githubRepo, err := impl.EnrichOptions(taskCtx, op, connection)
+       if err != nil {
+               return nil, err
+       }
 
        var since time.Time
        if op.Since != "" {
@@ -167,19 +171,6 @@ func (plugin Github) PrepareTaskData(taskCtx 
core.TaskContext, options map[strin
                        return nil, errors.BadInput.Wrap(err, "invalid value 
for `since`")
                }
        }
-       if op.GithubTransformationRule == nil && op.TransformationRuleId != 0 {
-               var transformationRule models.GithubTransformationRule
-               err = taskCtx.GetDal().First(&transformationRule, dal.Where("id 
= ?", op.TransformationRuleId))
-               if err != nil {
-                       return nil, errors.BadInput.Wrap(err, "fail to get 
transformationRule")
-               }
-               op.GithubTransformationRule = &transformationRule
-       }
-       var repo models.GithubRepo
-       err = taskCtx.GetDal().First(&repo, dal.Where("name = ? AND owner_login 
= ", op.Repo, op.Owner))
-       if err != nil {
-               return nil, errors.BadInput.Wrap(err, "fail to get repo")
-       }
        apiClient, err := tasks.CreateApiClient(taskCtx, connection)
        if err != nil {
                return nil, errors.Default.Wrap(err, "unable to get github API 
client instance")
@@ -187,7 +178,7 @@ func (plugin Github) PrepareTaskData(taskCtx 
core.TaskContext, options map[strin
        taskData := &tasks.GithubTaskData{
                Options:   op,
                ApiClient: apiClient,
-               Repo:      &repo,
+               Repo:      githubRepo,
        }
 
        if !since.IsZero() {
diff --git a/plugins/github/tasks/repo_convertor.go 
b/plugins/github/tasks/repo_convertor.go
index fc7278914..f2bd4500e 100644
--- a/plugins/github/tasks/repo_convertor.go
+++ b/plugins/github/tasks/repo_convertor.go
@@ -82,7 +82,7 @@ func ConvertRepo(taskCtx core.SubTaskContext) errors.Error {
                                Description: repository.Description,
                                ForkedFrom:  repository.ParentHTMLUrl,
                                Language:    repository.Language,
-                               CreatedDate: repository.CreatedDate,
+                               CreatedDate: &repository.CreatedDate,
                                UpdatedDate: repository.UpdatedDate,
                        }
 
diff --git a/plugins/github/tasks/task_data.go 
b/plugins/github/tasks/task_data.go
index 074f2ae16..79ae78890 100644
--- a/plugins/github/tasks/task_data.go
+++ b/plugins/github/tasks/task_data.go
@@ -29,10 +29,11 @@ import (
 type GithubOptions struct {
        ConnectionId                     uint64   `json:"connectionId" 
mapstructure:"connectionId,omitempty"`
        TransformationRuleId             uint64   `json:"transformationRuleId" 
mapstructure:"transformationRuleId,omitempty"`
+       ScopeId                          string   `json:"scopeId" 
mapstructure:"scopeId,omitempty"`
        Tasks                            []string `json:"tasks,omitempty" 
mapstructure:",omitempty"`
        Since                            string   `json:"since" 
mapstructure:"since,omitempty"`
-       Owner                            string   `json:"owner" 
mapstructure:"owner"`
-       Repo                             string   `json:"repo"  
mapstructure:"repo"`
+       Owner                            string   `json:"owner" 
mapstructure:"owner,omitempty"`
+       Repo                             string   `json:"repo"  
mapstructure:"repo,omitempty"`
        *models.GithubTransformationRule 
`mapstructure:"transformationRules,omitempty" json:"transformationRules"`
 }
 
@@ -45,25 +46,29 @@ type GithubTaskData struct {
 }
 
 func DecodeAndValidateTaskOptions(options map[string]interface{}) 
(*GithubOptions, errors.Error) {
-       var op GithubOptions
-       err := helper.Decode(options, &op, nil)
+       op, err := DecodeTaskOptions(options)
        if err != nil {
                return nil, err
        }
-       err = ValidateTaskOptions(&op)
+       err = ValidateTaskOptions(op)
        if err != nil {
                return nil, err
        }
-       return &op, nil
+       return op, nil
 }
 
-func ValidateAndEncodeTaskOptions(op *GithubOptions) (map[string]interface{}, 
errors.Error) {
-       err := ValidateTaskOptions(op)
+func DecodeTaskOptions(options map[string]interface{}) (*GithubOptions, 
errors.Error) {
+       var op GithubOptions
+       err := helper.Decode(options, &op, nil)
        if err != nil {
                return nil, err
        }
+       return &op, nil
+}
+
+func EncodeTaskOptions(op *GithubOptions) (map[string]interface{}, 
errors.Error) {
        var result map[string]interface{}
-       err = helper.Decode(op, &result, nil)
+       err := helper.Decode(op, &result, nil)
        if err != nil {
                return nil, err
        }
diff --git a/plugins/github_graphql/impl/impl.go 
b/plugins/github_graphql/impl/impl.go
index 48435bd1d..f98a25a94 100644
--- a/plugins/github_graphql/impl/impl.go
+++ b/plugins/github_graphql/impl/impl.go
@@ -19,7 +19,9 @@ package impl
 
 import (
        "context"
+       goerror "errors"
        "fmt"
+       "github.com/apache/incubator-devlake/plugins/core/dal"
        "reflect"
        "strings"
        "time"
@@ -120,13 +122,6 @@ func (plugin GithubGraphql) PrepareTaskData(taskCtx 
core.TaskContext, options ma
        if err != nil {
                return nil, err
        }
-       if op.Owner == "" {
-               return nil, errors.Default.New("owner is required for GitHub 
execution")
-       }
-       if op.Repo == "" {
-               return nil, errors.Default.New("repo is required for GitHub 
execution")
-       }
-
        connectionHelper := helper.NewConnectionHelper(
                taskCtx,
                nil,
@@ -137,6 +132,11 @@ func (plugin GithubGraphql) PrepareTaskData(taskCtx 
core.TaskContext, options ma
                return nil, errors.Default.Wrap(err, "unable to get github 
connection by the given connection ID: %v")
        }
 
+       _, err = EnrichOptions(taskCtx, &op, connection)
+       if err != nil {
+               return nil, err
+       }
+
        tokens := strings.Split(connection.Token, ",")
        src := oauth2.StaticTokenSource(
                &oauth2.Token{AccessToken: tokens[0]},
@@ -178,6 +178,49 @@ func (plugin GithubGraphql) PrepareTaskData(taskCtx 
core.TaskContext, options ma
        }, nil
 }
 
+func EnrichOptions(taskCtx core.TaskContext,
+       op *githubTasks.GithubOptions,
+       connection *models.GithubConnection) (*models.GithubRepo, errors.Error) 
{
+       var githubRepo models.GithubRepo
+       var err errors.Error
+       log := taskCtx.GetLogger()
+       // for advanced mode or others which we already set value to onwer/repo
+       if op.Owner != "" && op.Repo != "" {
+               err := taskCtx.GetDal().First(&githubRepo, dal.Where(
+                       "connection_id = ? AND name = ? AND owner_login = ?",
+                       op.ConnectionId, op.Repo, op.Owner))
+               if err != nil {
+                       return nil, errors.Default.Wrap(err, fmt.Sprintf("fail 
to find repo %s/%s", op.Owner, op.Repo))
+               }
+               op.TransformationRuleId = githubRepo.TransformationRuleId
+       }
+       // for bp v200 which we only set ScopeId for options
+       if githubRepo.GithubId == 0 && op.ScopeId != "" {
+               log.Debug(fmt.Sprintf("Getting githubRepo by op.ScopeId: %s", 
op.ScopeId))
+               err = taskCtx.GetDal().First(&githubRepo, 
dal.Where(`connection_id = ? AND github_id = ?`, connection.ID, op.ScopeId))
+               if err != nil {
+                       return nil, errors.Default.Wrap(err, fmt.Sprintf("fail 
to find repo %s", op.ScopeId))
+               }
+               ownerName := strings.Split(githubRepo.Name, "/")
+               if len(ownerName) != 2 {
+                       return nil, errors.Default.New("Fail to set owner/repo 
for github options.")
+               }
+               op.Owner = ownerName[0]
+               op.Repo = ownerName[1]
+               op.TransformationRuleId = githubRepo.TransformationRuleId
+       }
+       // Set GithubTransformationRule if it's nil, this has lower priority
+       if op.GithubTransformationRule == nil && op.TransformationRuleId != 0 {
+               var transformationRule models.GithubTransformationRule
+               err = taskCtx.GetDal().First(&transformationRule, dal.Where("id 
= ?", githubRepo.TransformationRuleId))
+               if err != nil && !goerror.Is(err, gorm.ErrRecordNotFound) {
+                       return nil, errors.BadInput.Wrap(err, "fail to get 
transformationRule")
+               }
+               op.GithubTransformationRule = &transformationRule
+       }
+       return &githubRepo, nil
+}
+
 // PkgPath information lost when compiled as plugin(.so)
 func (plugin GithubGraphql) RootPkgPath() string {
        return "github.com/apache/incubator-devlake/plugins/githubGraphql"
diff --git a/plugins/gitlab/tasks/project_convertor.go 
b/plugins/gitlab/tasks/project_convertor.go
index 85bdc018d..1aff3d75d 100644
--- a/plugins/gitlab/tasks/project_convertor.go
+++ b/plugins/gitlab/tasks/project_convertor.go
@@ -91,7 +91,7 @@ func convertToRepositoryModel(project *models.GitlabProject) 
*code.Repo {
                Url:         project.WebUrl,
                Description: project.Description,
                ForkedFrom:  project.ForkedFromProjectWebUrl,
-               CreatedDate: project.CreatedDate,
+               CreatedDate: &project.CreatedDate,
                UpdatedDate: project.UpdatedDate,
        }
        return domainRepository
diff --git a/plugins/jenkins/api/blueprint_v200.go 
b/plugins/jenkins/api/blueprint_v200.go
index b6a362002..b9f2b8894 100644
--- a/plugins/jenkins/api/blueprint_v200.go
+++ b/plugins/jenkins/api/blueprint_v200.go
@@ -64,8 +64,11 @@ func makeDataSourcePipelinePlanV200(
        connection *models.JenkinsConnection,
 ) (core.PipelinePlan, errors.Error) {
        var err errors.Error
-       var stage core.PipelineStage
        for i, bpScope := range bpScopes {
+               stage := plan[i]
+               if stage == nil {
+                       stage = core.PipelineStage{}
+               }
                jenkinsJob := &models.JenkinsJob{}
                // get repo from db
                err = basicRes.GetDal().First(jenkinsJob,
diff --git a/plugins/jira/api/blueprint_v200.go 
b/plugins/jira/api/blueprint_v200.go
index d0bf7abac..5bad7d93c 100644
--- a/plugins/jira/api/blueprint_v200.go
+++ b/plugins/jira/api/blueprint_v200.go
@@ -64,8 +64,11 @@ func makeDataSourcePipelinePlanV200(
 ) (core.PipelinePlan, errors.Error) {
        db := basicRes.GetDal()
        var err errors.Error
-       var stage core.PipelineStage
        for i, bpScope := range bpScopes {
+               stage := plan[i]
+               if stage == nil {
+                       stage = core.PipelineStage{}
+               }
                jiraBoard := &models.JiraBoard{}
                // get repo from db
                err = db.First(jiraBoard, dal.Where(`connection_id = ? and 
board_id = ?`, connection.ID, bpScope.Id))
diff --git a/services/blueprint_makeplan_v200.go 
b/services/blueprint_makeplan_v200.go
index c48355793..448d42530 100644
--- a/services/blueprint_makeplan_v200.go
+++ b/services/blueprint_makeplan_v200.go
@@ -44,9 +44,11 @@ func GeneratePlanJsonV200(
                if e != nil {
                        return nil, errors.Convert(err)
                }
-               e = db.Create(scopes).Error
-               if e != nil {
-                       return nil, errors.Convert(err)
+               for _, scope := range scopes {
+                       e = basicRes.GetDal().CreateOrUpdate(scope)
+                       if e != nil {
+                               return nil, errors.Convert(err)
+                       }
                }
        }
        return plan, err
diff --git a/services/pipeline_helper.go b/services/pipeline_helper.go
index d4a017718..b0706ce1b 100644
--- a/services/pipeline_helper.go
+++ b/services/pipeline_helper.go
@@ -20,6 +20,7 @@ package services
 import (
        "encoding/json"
        goerror "errors"
+       "fmt"
 
        "github.com/apache/incubator-devlake/config"
        "github.com/apache/incubator-devlake/errors"
@@ -89,6 +90,7 @@ func CreateDbPipeline(newPipeline *models.NewPipeline) 
(*models.DbPipeline, erro
        // create tasks accordingly
        for i := range newPipeline.Plan {
                for j := range newPipeline.Plan[i] {
+                       log.Debug(fmt.Sprintf("plan[%d][%d] is %+v\n", i, j, 
newPipeline.Plan[i][j]))
                        pipelineTask := newPipeline.Plan[i][j]
                        newTask := &models.NewTask{
                                PipelineTask: pipelineTask,

Reply via email to