From 839e530f4103da4bbdaa5aabeaedb858e8917aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=C3=A1n=20Dunne?= Date: Thu, 16 Jan 2025 14:32:35 +0000 Subject: [PATCH] feat: [CI-15791]: add tags to pipeline based on tools used --- convert/harness/downgrader/downgrade.go | 6 +++++ convert/harness/yaml/pipeline.go | 19 ++++++++------- convert/jenkinsjson/convert.go | 32 ++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/convert/harness/downgrader/downgrade.go b/convert/harness/downgrader/downgrade.go index 82db6aa6..0bc3c994 100644 --- a/convert/harness/downgrader/downgrade.go +++ b/convert/harness/downgrader/downgrade.go @@ -167,6 +167,12 @@ func (d *Downgrader) downgrade(src []*v1.Config) ([]byte, error) { config.Pipeline.Org = d.pipelineOrg config.Pipeline.Project = d.pipelineProj + config.Pipeline.Tags = make(map[string]string) + for _, tag := range strings.Split(p.Type, ",") { + if tag != "" { + config.Pipeline.Tags[tag] = "" + } + } config.Pipeline.Props.CI.Codebase = v0.Codebase{ Name: d.codebaseName, Conn: d.codebaseConn, diff --git a/convert/harness/yaml/pipeline.go b/convert/harness/yaml/pipeline.go index 88463e84..5aaa0f83 100644 --- a/convert/harness/yaml/pipeline.go +++ b/convert/harness/yaml/pipeline.go @@ -22,15 +22,16 @@ type ( // Pipeline defines a pipeline. Pipeline struct { - ID string `json:"identifier,omitempty" yaml:"identifier,omitempty"` - Name string `json:"name,omitempty" yaml:"name,omitempty"` - Desc string `json:"description,omitempty" yaml:"description,omitempty"` - Account string `json:"accountIdentifier,omitempty" yaml:"accountIdentifier,omitempty"` - Project string `json:"projectIdentifier,omitempty" yaml:"projectIdentifier,omitempty"` - Org string `json:"orgIdentifier,omitempty" yaml:"orgIdentifier,omitempty"` - Props Properties `json:"properties,omitempty" yaml:"properties,omitempty"` - Stages []*Stages `json:"stages,omitempty" yaml:"stages"` - Variables []*Variable `json:"variables,omitempty" yaml:"variables,omitempty"` + ID string `json:"identifier,omitempty" yaml:"identifier,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Desc string `json:"description,omitempty" yaml:"description,omitempty"` + Account string `json:"accountIdentifier,omitempty" yaml:"accountIdentifier,omitempty"` + Project string `json:"projectIdentifier,omitempty" yaml:"projectIdentifier,omitempty"` + Org string `json:"orgIdentifier,omitempty" yaml:"orgIdentifier,omitempty"` + Props Properties `json:"properties,omitempty" yaml:"properties,omitempty"` + Stages []*Stages `json:"stages,omitempty" yaml:"stages"` + Variables []*Variable `json:"variables,omitempty" yaml:"variables,omitempty"` + Tags map[string]string `json:"tags,omitempty" yaml:"tags,omitempty"` } // Properties defines pipeline properties. diff --git a/convert/jenkinsjson/convert.go b/convert/jenkinsjson/convert.go index 340de124..75416697 100644 --- a/convert/jenkinsjson/convert.go +++ b/convert/jenkinsjson/convert.go @@ -57,12 +57,24 @@ type ProcessedTools struct { AntProcessed bool SonarCubeProcessed bool SonarCubePresent bool + Tags []string } // In a unified pipeline trace, 'sh' types identified as branched/conditional will be pre-fixed with '_unifiedTraceBranch' // This is done because we don't want these steps to be merged, so that pipeline analysis is easier. const unifiedBranchedShStep = "sh_unifiedTraceBranch" +var tags = []string{ + "eks", "ec2", + "gke", "gcp", "gcloud", + "azure", + "artifactory", "jfrog", "gcr", "gar", + "java", "python", "go ", "ruby", "nodejs", "javascript", "typescript", "scala", "kotlin", "groovy", "csharp", "php", "perl", "bash", "powershell", + "docker ", "git ", "npm ", "yarn ", "node ", "maven", "mvn ", "gradle", "sbt ", "bazel", "pip ", "dotnet ", "msbuild", + "sfdx ", + "hadoop", "mariadb", "mysql", "psql", "mongo", "redis", "jdbc", +} + var mavenGoals string var gradleGoals string @@ -117,7 +129,7 @@ func (d *Converter) Convert(r io.Reader) ([]byte, error) { // create the harness pipeline spec dst := &harness.Pipeline{} - processedTools := &ProcessedTools{false, false, false, false, false, false, false, false, false} + processedTools := &ProcessedTools{false, false, false, false, false, false, false, false, false, []string{}} var variable map[string]string recursiveParseJsonToStages(&pipelineJson, dst, processedTools, variable) // create the harness pipeline resource @@ -125,6 +137,7 @@ func (d *Converter) Convert(r io.Reader) ([]byte, error) { Version: 1, Name: jenkinsjson.SanitizeForName(pipelineJson.Name), Kind: "pipeline", + Type: strings.Join(processedTools.Tags, ","), Spec: dst, } @@ -204,6 +217,20 @@ func collectStagesWithID(jsonNode *jenkinsjson.Node, processedTools *ProcessedTo }, } + // identify technology tags + for _, step := range stepsInStage { + switch step.Spec.(type) { + case *harness.StepExec: + exec := step.Spec.(*harness.StepExec) + for _, tag := range tags { + tagNoSpace := strings.TrimSpace(tag) + if strings.Contains(strings.ToLower(exec.Run), tag) || strings.Contains(strings.ToLower(exec.Image), tagNoSpace) { + processedTools.Tags = append(processedTools.Tags, tagNoSpace) + } + } + } + } + // Convert stageID to integer and store it with the stage id, err := strconv.Atoi(stageID) if err != nil { @@ -480,8 +507,10 @@ func collectStepsWithID(currentNode jenkinsjson.Node, stepGroupWithId *[]StepGro } case "emailext": *stepWithIDList = append(*stepWithIDList, StepWithID{Step: jenkinsjson.ConvertEmailext(currentNode, variables, timeout), ID: id}) + processedTools.Tags = append(processedTools.Tags, "email") case "junit": *stepWithIDList = append(*stepWithIDList, StepWithID{Step: jenkinsjson.ConvertJunit(currentNode, variables), ID: id}) + processedTools.Tags = append(processedTools.Tags, "junit") case "sleep": *stepWithIDList = append(*stepWithIDList, StepWithID{Step: jenkinsjson.ConvertSleep(currentNode, variables), ID: id}) case "dir": @@ -750,6 +779,7 @@ func collectStepsWithID(currentNode jenkinsjson.Node, stepGroupWithId *[]StepGro *stepWithIDList = append(*stepWithIDList, StepWithID{Step: jenkinsjson.ConvertKubeCtl(currentNode, currentNode.ParameterMap), ID: id}) case "mail": *stepWithIDList = append(*stepWithIDList, StepWithID{Step: jenkinsjson.ConvertMailer(currentNode, currentNode.ParameterMap), ID: id}) + processedTools.Tags = append(processedTools.Tags, "email") case "pagerdutyChangeEvent": *stepWithIDList = append(*stepWithIDList, StepWithID{Step: jenkinsjson.ConvertPagerDutyChangeEvent(currentNode, currentNode.ParameterMap), ID: id})