You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by mi...@apache.org on 2024/09/20 04:23:10 UTC

(incubator-devlake) 33/39: fix: update bamboo/bitbuctet/jenkins trans-to-deployment scope config… (#8065)

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

mintsweet pushed a commit to branch feat-dora-config
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git

commit 82e325e41f4ff344662b9995f83435e3e753f105
Author: abeizn <zi...@merico.dev>
AuthorDate: Wed Sep 18 15:14:13 2024 +0800

    fix: update bamboo/bitbuctet/jenkins trans-to-deployment scope config… (#8065)
    
    * fix: update bamboo/bitbuctet/jenkins trans-to-deployment scope config to pointer
    
    * fix: update circleci trans-to-deployment scope config to pointer
    
    * fix: bamboo lint
---
 backend/plugins/bamboo/e2e/deploy_build_test.go    | 10 ++++---
 backend/plugins/bamboo/e2e/job_build_test.go       | 11 ++++----
 backend/plugins/bamboo/e2e/job_test.go             |  7 +++--
 .../plugins/bamboo/e2e/plan_build_commits_test.go  |  8 +++---
 backend/plugins/bamboo/e2e/plan_build_test.go      | 12 ++++----
 backend/plugins/bamboo/impl/impl.go                | 12 +++++---
 backend/plugins/bamboo/models/scope_config.go      |  4 +--
 .../plugins/bamboo/tasks/job_build_extractor.go    |  6 ++--
 .../plugins/bamboo/tasks/plan_build_extractor.go   |  7 +++--
 backend/plugins/bamboo/tasks/plan_convertor.go     |  3 +-
 backend/plugins/bitbucket/e2e/deployments_test.go  |  7 +++--
 backend/plugins/bitbucket/impl/impl.go             | 12 +++++---
 backend/plugins/bitbucket/models/scope_config.go   |  4 +--
 .../plugins/bitbucket/tasks/pipeline_extractor.go  |  6 ++--
 .../bitbucket/tasks/pipeline_steps_extractor.go    |  6 ++--
 backend/plugins/circleci/impl/impl.go              | 12 +++++---
 backend/plugins/circleci/models/scope_config.go    |  4 +--
 backend/plugins/circleci/tasks/job_converter.go    |  6 ++--
 .../plugins/circleci/tasks/workflow_converter.go   |  6 ++--
 backend/plugins/jenkins/impl/impl.go               | 33 +++++++++++++---------
 backend/plugins/jenkins/models/scope_config.go     |  4 +--
 .../plugins/jenkins/tasks/build_cicd_convertor.go  | 12 +++++---
 backend/plugins/jenkins/tasks/stage_convertor.go   |  6 ++--
 23 files changed, 119 insertions(+), 79 deletions(-)

diff --git a/backend/plugins/bamboo/e2e/deploy_build_test.go b/backend/plugins/bamboo/e2e/deploy_build_test.go
index 380d4e26e..9d2102a3a 100644
--- a/backend/plugins/bamboo/e2e/deploy_build_test.go
+++ b/backend/plugins/bamboo/e2e/deploy_build_test.go
@@ -41,20 +41,22 @@ func getFakeAPIClient() *helper.ApiAsyncClient {
 func TestBambooDeployBuildDataFlow(t *testing.T) {
 	var bamboo impl.Bamboo
 	dataflowTester := e2ehelper.NewDataFlowTester(t, "bamboo", bamboo)
+	dPattern := "(?i)release"
+	pPattern := "(?i)release"
 	taskData := &tasks.BambooOptions{
 		Options: &models.BambooOptions{
 			ConnectionId: 1,
 			PlanKey:      "TEST-PLA2",
 			BambooScopeConfig: &models.BambooScopeConfig{
-				DeploymentPattern: "(?i)release",
-				ProductionPattern: "(?i)release",
+				DeploymentPattern: &dPattern,
+				ProductionPattern: &pPattern,
 			},
 		},
 		RegexEnricher: helper.NewRegexEnricher(),
 		ApiClient:     getFakeAPIClient(),
 	}
-	taskData.RegexEnricher.TryAdd(devops.DEPLOYMENT, taskData.Options.DeploymentPattern)
-	taskData.RegexEnricher.TryAdd(devops.PRODUCTION, taskData.Options.ProductionPattern)
+	taskData.RegexEnricher.TryAdd(devops.DEPLOYMENT, *taskData.Options.DeploymentPattern)
+	taskData.RegexEnricher.TryAdd(devops.PRODUCTION, *taskData.Options.ProductionPattern)
 	// import raw data table
 	dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_bamboo_api_deploy_builds.csv", "_raw_bamboo_api_deploy_builds")
 
diff --git a/backend/plugins/bamboo/e2e/job_build_test.go b/backend/plugins/bamboo/e2e/job_build_test.go
index 7ed7709bc..4914a5bb9 100644
--- a/backend/plugins/bamboo/e2e/job_build_test.go
+++ b/backend/plugins/bamboo/e2e/job_build_test.go
@@ -30,22 +30,23 @@ import (
 )
 
 func TestBambooJobBuildDataFlow(t *testing.T) {
-
 	var bamboo impl.Bamboo
 	dataflowTester := e2ehelper.NewDataFlowTester(t, "bamboo", bamboo)
+	dPattern := "(?i)release"
+	pPattern := "(?i)release"
 	taskData := &tasks.BambooOptions{
 		Options: &models.BambooOptions{
 			ConnectionId: 1,
 			PlanKey:      "TEST-PLA3",
 			BambooScopeConfig: &models.BambooScopeConfig{
-				DeploymentPattern: "(?i)compile",
-				ProductionPattern: "(?i)compile",
+				DeploymentPattern: &dPattern,
+				ProductionPattern: &pPattern,
 			},
 		},
 		RegexEnricher: helper.NewRegexEnricher(),
 		ApiClient:     getFakeAPIClient(),
 	}
-	taskData.RegexEnricher.TryAdd(devops.DEPLOYMENT, taskData.Options.DeploymentPattern)
+	taskData.RegexEnricher.TryAdd(devops.DEPLOYMENT, *taskData.Options.DeploymentPattern)
 	// import raw data table
 	// SELECT * FROM _raw_bamboo_api_job_build INTO OUTFILE "/tmp/_raw_bamboo_api_job_builds.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
 	dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_bamboo_api_job_builds.csv", "_raw_bamboo_api_job_builds")
@@ -63,7 +64,7 @@ func TestBambooJobBuildDataFlow(t *testing.T) {
 	)
 
 	// verify extraction
-	taskData.RegexEnricher.TryAdd(devops.PRODUCTION, taskData.Options.ProductionPattern)
+	taskData.RegexEnricher.TryAdd(devops.PRODUCTION, *taskData.Options.ProductionPattern)
 	dataflowTester.FlushTabler(&models.BambooJobBuild{})
 	dataflowTester.Subtask(tasks.ExtractJobBuildMeta, taskData)
 	dataflowTester.VerifyTable(
diff --git a/backend/plugins/bamboo/e2e/job_test.go b/backend/plugins/bamboo/e2e/job_test.go
index 8d3a29b0b..c3efc372a 100644
--- a/backend/plugins/bamboo/e2e/job_test.go
+++ b/backend/plugins/bamboo/e2e/job_test.go
@@ -30,14 +30,15 @@ func TestBambooJobDataFlow(t *testing.T) {
 
 	var bamboo impl.Bamboo
 	dataflowTester := e2ehelper.NewDataFlowTester(t, "bamboo", bamboo)
-
+	dPattern := "(?i)release"
+	pPattern := "(?i)release"
 	taskData := &tasks.BambooOptions{
 		Options: &models.BambooOptions{
 			ConnectionId: 1,
 			PlanKey:      "TEST-PLA1",
 			BambooScopeConfig: &models.BambooScopeConfig{
-				DeploymentPattern: "(?i)compile",
-				ProductionPattern: "(?i)compile",
+				DeploymentPattern: &dPattern,
+				ProductionPattern: &pPattern,
 			},
 		},
 		ApiClient: getFakeAPIClient(),
diff --git a/backend/plugins/bamboo/e2e/plan_build_commits_test.go b/backend/plugins/bamboo/e2e/plan_build_commits_test.go
index 99294fd8b..2a489d1b8 100644
--- a/backend/plugins/bamboo/e2e/plan_build_commits_test.go
+++ b/backend/plugins/bamboo/e2e/plan_build_commits_test.go
@@ -29,17 +29,17 @@ import (
 )
 
 func TestBambooPlanBuildCommitsDataFlow(t *testing.T) {
-
 	var bamboo impl.Bamboo
 	dataflowTester := e2ehelper.NewDataFlowTester(t, "bamboo", bamboo)
-
+	dPattern := "(?i)release"
+	pPattern := "(?i)release"
 	taskData := &tasks.BambooOptions{
 		Options: &models.BambooOptions{
 			ConnectionId: 1,
 			PlanKey:      "TEST-PLA2",
 			BambooScopeConfig: &models.BambooScopeConfig{
-				DeploymentPattern: "(?i)compile",
-				ProductionPattern: "(?i)compile",
+				DeploymentPattern: &dPattern,
+				ProductionPattern: &pPattern,
 			},
 		},
 		ApiClient: getFakeAPIClient(),
diff --git a/backend/plugins/bamboo/e2e/plan_build_test.go b/backend/plugins/bamboo/e2e/plan_build_test.go
index 67584f8f1..9db7b9ecc 100644
--- a/backend/plugins/bamboo/e2e/plan_build_test.go
+++ b/backend/plugins/bamboo/e2e/plan_build_test.go
@@ -30,24 +30,24 @@ import (
 )
 
 func TestBambooPlanBuildDataFlow(t *testing.T) {
-
 	var bamboo impl.Bamboo
 	dataflowTester := e2ehelper.NewDataFlowTester(t, "bamboo", bamboo)
-
+	dPattern := "(?i)release"
+	pPattern := "(?i)release"
 	taskData := &tasks.BambooOptions{
 		Options: &models.BambooOptions{
 			ConnectionId: 1,
 			PlanKey:      "TEST-PLA2",
 			BambooScopeConfig: &models.BambooScopeConfig{
-				DeploymentPattern: "(?i)compile",
-				ProductionPattern: "(?i)compile",
+				DeploymentPattern: &dPattern,
+				ProductionPattern: &pPattern,
 			},
 		},
 		RegexEnricher: helper.NewRegexEnricher(),
 		ApiClient:     getFakeAPIClient(),
 	}
-	taskData.RegexEnricher.TryAdd(devops.DEPLOYMENT, taskData.Options.DeploymentPattern)
-	taskData.RegexEnricher.TryAdd(devops.PRODUCTION, taskData.Options.ProductionPattern)
+	taskData.RegexEnricher.TryAdd(devops.DEPLOYMENT, *taskData.Options.DeploymentPattern)
+	taskData.RegexEnricher.TryAdd(devops.PRODUCTION, *taskData.Options.ProductionPattern)
 	// import raw data table
 	// SELECT * FROM _raw_bamboo_api_job_build INTO OUTFILE "/tmp/_raw_bamboo_api_job_builds.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
 	dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_bamboo_api_plan_builds.csv", "_raw_bamboo_api_plan_builds")
diff --git a/backend/plugins/bamboo/impl/impl.go b/backend/plugins/bamboo/impl/impl.go
index 15a140165..0ac41bbd8 100644
--- a/backend/plugins/bamboo/impl/impl.go
+++ b/backend/plugins/bamboo/impl/impl.go
@@ -183,11 +183,15 @@ func (p Bamboo) PrepareTaskData(taskCtx plugin.TaskContext, options map[string]i
 		op.BambooScopeConfig = new(models.BambooScopeConfig)
 	}
 	regexEnricher := helper.NewRegexEnricher()
-	if err := regexEnricher.TryAdd(devops.DEPLOYMENT, op.DeploymentPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+	if op.DeploymentPattern != nil {
+		if err := regexEnricher.TryAdd(devops.DEPLOYMENT, *op.DeploymentPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+		}
 	}
-	if err := regexEnricher.TryAdd(devops.PRODUCTION, op.ProductionPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+	if op.ProductionPattern != nil {
+		if err := regexEnricher.TryAdd(devops.PRODUCTION, *op.ProductionPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+		}
 	}
 	if len(op.BambooScopeConfig.EnvNameList) > 0 || (len(op.BambooScopeConfig.EnvNameList) == 0 && op.BambooScopeConfig.EnvNamePattern == "") {
 		if err = regexEnricher.TryAddList(devops.ENV_NAME_PATTERN, op.BambooScopeConfig.EnvNameList...); err != nil {
diff --git a/backend/plugins/bamboo/models/scope_config.go b/backend/plugins/bamboo/models/scope_config.go
index 1ec217baa..46703664a 100644
--- a/backend/plugins/bamboo/models/scope_config.go
+++ b/backend/plugins/bamboo/models/scope_config.go
@@ -24,8 +24,8 @@ import (
 type BambooScopeConfig struct {
 	common.ScopeConfig `mapstructure:",squash" json:",inline" gorm:"embedded"`
 	RepoMap            map[string][]int `json:"repoMap" gorm:"type:json;serializer:json"` // should be {realRepoName: [bamboo_repoId, ...]}
-	DeploymentPattern  string           `mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern" gorm:"type:varchar(255)"`
-	ProductionPattern  string           `mapstructure:"productionPattern,omitempty" json:"productionPattern" gorm:"type:varchar(255)"`
+	DeploymentPattern  *string          `mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern" gorm:"type:varchar(255)"`
+	ProductionPattern  *string          `mapstructure:"productionPattern,omitempty" json:"productionPattern" gorm:"type:varchar(255)"`
 	EnvNamePattern     string           `mapstructure:"envNamePattern,omitempty" json:"envNamePattern" gorm:"type:varchar(255)"`
 	EnvNameList        []string         `gorm:"type:json;serializer:json" json:"envNameList" mapstructure:"envNameList"`
 }
diff --git a/backend/plugins/bamboo/tasks/job_build_extractor.go b/backend/plugins/bamboo/tasks/job_build_extractor.go
index 2077aa467..23bbb04f0 100644
--- a/backend/plugins/bamboo/tasks/job_build_extractor.go
+++ b/backend/plugins/bamboo/tasks/job_build_extractor.go
@@ -52,8 +52,10 @@ func ExtractJobBuild(taskCtx plugin.SubTaskContext) errors.Error {
 			body.PlanKey = data.Options.PlanKey
 			body.PlanName = plan.PlanName
 			body.PlanBuildKey = fmt.Sprintf("%s-%v", plan.PlanKey, body.Number)
-			body.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, body.JobName)
-			body.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, body.JobName)
+			if data.Options.DeploymentPattern != nil || data.Options.ProductionPattern != nil {
+				body.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, body.JobName)
+				body.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, body.JobName)
+			}
 			results := make([]interface{}, 0)
 			results = append(results, body)
 			return results, nil
diff --git a/backend/plugins/bamboo/tasks/plan_build_extractor.go b/backend/plugins/bamboo/tasks/plan_build_extractor.go
index 2ce1eeb86..386ec2856 100644
--- a/backend/plugins/bamboo/tasks/plan_build_extractor.go
+++ b/backend/plugins/bamboo/tasks/plan_build_extractor.go
@@ -45,9 +45,10 @@ func ExtractPlanBuild(taskCtx plugin.SubTaskContext) errors.Error {
 			body := res.Convert()
 			body.ConnectionId = data.Options.ConnectionId
 			body.PlanKey = data.Options.PlanKey
-			body.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, body.PlanName)
-			body.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, body.PlanName)
-
+			if data.Options.DeploymentPattern != nil || data.Options.ProductionPattern != nil {
+				body.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, body.PlanName)
+				body.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, body.PlanName)
+			}
 			var url string
 			homepage, errGetHomePage := GetBambooHomePage(body.LinkHref)
 			if errGetHomePage != nil {
diff --git a/backend/plugins/bamboo/tasks/plan_convertor.go b/backend/plugins/bamboo/tasks/plan_convertor.go
index 261e6dfb3..5125b6c78 100644
--- a/backend/plugins/bamboo/tasks/plan_convertor.go
+++ b/backend/plugins/bamboo/tasks/plan_convertor.go
@@ -18,6 +18,8 @@ limitations under the License.
 package tasks
 
 import (
+	"reflect"
+
 	"github.com/apache/incubator-devlake/core/dal"
 	"github.com/apache/incubator-devlake/core/errors"
 	"github.com/apache/incubator-devlake/core/models/domainlayer"
@@ -26,7 +28,6 @@ import (
 	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	bambooModels "github.com/apache/incubator-devlake/plugins/bamboo/models"
-	"reflect"
 )
 
 const RAW_PLAN_TABLE = "bamboo_plan"
diff --git a/backend/plugins/bitbucket/e2e/deployments_test.go b/backend/plugins/bitbucket/e2e/deployments_test.go
index 8d68a0dff..9e060d19c 100644
--- a/backend/plugins/bitbucket/e2e/deployments_test.go
+++ b/backend/plugins/bitbucket/e2e/deployments_test.go
@@ -31,14 +31,15 @@ import (
 func TestDeloymentsDataFlow(t *testing.T) {
 	var bitbucket impl.Bitbucket
 	dataflowTester := e2ehelper.NewDataFlowTester(t, "bitbucket", bitbucket)
-
+	dPattern := ""
+	pPattern := ""
 	taskData := &tasks.BitbucketTaskData{
 		Options: &tasks.BitbucketOptions{
 			ConnectionId: 1,
 			FullName:     "likyh/likyhphp",
 			BitbucketScopeConfig: &models.BitbucketScopeConfig{
-				DeploymentPattern: "",
-				ProductionPattern: "",
+				DeploymentPattern: &dPattern,
+				ProductionPattern: &pPattern,
 			},
 		},
 	}
diff --git a/backend/plugins/bitbucket/impl/impl.go b/backend/plugins/bitbucket/impl/impl.go
index 953819024..dd917790c 100644
--- a/backend/plugins/bitbucket/impl/impl.go
+++ b/backend/plugins/bitbucket/impl/impl.go
@@ -176,11 +176,15 @@ func (p Bitbucket) PrepareTaskData(taskCtx plugin.TaskContext, options map[strin
 	}
 
 	regexEnricher := helper.NewRegexEnricher()
-	if err := regexEnricher.TryAdd(devops.DEPLOYMENT, op.DeploymentPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+	if op.DeploymentPattern != nil {
+		if err := regexEnricher.TryAdd(devops.DEPLOYMENT, *op.DeploymentPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+		}
 	}
-	if err := regexEnricher.TryAdd(devops.PRODUCTION, op.ProductionPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+	if op.ProductionPattern != nil {
+		if err := regexEnricher.TryAdd(devops.PRODUCTION, *op.ProductionPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+		}
 	}
 	taskData := &tasks.BitbucketTaskData{
 		Options:       op,
diff --git a/backend/plugins/bitbucket/models/scope_config.go b/backend/plugins/bitbucket/models/scope_config.go
index 207485a10..ca4811f05 100644
--- a/backend/plugins/bitbucket/models/scope_config.go
+++ b/backend/plugins/bitbucket/models/scope_config.go
@@ -24,8 +24,8 @@ import (
 
 type BitbucketScopeConfig struct {
 	common.ScopeConfig `mapstructure:",squash" json:",inline" gorm:"embedded"`
-	DeploymentPattern  string            `mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern" gorm:"type:varchar(255)"`
-	ProductionPattern  string            `mapstructure:"productionPattern,omitempty" json:"productionPattern" gorm:"type:varchar(255)"`
+	DeploymentPattern  *string           `mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern" gorm:"type:varchar(255)"`
+	ProductionPattern  *string           `mapstructure:"productionPattern,omitempty" json:"productionPattern" gorm:"type:varchar(255)"`
 	Refdiff            datatypes.JSONMap `mapstructure:"refdiff,omitempty" json:"refdiff" swaggertype:"object" format:"json"`
 
 	// a string array, split by `,`.
diff --git a/backend/plugins/bitbucket/tasks/pipeline_extractor.go b/backend/plugins/bitbucket/tasks/pipeline_extractor.go
index ec924db8d..c0e23ec7e 100644
--- a/backend/plugins/bitbucket/tasks/pipeline_extractor.go
+++ b/backend/plugins/bitbucket/tasks/pipeline_extractor.go
@@ -103,8 +103,10 @@ func ExtractApiPipelines(taskCtx plugin.SubTaskContext) errors.Error {
 				DurationInSeconds:   bitbucketApiPipeline.DurationInSeconds,
 				BitbucketCreatedOn:  common.Iso8601TimeToTime(bitbucketApiPipeline.CreatedOn),
 				BitbucketCompleteOn: common.Iso8601TimeToTime(bitbucketApiPipeline.CompletedOn),
-				Type:                data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, bitbucketApiPipeline.Target.RefName),
-				Environment:         data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, bitbucketApiPipeline.Target.RefName),
+			}
+			if data.Options.DeploymentPattern != nil || data.Options.ProductionPattern != nil {
+				bitbucketPipeline.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, bitbucketApiPipeline.Target.RefName)
+				bitbucketPipeline.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, bitbucketApiPipeline.Target.RefName)
 			}
 			if bitbucketApiPipeline.State.Result != nil {
 				bitbucketPipeline.Result = bitbucketApiPipeline.State.Result.Name
diff --git a/backend/plugins/bitbucket/tasks/pipeline_steps_extractor.go b/backend/plugins/bitbucket/tasks/pipeline_steps_extractor.go
index 82bd93bd4..684ada923 100644
--- a/backend/plugins/bitbucket/tasks/pipeline_steps_extractor.go
+++ b/backend/plugins/bitbucket/tasks/pipeline_steps_extractor.go
@@ -93,8 +93,10 @@ func ExtractPipelineSteps(taskCtx plugin.SubTaskContext) errors.Error {
 				DurationInSeconds: apiPipelineStep.DurationInSeconds,
 				BuildSecondsUsed:  apiPipelineStep.BuildSecondsUsed,
 				RunNumber:         apiPipelineStep.RunNumber,
-				Type:              data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, apiPipelineStep.Name),
-				Environment:       data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, apiPipelineStep.Name),
+			}
+			if data.Options.DeploymentPattern != nil || data.Options.ProductionPattern != nil {
+				bitbucketStep.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, apiPipelineStep.Name)
+				bitbucketStep.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, apiPipelineStep.Name)
 			}
 			return []interface{}{
 				bitbucketStep,
diff --git a/backend/plugins/circleci/impl/impl.go b/backend/plugins/circleci/impl/impl.go
index c2ae4a8bf..8cca5895d 100644
--- a/backend/plugins/circleci/impl/impl.go
+++ b/backend/plugins/circleci/impl/impl.go
@@ -153,11 +153,15 @@ func (p Circleci) PrepareTaskData(taskCtx plugin.TaskContext, options map[string
 		op.ScopeConfig = new(models.CircleciScopeConfig)
 	}
 	regexEnricher := helper.NewRegexEnricher()
-	if err := regexEnricher.TryAdd(devops.DEPLOYMENT, op.ScopeConfig.DeploymentPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+	if op.ScopeConfig.DeploymentPattern != nil {
+		if err := regexEnricher.TryAdd(devops.DEPLOYMENT, *op.ScopeConfig.DeploymentPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+		}
 	}
-	if err := regexEnricher.TryAdd(devops.PRODUCTION, op.ScopeConfig.ProductionPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+	if op.ScopeConfig.ProductionPattern != nil {
+		if err := regexEnricher.TryAdd(devops.PRODUCTION, *op.ScopeConfig.ProductionPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+		}
 	}
 	taskData.RegexEnricher = regexEnricher
 	return taskData, nil
diff --git a/backend/plugins/circleci/models/scope_config.go b/backend/plugins/circleci/models/scope_config.go
index 8d6a433bd..5b7ed1b46 100644
--- a/backend/plugins/circleci/models/scope_config.go
+++ b/backend/plugins/circleci/models/scope_config.go
@@ -23,8 +23,8 @@ import (
 
 type CircleciScopeConfig struct {
 	common.ScopeConfig `mapstructure:",squash" json:",inline" gorm:"embedded"`
-	DeploymentPattern  string `gorm:"type:varchar(255)" mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern"`
-	ProductionPattern  string `gorm:"type:varchar(255)" mapstructure:"productionPattern,omitempty" json:"productionPattern"`
+	DeploymentPattern  *string `gorm:"type:varchar(255)" mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern"`
+	ProductionPattern  *string `gorm:"type:varchar(255)" mapstructure:"productionPattern,omitempty" json:"productionPattern"`
 }
 
 func (t CircleciScopeConfig) TableName() string {
diff --git a/backend/plugins/circleci/tasks/job_converter.go b/backend/plugins/circleci/tasks/job_converter.go
index 2cb8de120..accfa0ce5 100644
--- a/backend/plugins/circleci/tasks/job_converter.go
+++ b/backend/plugins/circleci/tasks/job_converter.go
@@ -86,8 +86,10 @@ func ConvertJobs(taskCtx plugin.SubTaskContext) errors.Error {
 					Failure: []string{"failed", "failing", "error"}, // not_run,canceled
 					Default: devops.RESULT_DEFAULT,
 				}, userTool.Status),
-				Type:        data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, userTool.Name),
-				Environment: data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, userTool.Name),
+			}
+			if data.Options.ScopeConfig.DeploymentPattern != nil || data.Options.ScopeConfig.ProductionPattern != nil {
+				task.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, userTool.Name)
+				task.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, userTool.Name)
 			}
 			if task.DurationSec == 0 {
 				task.DurationSec = userTool.DurationSec
diff --git a/backend/plugins/circleci/tasks/workflow_converter.go b/backend/plugins/circleci/tasks/workflow_converter.go
index 78223f5cf..7389b2271 100644
--- a/backend/plugins/circleci/tasks/workflow_converter.go
+++ b/backend/plugins/circleci/tasks/workflow_converter.go
@@ -81,10 +81,12 @@ func ConvertWorkflows(taskCtx plugin.SubTaskContext) errors.Error {
 					Failure: []string{"failed", "failing", "error"}, // not_run,canceled
 					Default: devops.RESULT_DEFAULT,
 				}, userTool.Status),
-				Type:         data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, userTool.Name),
-				Environment:  data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, userTool.Name),
 				DisplayTitle: fmt.Sprintf("%s#%d", userTool.Name, userTool.PipelineNumber),
 			}
+			if data.Options.ScopeConfig.DeploymentPattern != nil || data.Options.ScopeConfig.ProductionPattern != nil {
+				pipeline.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, userTool.Name)
+				pipeline.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, userTool.Name)
+			}
 			result := make([]interface{}, 0, 2)
 			result = append(result, pipeline)
 
diff --git a/backend/plugins/jenkins/impl/impl.go b/backend/plugins/jenkins/impl/impl.go
index 7be75a8e1..be9589152 100644
--- a/backend/plugins/jenkins/impl/impl.go
+++ b/backend/plugins/jenkins/impl/impl.go
@@ -144,11 +144,15 @@ func (p Jenkins) PrepareTaskData(taskCtx plugin.TaskContext, options map[string]
 	}
 
 	regexEnricher := helper.NewRegexEnricher()
-	if err := regexEnricher.TryAdd(devops.DEPLOYMENT, op.ScopeConfig.DeploymentPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+	if op.ScopeConfig.DeploymentPattern != nil {
+		if err := regexEnricher.TryAdd(devops.DEPLOYMENT, *op.ScopeConfig.DeploymentPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `deploymentPattern`")
+		}
 	}
-	if err := regexEnricher.TryAdd(devops.PRODUCTION, op.ScopeConfig.ProductionPattern); err != nil {
-		return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+	if op.ScopeConfig.ProductionPattern != nil {
+		if err := regexEnricher.TryAdd(devops.PRODUCTION, *op.ScopeConfig.ProductionPattern); err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `productionPattern`")
+		}
 	}
 	taskData := &tasks.JenkinsTaskData{
 		Options:       op,
@@ -291,18 +295,19 @@ func EnrichOptions(taskCtx plugin.TaskContext,
 		op.JobPath = fmt.Sprintf("%s/", op.JobPath)
 	}
 	// We only set op.JenkinsScopeConfig when it's nil and we have op.ScopeConfigId != 0
-	if op.ScopeConfig.DeploymentPattern == "" && op.ScopeConfig.ProductionPattern == "" && op.ScopeConfigId != 0 {
-		var scopeConfig models.JenkinsScopeConfig
-		err = taskCtx.GetDal().First(&scopeConfig, dal.Where("id = ?", op.ScopeConfigId))
-		if err != nil {
-			return errors.BadInput.Wrap(err, "fail to get scopeConfig")
+	if op.ScopeConfig.DeploymentPattern != nil && op.ScopeConfig.ProductionPattern != nil {
+		if *op.ScopeConfig.DeploymentPattern == "" && *op.ScopeConfig.ProductionPattern == "" && op.ScopeConfigId != 0 {
+			var scopeConfig models.JenkinsScopeConfig
+			err = taskCtx.GetDal().First(&scopeConfig, dal.Where("id = ?", op.ScopeConfigId))
+			if err != nil {
+				return errors.BadInput.Wrap(err, "fail to get scopeConfig")
+			}
+			op.ScopeConfig = &scopeConfig
 		}
-		op.ScopeConfig = &scopeConfig
-	}
 
-	if op.ScopeConfig.DeploymentPattern == "" && op.ScopeConfig.ProductionPattern == "" && op.ScopeConfigId == 0 {
-		op.ScopeConfig = new(models.JenkinsScopeConfig)
+		if *op.ScopeConfig.DeploymentPattern == "" && *op.ScopeConfig.ProductionPattern == "" && op.ScopeConfigId == 0 {
+			op.ScopeConfig = new(models.JenkinsScopeConfig)
+		}
 	}
-
 	return nil
 }
diff --git a/backend/plugins/jenkins/models/scope_config.go b/backend/plugins/jenkins/models/scope_config.go
index 1eb889ca4..7f7b90039 100644
--- a/backend/plugins/jenkins/models/scope_config.go
+++ b/backend/plugins/jenkins/models/scope_config.go
@@ -23,8 +23,8 @@ import (
 
 type JenkinsScopeConfig struct {
 	common.ScopeConfig `mapstructure:",squash" json:",inline" gorm:"embedded"`
-	DeploymentPattern  string `gorm:"type:varchar(255)" mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern"`
-	ProductionPattern  string `gorm:"type:varchar(255)" mapstructure:"productionPattern,omitempty" json:"productionPattern"`
+	DeploymentPattern  *string `gorm:"type:varchar(255)" mapstructure:"deploymentPattern,omitempty" json:"deploymentPattern"`
+	ProductionPattern  *string `gorm:"type:varchar(255)" mapstructure:"productionPattern,omitempty" json:"productionPattern"`
 }
 
 func (t JenkinsScopeConfig) TableName() string {
diff --git a/backend/plugins/jenkins/tasks/build_cicd_convertor.go b/backend/plugins/jenkins/tasks/build_cicd_convertor.go
index 34ec88d57..f09f27b75 100644
--- a/backend/plugins/jenkins/tasks/build_cicd_convertor.go
+++ b/backend/plugins/jenkins/tasks/build_cicd_convertor.go
@@ -128,8 +128,10 @@ func ConvertBuildsToCicdTasks(taskCtx plugin.SubTaskContext) (err errors.Error)
 				},
 				DurationSec: durationSec,
 				CicdScopeId: jobIdGen.Generate(jenkinsBuild.ConnectionId, data.Options.JobFullName),
-				Type:        data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, jenkinsBuild.FullName),
-				Environment: data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, jenkinsBuild.FullName),
+			}
+			if data.Options.ScopeConfig.DeploymentPattern != nil || data.Options.ScopeConfig.ProductionPattern != nil {
+				jenkinsPipeline.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, jenkinsBuild.FullName)
+				jenkinsPipeline.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, jenkinsBuild.FullName)
 			}
 			jenkinsPipeline.RawDataOrigin = jenkinsBuild.RawDataOrigin
 			results = append(results, jenkinsPipeline)
@@ -151,10 +153,12 @@ func ConvertBuildsToCicdTasks(taskCtx plugin.SubTaskContext) (err errors.Error)
 						FinishedDate: jenkinsPipelineFinishedDate,
 					},
 					CicdScopeId: jobIdGen.Generate(jenkinsBuild.ConnectionId, data.Options.JobFullName),
-					Type:        data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, jenkinsBuild.FullName),
-					Environment: data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, jenkinsBuild.FullName),
 					PipelineId:  buildIdGen.Generate(jenkinsBuild.ConnectionId, jenkinsBuild.FullName),
 				}
+				if data.Options.ScopeConfig.DeploymentPattern != nil || data.Options.ScopeConfig.ProductionPattern != nil {
+					jenkinsTask.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, jenkinsBuild.FullName)
+					jenkinsTask.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, jenkinsBuild.FullName)
+				}
 				// if the task is not executed, set the result to default, so that it will not be calculated in the dora
 				if jenkinsTask.OriginalStatus == "NOT_EXECUTED" {
 					jenkinsTask.Result = devops.RESULT_DEFAULT
diff --git a/backend/plugins/jenkins/tasks/stage_convertor.go b/backend/plugins/jenkins/tasks/stage_convertor.go
index 35c31fade..83a053ecf 100644
--- a/backend/plugins/jenkins/tasks/stage_convertor.go
+++ b/backend/plugins/jenkins/tasks/stage_convertor.go
@@ -152,8 +152,10 @@ func ConvertStages(taskCtx plugin.SubTaskContext) (err errors.Error) {
 				OriginalResult: body.Result,
 				OriginalStatus: body.Status,
 				CicdScopeId:    jobIdGen.Generate(body.ConnectionId, data.Options.JobFullName),
-				Type:           data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, body.Name),
-				Environment:    data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, body.Name),
+			}
+			if data.Options.ScopeConfig.DeploymentPattern != nil || data.Options.ScopeConfig.ProductionPattern != nil {
+				jenkinsTask.Type = data.RegexEnricher.ReturnNameIfMatched(devops.DEPLOYMENT, body.Name)
+				jenkinsTask.Environment = data.RegexEnricher.ReturnNameIfOmittedOrMatched(devops.PRODUCTION, body.Name)
 			}
 			// if the task is not executed, set the result to default, so that it will not be calculated in the dora
 			if jenkinsTask.OriginalStatus == "NOT_EXECUTED" {