From 065fedbef4d2b83196143a17526c83de1a2a7901 Mon Sep 17 00:00:00 2001
From: Vyacheslav Starostin <32613074+vstarostin@users.noreply.github.com>
Date: Thu, 16 May 2024 16:03:14 +0500
Subject: [PATCH 01/16] sonarExecuteScan: update documentation (#4930)
* sonarExecuteScan: update documentation
* Jenkins only
* Jenkins only
---
cmd/sonarExecuteScan_generated.go | 2 +-
resources/metadata/sonarExecuteScan.yaml | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/cmd/sonarExecuteScan_generated.go b/cmd/sonarExecuteScan_generated.go
index 9f2350c4f4..c818d61499 100644
--- a/cmd/sonarExecuteScan_generated.go
+++ b/cmd/sonarExecuteScan_generated.go
@@ -246,7 +246,7 @@ func SonarExecuteScanCommand() *cobra.Command {
func addSonarExecuteScanFlags(cmd *cobra.Command, stepConfig *sonarExecuteScanOptions) {
cmd.Flags().StringVar(&stepConfig.Instance, "instance", os.Getenv("PIPER_instance"), "Jenkins only: The name of the SonarQube instance defined in the Jenkins settings. DEPRECATED: use serverUrl parameter instead")
cmd.Flags().StringVar(&stepConfig.Proxy, "proxy", os.Getenv("PIPER_proxy"), "Proxy URL to be used for communication with the SonarQube instance.")
- cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "The URL to the Sonar backend.")
+ cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "The URL to the Sonar backend. Jenkins only: The serverUrl parameter requires the [`instance`](#instance) parameter to be explicitly set to an empty string, as it will have no effect otherwise.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "Token used to authenticate with the Sonar Server.")
cmd.Flags().StringVar(&stepConfig.Organization, "organization", os.Getenv("PIPER_organization"), "SonarCloud.io only: Organization that the project will be assigned to in SonarCloud.io.")
cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List of download links to custom TLS certificates. This is required to ensure trusted connections to instances with custom certificates.")
diff --git a/resources/metadata/sonarExecuteScan.yaml b/resources/metadata/sonarExecuteScan.yaml
index 3c67f5525a..e3230f13de 100644
--- a/resources/metadata/sonarExecuteScan.yaml
+++ b/resources/metadata/sonarExecuteScan.yaml
@@ -35,7 +35,8 @@ spec:
- name: host
- name: sonarServerUrl
type: string
- description: "The URL to the Sonar backend."
+ description: "The URL to the Sonar backend.
+ Jenkins only: The serverUrl parameter requires the [`instance`](#instance) parameter to be explicitly set to an empty string, as it will have no effect otherwise."
scope:
- PARAMETERS
- STAGES
From 7de5fdfa8af905f5ed66dcba9592121ddf702abc Mon Sep 17 00:00:00 2001
From: Jordi van Liempt <35920075+jliempt@users.noreply.github.com>
Date: Fri, 17 May 2024 10:24:31 +0200
Subject: [PATCH 02/16] feat(gcpPublishEvent): Add additionalEventData param
(#4928)
* add additionalEventData param
* fix double JSON marshalling
* go generate
* add logging of events and config
* change logging to debug
* add event log
* fix CloudEvent JSON type
* apply review feedback
* fix log
* add missing error handling
---------
Co-authored-by: jliempt <>
---
cmd/gcpPublishEvent.go | 23 +++++++++++++--
cmd/gcpPublishEvent_generated.go | 11 +++++++
pkg/events/events.go | 39 +++++++++++++++++++++++--
pkg/events/events_test.go | 22 ++++++++++++++
pkg/gcp/pubsub.go | 2 ++
resources/metadata/gcpPublishEvent.yaml | 5 ++++
6 files changed, 97 insertions(+), 5 deletions(-)
diff --git a/cmd/gcpPublishEvent.go b/cmd/gcpPublishEvent.go
index 3ae5eb5b39..46600112af 100644
--- a/cmd/gcpPublishEvent.go
+++ b/cmd/gcpPublishEvent.go
@@ -81,7 +81,7 @@ func runGcpPublishEvent(utils gcpPublishEventUtils) error {
log.Entry().WithError(err).Warning("Cannot infer config from CI environment")
}
- data, err = events.NewEvent(config.EventType, config.EventSource).CreateWithJSONData(config.EventData).ToBytes()
+ data, err = createNewEvent(config)
if err != nil {
return errors.Wrap(err, "failed to create event data")
}
@@ -101,7 +101,26 @@ func runGcpPublishEvent(utils gcpPublishEventUtils) error {
return errors.Wrap(err, "failed to publish event")
}
- log.Entry().Info("event published successfully!")
+ log.Entry().Infof("Event published successfully! With topic: %s", config.Topic)
return nil
}
+
+func createNewEvent(config *gcpPublishEventOptions) ([]byte, error) {
+ event, err := events.NewEvent(config.EventType, config.EventSource).CreateWithJSONData(config.EventData)
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "failed to create new event")
+ }
+
+ err = event.AddToCloudEventData(config.AdditionalEventData)
+ if err != nil {
+ log.Entry().Debugf("couldn't add additionalData to cloud event data: %s", err)
+ }
+
+ eventBytes, err := event.ToBytes()
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "casting event to bytes failed")
+ }
+ log.Entry().Debugf("CloudEvent created: %s", string(eventBytes))
+ return eventBytes, nil
+}
diff --git a/cmd/gcpPublishEvent_generated.go b/cmd/gcpPublishEvent_generated.go
index 47fcea9b21..d7f8eb7210 100644
--- a/cmd/gcpPublishEvent_generated.go
+++ b/cmd/gcpPublishEvent_generated.go
@@ -26,6 +26,7 @@ type gcpPublishEventOptions struct {
EventSource string `json:"eventSource,omitempty"`
EventType string `json:"eventType,omitempty"`
EventData string `json:"eventData,omitempty"`
+ AdditionalEventData string `json:"additionalEventData,omitempty"`
}
// GcpPublishEventCommand Publishes an event to GCP using OIDC authentication (beta)
@@ -138,6 +139,7 @@ func addGcpPublishEventFlags(cmd *cobra.Command, stepConfig *gcpPublishEventOpti
cmd.Flags().StringVar(&stepConfig.EventSource, "eventSource", os.Getenv("PIPER_eventSource"), "The events source as defined by CDEvents.")
cmd.Flags().StringVar(&stepConfig.EventType, "eventType", os.Getenv("PIPER_eventType"), "")
cmd.Flags().StringVar(&stepConfig.EventData, "eventData", os.Getenv("PIPER_eventData"), "Data to be merged with the generated data for the cloud event data field (JSON)")
+ cmd.Flags().StringVar(&stepConfig.AdditionalEventData, "additionalEventData", os.Getenv("PIPER_additionalEventData"), "Data (formatted as JSON string) to add to eventData. This can be used to enrich eventData that comes from the pipeline environment.")
}
@@ -247,6 +249,15 @@ func gcpPublishEventMetadata() config.StepData {
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_eventData"),
},
+ {
+ Name: "additionalEventData",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"PARAMETERS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: os.Getenv("PIPER_additionalEventData"),
+ },
},
},
},
diff --git a/pkg/events/events.go b/pkg/events/events.go
index cd8d78e03b..700337e9f4 100644
--- a/pkg/events/events.go
+++ b/pkg/events/events.go
@@ -30,8 +30,17 @@ func NewEvent(eventType, eventSource string) Event {
}
}
-func (e Event) CreateWithJSONData(data string, opts ...Option) Event {
- return e.Create(data, opts...)
+func (e Event) CreateWithJSONData(data string, opts ...Option) (Event, error) {
+ // passing a string to e.cloudEvent.SetData will result in the string being marshalled, ending up with double escape characters
+ // therefore pass a map instead
+ var dataMap map[string]interface{}
+ if data != "" {
+ err := json.Unmarshal([]byte(data), &dataMap)
+ if err != nil {
+ return e, errors.Wrap(err, "eventData is an invalid JSON")
+ }
+ }
+ return e.Create(dataMap, opts...), nil
}
func (e Event) Create(data any, opts ...Option) Event {
@@ -46,7 +55,6 @@ func (e Event) Create(data any, opts ...Option) Event {
for _, applyOpt := range opts {
applyOpt(e.cloudEvent.Context.AsV1())
}
-
return e
}
@@ -57,3 +65,28 @@ func (e Event) ToBytes() ([]byte, error) {
}
return data, nil
}
+
+func (e *Event) AddToCloudEventData(additionalDataString string) error {
+ if additionalDataString == "" {
+ return nil
+ }
+
+ var additionalData map[string]interface{}
+ err := json.Unmarshal([]byte(additionalDataString), &additionalData)
+ if err != nil {
+ errors.Wrap(err, "couldn't add additional data to cloud event")
+ }
+
+ var newEventData map[string]interface{}
+ err = json.Unmarshal(e.cloudEvent.DataEncoded, &newEventData)
+ if err != nil {
+ errors.Wrap(err, "couldn't add additional data to cloud event")
+ }
+
+ for k, v := range additionalData {
+ newEventData[k] = v
+ }
+
+ e.cloudEvent.SetData("application/json", newEventData)
+ return nil
+}
diff --git a/pkg/events/events_test.go b/pkg/events/events_test.go
index 2ef1a0a00f..87e4742ef8 100644
--- a/pkg/events/events_test.go
+++ b/pkg/events/events_test.go
@@ -16,4 +16,26 @@ func TestEventCreation(t *testing.T) {
assert.Equal(t, mock.Anything, event.cloudEvent.Type())
assert.Equal(t, mock.Anything, event.cloudEvent.Source())
})
+
+ t.Run("CreateWithJSONData - no additional data", func(t *testing.T) {
+ // init
+ testData := `{"testKey":"testValue"}`
+ // test
+ event, err := NewEvent(mock.Anything, mock.Anything).CreateWithJSONData(testData)
+ // asserts
+ assert.NoError(t, err)
+ assert.Equal(t, string(event.cloudEvent.Data()), testData)
+ })
+
+ t.Run("CreateWithJSONData + AddToCloudEventData", func(t *testing.T) {
+ // init
+ testData := `{"testKey": "testValue"}`
+ additionalData := `{"additionalKey": "additionalValue"}`
+ // test
+ event, err := NewEvent(mock.Anything, mock.Anything).CreateWithJSONData(testData)
+ event.AddToCloudEventData(additionalData)
+ // asserts
+ assert.NoError(t, err)
+ assert.Equal(t, string(event.cloudEvent.Data()), `{"additionalKey":"additionalValue","testKey":"testValue"}`)
+ })
}
diff --git a/pkg/gcp/pubsub.go b/pkg/gcp/pubsub.go
index 3dd604ade3..1e52bbb23a 100644
--- a/pkg/gcp/pubsub.go
+++ b/pkg/gcp/pubsub.go
@@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
+ "github.com/SAP/jenkins-library/pkg/log"
"github.com/pkg/errors"
)
@@ -38,6 +39,7 @@ func Publish(projectNumber string, topic string, token string, key string, data
if err != nil {
return errors.Wrap(err, "failed to marshal event")
}
+ log.Entry().Debugf("created pubsub event: %s", string(eventBytes))
// create request
request, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf(api_url, projectNumber, topic), bytes.NewReader(eventBytes))
diff --git a/resources/metadata/gcpPublishEvent.yaml b/resources/metadata/gcpPublishEvent.yaml
index fb7abd048f..4fa43826e8 100644
--- a/resources/metadata/gcpPublishEvent.yaml
+++ b/resources/metadata/gcpPublishEvent.yaml
@@ -81,3 +81,8 @@ spec:
resourceRef:
- name: commonPipelineEnvironment
param: custom/eventData
+ - name: additionalEventData
+ description: Data (formatted as JSON string) to add to eventData. This can be used to enrich eventData that comes from the pipeline environment.
+ type: string
+ scope:
+ - PARAMETERS
From bbd087e03d40cb7f3ca0f74d68b81fcb23a4965e Mon Sep 17 00:00:00 2001
From: Vyacheslav Starostin <32613074+vstarostin@users.noreply.github.com>
Date: Tue, 21 May 2024 14:35:26 +0500
Subject: [PATCH 03/16] Add Vault resource to parameters (#4932)
---
pkg/documentation/generator/parameters.go | 3 +++
1 file changed, 3 insertions(+)
diff --git a/pkg/documentation/generator/parameters.go b/pkg/documentation/generator/parameters.go
index f52a4ba712..bb66c832b9 100644
--- a/pkg/documentation/generator/parameters.go
+++ b/pkg/documentation/generator/parameters.go
@@ -337,6 +337,9 @@ func resourceReferenceDetails(resourceRef []config.ResourceReference) string {
func addVaultResourceDetails(resource config.ResourceReference, resourceDetails string) string {
if resource.Type == "vaultSecret" || resource.Type == "vaultSecretFile" {
+ resourceDetails += "
Vault resource:
"
+ resourceDetails += fmt.Sprintf(" name: `%v`
", resource.Name)
+ resourceDetails += fmt.Sprintf(" default value: `%v`
", resource.Default)
resourceDetails += "
Vault paths:
"
resourceDetails += "
"
for _, rootPath := range config.VaultRootPaths {
From a5061f33282dcbba39167e7a9adb30b1d4398753 Mon Sep 17 00:00:00 2001
From: Ralf Pannemans
Date: Thu, 23 May 2024 13:32:11 +0200
Subject: [PATCH 04/16] chore(deps): update syft version to 1.4.1 (#4933)
* Bump default syft version to 1.4.1
Co-authored-by: Pavel Busko
---
cmd/cnbBuild_generated.go | 4 ++--
cmd/kanikoExecute_generated.go | 4 ++--
cmd/kanikoExecute_test.go | 20 ++++++++++----------
integration/integration_cnb_test.go | 8 ++++----
pkg/syft/syft.go | 2 +-
pkg/syft/syft_test.go | 6 +++---
resources/metadata/cnbBuild.yaml | 2 +-
resources/metadata/kanikoExecute.yaml | 2 +-
8 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/cmd/cnbBuild_generated.go b/cmd/cnbBuild_generated.go
index e51fe38b09..0f573af8e7 100644
--- a/cmd/cnbBuild_generated.go
+++ b/cmd/cnbBuild_generated.go
@@ -250,7 +250,7 @@ func addCnbBuildFlags(cmd *cobra.Command, stepConfig *cnbBuildOptions) {
cmd.Flags().StringSliceVar(&stepConfig.PreserveFiles, "preserveFiles", []string{}, "List of globs, for keeping build results in the Jenkins workspace.\n\n*Note*: globs will be calculated relative to the [path](#path) property.\n")
cmd.Flags().StringVar(&stepConfig.BuildSettingsInfo, "buildSettingsInfo", os.Getenv("PIPER_buildSettingsInfo"), "Build settings info is typically filled by the step automatically to create information about the build settings that were used during the mta build. This information is typically used for compliance related processes.")
cmd.Flags().BoolVar(&stepConfig.CreateBOM, "createBOM", false, "Creates the bill of materials (BOM) using Syft and stores it in a file in CycloneDX 1.4 format.")
- cmd.Flags().StringVar(&stepConfig.SyftDownloadURL, "syftDownloadUrl", `https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz`, "Specifies the download url of the Syft Linux amd64 tar binary file. This can be found at https://github.com/anchore/syft/releases/.")
+ cmd.Flags().StringVar(&stepConfig.SyftDownloadURL, "syftDownloadUrl", `https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz`, "Specifies the download url of the Syft Linux amd64 tar binary file. This can be found at https://github.com/anchore/syft/releases/.")
cmd.Flags().StringVar(&stepConfig.RunImage, "runImage", os.Getenv("PIPER_runImage"), "Base image from which application images are built. Will be defaulted to the image provided by the builder.")
cmd.Flags().StringVar(&stepConfig.DefaultProcess, "defaultProcess", os.Getenv("PIPER_defaultProcess"), "Process that should be started by default. See https://buildpacks.io/docs/app-developer-guide/run-an-app/")
@@ -507,7 +507,7 @@ func cnbBuildMetadata() config.StepData {
Type: "string",
Mandatory: false,
Aliases: []config.Alias{},
- Default: `https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz`,
+ Default: `https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz`,
},
{
Name: "runImage",
diff --git a/cmd/kanikoExecute_generated.go b/cmd/kanikoExecute_generated.go
index c050a8cc4f..dba06a068e 100644
--- a/cmd/kanikoExecute_generated.go
+++ b/cmd/kanikoExecute_generated.go
@@ -314,7 +314,7 @@ func addKanikoExecuteFlags(cmd *cobra.Command, stepConfig *kanikoExecuteOptions)
cmd.Flags().StringSliceVar(&stepConfig.TargetArchitectures, "targetArchitectures", []string{``}, "Defines the target architectures for which the build should run using OS and architecture separated by a comma. (EXPERIMENTAL)")
cmd.Flags().BoolVar(&stepConfig.ReadImageDigest, "readImageDigest", false, "")
cmd.Flags().BoolVar(&stepConfig.CreateBOM, "createBOM", false, "Creates the bill of materials (BOM) using Syft and stores it in a file in CycloneDX 1.4 format.")
- cmd.Flags().StringVar(&stepConfig.SyftDownloadURL, "syftDownloadUrl", `https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz`, "Specifies the download url of the Syft Linux amd64 tar binary file. This can be found at https://github.com/anchore/syft/releases/.")
+ cmd.Flags().StringVar(&stepConfig.SyftDownloadURL, "syftDownloadUrl", `https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz`, "Specifies the download url of the Syft Linux amd64 tar binary file. This can be found at https://github.com/anchore/syft/releases/.")
}
@@ -554,7 +554,7 @@ func kanikoExecuteMetadata() config.StepData {
Type: "string",
Mandatory: false,
Aliases: []config.Alias{},
- Default: `https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz`,
+ Default: `https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz`,
},
},
},
diff --git a/cmd/kanikoExecute_test.go b/cmd/kanikoExecute_test.go
index b8aa6483ce..83c18fd7e2 100644
--- a/cmd/kanikoExecute_test.go
+++ b/cmd/kanikoExecute_test.go
@@ -360,7 +360,7 @@ func TestRunKanikoExecute(t *testing.T) {
assert.Equal(t, "https://index.docker.io", commonPipelineEnvironment.container.registryURL)
assert.Equal(t, "/tmp/syfttest/syft", execRunner.Calls[2].Exec)
- assert.Equal(t, []string{"packages", "registry:index.docker.io/myImage:tag", "-o", "cyclonedx-xml", "--file", "bom-docker-0.xml", "-q"}, execRunner.Calls[2].Params)
+ assert.Equal(t, []string{"scan", "registry:index.docker.io/myImage:tag", "-o", "cyclonedx-xml=bom-docker-0.xml", "-q"}, execRunner.Calls[2].Params)
})
t.Run("success case - multi image build with root image", func(t *testing.T) {
@@ -509,16 +509,16 @@ func TestRunKanikoExecute(t *testing.T) {
{"--dockerfile", "Dockerfile", "--context", "dir://" + cwd, "--destination", "my.registry.com:50000/myImage:myTag"},
{"--dockerfile", filepath.Join("sub1", "Dockerfile"), "--context", "dir://" + cwd, "--destination", "my.registry.com:50000/myImage-sub1:myTag"},
{"--dockerfile", filepath.Join("sub2", "Dockerfile"), "--context", "dir://" + cwd, "--destination", "my.registry.com:50000/myImage-sub2:myTag"},
- {"packages", "registry:my.registry.com:50000/myImage:myTag", "-o", "cyclonedx-xml", "--file"},
- {"packages", "registry:my.registry.com:50000/myImage-sub1:myTag", "-o", "cyclonedx-xml", "--file"},
- {"packages", "registry:my.registry.com:50000/myImage-sub2:myTag", "-o", "cyclonedx-xml", "--file"},
+ {"scan", "registry:my.registry.com:50000/myImage:myTag", "-o"},
+ {"scan", "registry:my.registry.com:50000/myImage-sub1:myTag", "-o"},
+ {"scan", "registry:my.registry.com:50000/myImage-sub2:myTag", "-o"},
}
// need to go this way since we cannot count on the correct order
for index, call := range execRunner.Calls {
found := false
for _, expected := range expectedParams {
- if expected[0] == "packages" {
- expected = append(expected, fmt.Sprintf("bom-docker-%d.xml", index-3), "-q")
+ if expected[0] == "scan" {
+ expected = append(expected, fmt.Sprintf("cyclonedx-xml=bom-docker-%d.xml", index-3), "-q")
}
if strings.Join(call.Params, " ") == strings.Join(expected, " ") {
found = true
@@ -662,15 +662,15 @@ func TestRunKanikoExecute(t *testing.T) {
expectedParams := [][]string{
{"--dockerfile", "Dockerfile", "--context", "dir://" + cwd, "--context-sub-path", "/test1", "--destination", "my.registry.com:50000/myImageOne:myTag"},
{"--dockerfile", "Dockerfile", "--context", "dir://" + cwd, "--context-sub-path", "/test2", "--destination", "my.registry.com:50000/myImageTwo:myTagTwo"},
- {"packages", "registry:my.registry.com:50000/myImageOne:myTag", "-o", "cyclonedx-xml", "--file"},
- {"packages", "registry:my.registry.com:50000/myImageTwo:myTagTwo", "-o", "cyclonedx-xml", "--file"},
+ {"scan", "registry:my.registry.com:50000/myImageOne:myTag", "-o"},
+ {"scan", "registry:my.registry.com:50000/myImageTwo:myTagTwo", "-o"},
}
// need to go this way since we cannot count on the correct order
for index, call := range execRunner.Calls {
found := false
for _, expected := range expectedParams {
- if expected[0] == "packages" {
- expected = append(expected, fmt.Sprintf("bom-docker-%d.xml", index-2), "-q")
+ if expected[0] == "scan" {
+ expected = append(expected, fmt.Sprintf("cyclonedx-xml=bom-docker-%d.xml", index-2), "-q")
}
if strings.Join(call.Params, " ") == strings.Join(expected, " ") {
found = true
diff --git a/integration/integration_cnb_test.go b/integration/integration_cnb_test.go
index 01bb6cefc0..8db6b38d6f 100644
--- a/integration/integration_cnb_test.go
+++ b/integration/integration_cnb_test.go
@@ -163,7 +163,7 @@ func TestCNBIntegrationZipPath(t *testing.T) {
fmt.Sprintf("Saving %s/not-found:0.0.1", registryURL),
"*** Images (sha256:",
"SUCCESS",
- "syft packages registry:localhost:5000/not-found:0.0.1 -o cyclonedx-xml --file bom-docker-0.xml -q",
+ "syft scan registry:localhost:5000/not-found:0.0.1 -o cyclonedx-xml=bom-docker-0.xml -q",
)
container.assertHasFiles(t, "/project/bom-docker-0.xml")
container.terminate(t)
@@ -309,9 +309,9 @@ func TestCNBIntegrationMultiImage(t *testing.T) {
"Saving localhost:5000/go-app:v1.0.0...",
"Using cached buildpack",
"Saving localhost:5000/my-app2:latest...",
- "syft packages registry:localhost:5000/io-buildpacks-my-app:latest -o cyclonedx-xml --file bom-docker-0.xml -q",
- "syft packages registry:localhost:5000/go-app:v1.0.0 -o cyclonedx-xml --file bom-docker-1.xml -q",
- "syft packages registry:localhost:5000/my-app2:latest -o cyclonedx-xml --file bom-docker-2.xml -q",
+ "syft scan registry:localhost:5000/io-buildpacks-my-app:latest -o cyclonedx-xml=bom-docker-0.xml -q",
+ "syft scan registry:localhost:5000/go-app:v1.0.0 -o cyclonedx-xml=bom-docker-1.xml -q",
+ "syft scan registry:localhost:5000/my-app2:latest -o cyclonedx-xml=bom-docker-2.xml -q",
)
container.assertHasFiles(t, "/project/bom-docker-0.xml")
diff --git a/pkg/syft/syft.go b/pkg/syft/syft.go
index 4600323b6c..48a2f6b484 100644
--- a/pkg/syft/syft.go
+++ b/pkg/syft/syft.go
@@ -42,7 +42,7 @@ func GenerateSBOM(syftDownloadURL, dockerConfigDir string, execRunner command.Ex
return errors.New("syft: image name must not be empty")
}
// TrimPrefix needed as syft needs containerRegistry name only
- err = execRunner.RunExecutable(syftFile, "packages", fmt.Sprintf("registry:%s/%s", strings.TrimPrefix(registryURL, "https://"), image), "-o", "cyclonedx-xml", "--file", fmt.Sprintf("bom-docker-%v.xml", index), "-q")
+ err = execRunner.RunExecutable(syftFile, "scan", fmt.Sprintf("registry:%s/%s", strings.TrimPrefix(registryURL, "https://"), image), "-o", fmt.Sprintf("cyclonedx-xml=bom-docker-%v.xml", index), "-q")
if err != nil {
return fmt.Errorf("failed to generate SBOM: %w", err)
}
diff --git a/pkg/syft/syft_test.go b/pkg/syft/syft_test.go
index bfc8e73789..c651c1d7e5 100644
--- a/pkg/syft/syft_test.go
+++ b/pkg/syft/syft_test.go
@@ -44,17 +44,17 @@ func TestGenerateSBOM(t *testing.T) {
assert.Len(t, execMock.Calls, 2)
firstCall := execMock.Calls[0]
assert.Equal(t, firstCall.Exec, "/tmp/syfttest/syft")
- assert.Equal(t, firstCall.Params, []string{"packages", "registry:my-registry/image:latest", "-o", "cyclonedx-xml", "--file", "bom-docker-0.xml", "-q"})
+ assert.Equal(t, firstCall.Params, []string{"scan", "registry:my-registry/image:latest", "-o", "cyclonedx-xml=bom-docker-0.xml", "-q"})
secondCall := execMock.Calls[1]
assert.Equal(t, secondCall.Exec, "/tmp/syfttest/syft")
- assert.Equal(t, secondCall.Params, []string{"packages", "registry:my-registry/image:1.2.3", "-o", "cyclonedx-xml", "--file", "bom-docker-1.xml", "-q"})
+ assert.Equal(t, secondCall.Params, []string{"scan", "registry:my-registry/image:1.2.3", "-o", "cyclonedx-xml=bom-docker-1.xml", "-q"})
})
t.Run("error case: syft execution failed", func(t *testing.T) {
execMock = mock.ExecMockRunner{}
execMock.ShouldFailOnCommand = map[string]error{
- "/tmp/syfttest/syft packages registry:my-registry/image:latest -o cyclonedx-xml --file bom-docker-0.xml -q": errors.New("failed"),
+ "/tmp/syfttest/syft scan registry:my-registry/image:latest -o cyclonedx-xml=bom-docker-0.xml -q": errors.New("failed"),
}
err := syft.GenerateSBOM("http://test-syft-gh-release.com/syft.tar.gz", "", &execMock, &fileMock, client, "https://my-registry", []string{"image:latest"})
diff --git a/resources/metadata/cnbBuild.yaml b/resources/metadata/cnbBuild.yaml
index d6e7427f94..744035e14d 100644
--- a/resources/metadata/cnbBuild.yaml
+++ b/resources/metadata/cnbBuild.yaml
@@ -339,7 +339,7 @@ spec:
scope:
- PARAMETERS
- STEPS
- default: "https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz"
+ default: "https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz"
- name: runImage
type: string
description: "Base image from which application images are built. Will be defaulted to the image provided by the builder."
diff --git a/resources/metadata/kanikoExecute.yaml b/resources/metadata/kanikoExecute.yaml
index f8acefba0b..5efad0931c 100644
--- a/resources/metadata/kanikoExecute.yaml
+++ b/resources/metadata/kanikoExecute.yaml
@@ -305,7 +305,7 @@ spec:
scope:
- PARAMETERS
- STEPS
- default: "https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz"
+ default: "https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz"
outputs:
resources:
- name: commonPipelineEnvironment
From 77758b3db0b639b4529ed42b045dfa1df75f50bb Mon Sep 17 00:00:00 2001
From: Ralf Pannemans
Date: Thu, 23 May 2024 13:44:22 +0200
Subject: [PATCH 05/16] feat(cnbBuild): Only use sbom-cataloger with cnb images
(#4934)
---
cmd/cnbBuild.go | 10 +++++++++-
pkg/syft/syft.go | 44 +++++++++++++++++++++++++++++++++----------
pkg/syft/syft_test.go | 2 +-
3 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/cmd/cnbBuild.go b/cmd/cnbBuild.go
index f5d6a3e76a..6ee7a5d3d1 100644
--- a/cmd/cnbBuild.go
+++ b/cmd/cnbBuild.go
@@ -346,7 +346,15 @@ func callCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData,
buildSummary.Print()
if config.CreateBOM {
- err = syft.GenerateSBOM(config.SyftDownloadURL, filepath.Dir(config.DockerConfigJSON), utils, utils, httpClient, commonPipelineEnvironment.container.registryURL, commonPipelineEnvironment.container.imageNameTags)
+ log.Entry().Debugf("Creating sbom for %d images\n", len(commonPipelineEnvironment.container.imageNameTags))
+ syftScanner, err := syft.CreateSyftScanner(config.SyftDownloadURL, utils, httpClient)
+ if err != nil {
+ log.SetErrorCategory(log.ErrorCompliance)
+ return errors.Wrap(err, "failed to create syft scanner file")
+ }
+ // images produces with cnb have sboms
+ syftScanner.AddArgument("--override-default-catalogers=sbom-cataloger")
+ err = syftScanner.ScanImages(filepath.Dir(config.DockerConfigJSON), utils, commonPipelineEnvironment.container.registryURL, commonPipelineEnvironment.container.imageNameTags)
if err != nil {
log.SetErrorCategory(log.ErrorCompliance)
return errors.Wrap(err, "failed to create BOM file")
diff --git a/pkg/syft/syft.go b/pkg/syft/syft.go
index 48a2f6b484..2d0f01935c 100644
--- a/pkg/syft/syft.go
+++ b/pkg/syft/syft.go
@@ -15,34 +15,58 @@ import (
"github.com/pkg/errors"
)
-func GenerateSBOM(syftDownloadURL, dockerConfigDir string, execRunner command.ExecRunner, fileUtils piperutils.FileUtils, httpClient piperhttp.Sender, registryURL string, images []string) error {
- if registryURL == "" {
- return errors.New("syft: regisitry url must not be empty")
- }
+type SyftScanner struct {
+ syftFile string
+ additionalArgs []string
+}
- if len(images) == 0 {
- return errors.New("syft: no images provided")
+func GenerateSBOM(syftDownloadURL, dockerConfigDir string, execRunner command.ExecRunner, fileUtils piperutils.FileUtils, httpClient piperhttp.Sender, registryURL string, images []string) error {
+ scanner, err := CreateSyftScanner(syftDownloadURL, fileUtils, httpClient)
+ if err != nil {
+ return err
}
+ return scanner.ScanImages(dockerConfigDir, execRunner, registryURL, images)
+}
- execRunner.AppendEnv([]string{fmt.Sprintf("DOCKER_CONFIG=%s", dockerConfigDir)})
+func CreateSyftScanner(syftDownloadURL string, fileUtils piperutils.FileUtils, httpClient piperhttp.Sender) (*SyftScanner, error) {
tmpDir, err := fileUtils.TempDir("", "syft")
if err != nil {
- return err
+ return nil, err
}
syftFile := filepath.Join(tmpDir, "syft")
err = install(syftDownloadURL, syftFile, fileUtils, httpClient)
if err != nil {
- return errors.Wrap(err, "failed to install syft")
+ return nil, errors.Wrap(err, "failed to install syft")
}
+ return &SyftScanner{syftFile: syftFile}, nil
+}
+
+func (s *SyftScanner) AddArgument(arg string) {
+ s.additionalArgs = append(s.additionalArgs, arg)
+}
+
+func (s *SyftScanner) ScanImages(dockerConfigDir string, execRunner command.ExecRunner, registryURL string, images []string) error {
+ if registryURL == "" {
+ return errors.New("syft: registry url must not be empty")
+ }
+
+ if len(images) == 0 {
+ return errors.New("syft: no images provided")
+ }
+
+ execRunner.AppendEnv([]string{fmt.Sprintf("DOCKER_CONFIG=%s", dockerConfigDir)})
+
for index, image := range images {
if image == "" {
return errors.New("syft: image name must not be empty")
}
// TrimPrefix needed as syft needs containerRegistry name only
- err = execRunner.RunExecutable(syftFile, "scan", fmt.Sprintf("registry:%s/%s", strings.TrimPrefix(registryURL, "https://"), image), "-o", fmt.Sprintf("cyclonedx-xml=bom-docker-%v.xml", index), "-q")
+ args := []string{"scan", fmt.Sprintf("registry:%s/%s", strings.TrimPrefix(registryURL, "https://"), image), "-o", fmt.Sprintf("cyclonedx-xml=bom-docker-%v.xml", index), "-q"}
+ args = append(args, s.additionalArgs...)
+ err := execRunner.RunExecutable(s.syftFile, args...)
if err != nil {
return fmt.Errorf("failed to generate SBOM: %w", err)
}
diff --git a/pkg/syft/syft_test.go b/pkg/syft/syft_test.go
index c651c1d7e5..93ad0e7888 100644
--- a/pkg/syft/syft_test.go
+++ b/pkg/syft/syft_test.go
@@ -65,7 +65,7 @@ func TestGenerateSBOM(t *testing.T) {
t.Run("error case: no registry", func(t *testing.T) {
err := syft.GenerateSBOM("http://test-syft-gh-release.com/syft.tar.gz", "", &execMock, &fileMock, client, "", []string{"image:latest"})
assert.Error(t, err)
- assert.Equal(t, "syft: regisitry url must not be empty", err.Error())
+ assert.Equal(t, "syft: registry url must not be empty", err.Error())
})
t.Run("error case: no images provided", func(t *testing.T) {
From f7543be3b09a5c08c7cb000e4c44e4513cd8db0c Mon Sep 17 00:00:00 2001
From: Dmitrii Pavlukhin
Date: Fri, 24 May 2024 12:01:45 +0300
Subject: [PATCH 06/16] Implement MTA build for detectExecuteScan step (#4876)
* added-parameter
* added-platform-param-for-mta-build
* add-verbose-build-config-output
* set-install-artifacts-true
* comment-m2-defaults
* returned-m2-param
* synced-with-master
* fix-yaml
* fix-yaml2
* fix-yaml3
* fix-yaml3
* fix-yaml4
* returned-m2path-in-folder
---------
Co-authored-by: Andrei Kireev
---
cmd/detectExecuteScan.go | 38 +++++++++++++++++++++++
cmd/detectExecuteScan_generated.go | 22 +++++++++++++
resources/metadata/detectExecuteScan.yaml | 17 ++++++++++
3 files changed, 77 insertions(+)
diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go
index 070f87e22b..3d6e89e02d 100644
--- a/cmd/detectExecuteScan.go
+++ b/cmd/detectExecuteScan.go
@@ -213,6 +213,18 @@ func runDetect(ctx context.Context, config detectExecuteScanOptions, utils detec
}
}
+ // for MTA
+ if config.BuildMTA {
+ log.Entry().Infof("running MTA Build")
+ mtaConfig := setMTAConfig(config)
+ mtaUtils := newMtaBuildUtilsBundle()
+
+ err := runMtaBuild(mtaConfig, &mtaBuildCommonPipelineEnvironment{}, mtaUtils)
+ if err != nil {
+ return err
+ }
+ }
+
blackduckSystem := newBlackduckSystem(config)
args := []string{"./detect.sh"}
@@ -1040,9 +1052,35 @@ func setMavenConfig(config detectExecuteScanOptions) mavenBuildOptions {
Publish: false,
}
+ // Print the mavenBuildOptions configuration in verbose mode
+ log.Entry().Debugf("Maven configuration: %v", mavenConfig)
+
return mavenConfig
}
+func setMTAConfig(config detectExecuteScanOptions) mtaBuildOptions {
+
+ if config.M2Path == "" {
+ config.M2Path = ".m2"
+ }
+
+ mtaConfig := mtaBuildOptions{
+ ProjectSettingsFile: config.ProjectSettingsFile,
+ GlobalSettingsFile: config.GlobalSettingsFile,
+ M2Path: config.M2Path,
+ Platform: config.MtaPlatform,
+ InstallArtifacts: true,
+ CreateBOM: false,
+ }
+
+ // Print the mtaBuildOptions configuration in verbose mode
+
+ log.Entry().Debugf("MTA configuration: %v", mtaConfig)
+
+ return mtaConfig
+
+}
+
func logConfigInVerboseMode(config detectExecuteScanOptions) {
config.Token = "********"
config.GithubToken = "********"
diff --git a/cmd/detectExecuteScan_generated.go b/cmd/detectExecuteScan_generated.go
index e08238bb90..356bfe4d29 100644
--- a/cmd/detectExecuteScan_generated.go
+++ b/cmd/detectExecuteScan_generated.go
@@ -41,7 +41,9 @@ type detectExecuteScanOptions struct {
M2Path string `json:"m2Path,omitempty"`
InstallArtifacts bool `json:"installArtifacts,omitempty"`
BuildMaven bool `json:"buildMaven,omitempty"`
+ BuildMTA bool `json:"buildMTA,omitempty"`
GenerateReportsForEmptyProjects bool `json:"generateReportsForEmptyProjects,omitempty"`
+ MtaPlatform string `json:"mtaPlatform,omitempty"`
PomPath string `json:"pomPath,omitempty"`
IncludedPackageManagers []string `json:"includedPackageManagers,omitempty"`
ExcludedPackageManagers []string `json:"excludedPackageManagers,omitempty"`
@@ -294,7 +296,9 @@ func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScan
cmd.Flags().StringVar(&stepConfig.M2Path, "m2Path", os.Getenv("PIPER_m2Path"), "Path to the location of the local repository that should be used.")
cmd.Flags().BoolVar(&stepConfig.InstallArtifacts, "installArtifacts", false, "If enabled, it will install all artifacts to the local maven repository to make them available before running detect. This is required if any maven module has dependencies to other modules in the repository and they were not installed before.")
cmd.Flags().BoolVar(&stepConfig.BuildMaven, "buildMaven", false, "Experiment parameter for maven multi-modules projects building")
+ cmd.Flags().BoolVar(&stepConfig.BuildMTA, "buildMTA", false, "Experiment parameter for MTA projects building")
cmd.Flags().BoolVar(&stepConfig.GenerateReportsForEmptyProjects, "generateReportsForEmptyProjects", false, "If enabled, it will generate reports for empty projects. This could be useful to see the compliance reports in Sirius")
+ cmd.Flags().StringVar(&stepConfig.MtaPlatform, "mtaPlatform", `CF`, "The platform of the MTA project")
cmd.Flags().StringVar(&stepConfig.PomPath, "pomPath", `pom.xml`, "Path to the pom file which should be installed including all children.")
cmd.Flags().StringSliceVar(&stepConfig.IncludedPackageManagers, "includedPackageManagers", []string{}, "The package managers that need to be included for this scan. Providing the package manager names with this parameter will ensure that the build descriptor file of that package manager will be searched in the scan folder For the complete list of possible values for this parameter, please refer [Synopsys detect documentation](https://community.synopsys.com/s/document-item?bundleId=integrations-detect&topicId=properties%2Fconfiguration%2Fdetector.html&_LANG=enus&anchor=detector-types-included-advanced)")
cmd.Flags().StringSliceVar(&stepConfig.ExcludedPackageManagers, "excludedPackageManagers", []string{}, "The package managers that need to be excluded for this scan. Providing the package manager names with this parameter will ensure that the build descriptor file of that package manager will be ignored in the scan folder For the complete list of possible values for this parameter, please refer [Synopsys detect documentation](https://community.synopsys.com/s/document-item?bundleId=integrations-detect&topicId=properties%2Fconfiguration%2Fdetector.html&_LANG=enus&anchor=detector-types-excluded-advanced)")
@@ -537,6 +541,15 @@ func detectExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: false,
},
+ {
+ Name: "buildMTA",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"STEPS", "STAGES", "PARAMETERS"},
+ Type: "bool",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: false,
+ },
{
Name: "generateReportsForEmptyProjects",
ResourceRef: []config.ResourceReference{},
@@ -546,6 +559,15 @@ func detectExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: false,
},
+ {
+ Name: "mtaPlatform",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: `CF`,
+ },
{
Name: "pomPath",
ResourceRef: []config.ResourceReference{},
diff --git a/resources/metadata/detectExecuteScan.yaml b/resources/metadata/detectExecuteScan.yaml
index 8873952f2f..636e688914 100644
--- a/resources/metadata/detectExecuteScan.yaml
+++ b/resources/metadata/detectExecuteScan.yaml
@@ -257,6 +257,15 @@ spec:
- STEPS
- STAGES
- PARAMETERS
+ - name: buildMTA
+ type: bool
+ default: false
+ description:
+ "Experiment parameter for MTA projects building"
+ scope:
+ - STEPS
+ - STAGES
+ - PARAMETERS
- name: generateReportsForEmptyProjects
type: bool
default: false
@@ -266,6 +275,14 @@ spec:
- STEPS
- STAGES
- PARAMETERS
+ - name: mtaPlatform
+ type: string
+ description: "The platform of the MTA project"
+ default: "CF"
+ scope:
+ - PARAMETERS
+ - STAGES
+ - STEPS
- name: pomPath
type: string
description: Path to the pom file which should be installed including all children.
From 8924b9786e0c9856c6824d256710f55f642cd3b1 Mon Sep 17 00:00:00 2001
From: Daria Kuznetsova
Date: Mon, 27 May 2024 13:09:05 +0200
Subject: [PATCH 07/16] feat(codeqlExecuteScan): added a feature to execute
custom command (#4912)
* added running custom command
* go mod tidy
* added log with parsed command info
* fixed log format
---------
Co-authored-by: sumeet patil
---
cmd/codeqlExecuteScan.go | 26 +++++++++++++++++++++++
cmd/codeqlExecuteScan_generated.go | 11 ++++++++++
go.mod | 2 +-
resources/metadata/codeqlExecuteScan.yaml | 7 ++++++
4 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/cmd/codeqlExecuteScan.go b/cmd/codeqlExecuteScan.go
index fdace77ad3..546a310dd5 100644
--- a/cmd/codeqlExecuteScan.go
+++ b/cmd/codeqlExecuteScan.go
@@ -15,6 +15,7 @@ import (
"github.com/SAP/jenkins-library/pkg/maven"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/telemetry"
+ "github.com/google/shlex"
"github.com/pkg/errors"
)
@@ -139,6 +140,13 @@ func runCodeqlExecuteScan(config *codeqlExecuteScanOptions, telemetryData *telem
}
reports = append(reports, scanReports...)
+ if len(config.CustomCommand) > 0 {
+ err = runCustomCommand(utils, config.CustomCommand)
+ if err != nil {
+ return reports, err
+ }
+ }
+
repoInfo, err := codeql.GetRepoInfo(config.Repository, config.AnalyzedRef, config.CommitID,
config.TargetGithubRepoURL, config.TargetGithubBranchName)
if err != nil {
@@ -394,6 +402,24 @@ func uploadProjectToGitHub(config *codeqlExecuteScanOptions, repoInfo *codeql.Re
return nil
}
+func runCustomCommand(utils codeqlExecuteScanUtils, command string) error {
+ log.Entry().Infof("custom command will be run: %s", command)
+ cmd, err := shlex.Split(command)
+ if err != nil {
+ log.Entry().WithError(err).Errorf("failed to parse custom command %s", command)
+ return err
+ }
+ log.Entry().Infof("Parsed command '%s' with %d arguments: ['%s']", cmd[0], len(cmd[1:]), strings.Join(cmd[1:], "', '"))
+
+ err = utils.RunExecutable(cmd[0], cmd[1:]...)
+ if err != nil {
+ log.Entry().WithError(err).Errorf("failed to run command %s", command)
+ return err
+ }
+ log.Entry().Info("Success.")
+ return nil
+}
+
func checkForCompliance(scanResults []codeql.CodeqlFindings, config *codeqlExecuteScanOptions, repoInfo *codeql.RepoInfo) error {
for _, scanResult := range scanResults {
if scanResult.ClassificationName == codeql.AuditAll {
diff --git a/cmd/codeqlExecuteScan_generated.go b/cmd/codeqlExecuteScan_generated.go
index b7cb31e10c..bd4ac20aba 100644
--- a/cmd/codeqlExecuteScan_generated.go
+++ b/cmd/codeqlExecuteScan_generated.go
@@ -45,6 +45,7 @@ type codeqlExecuteScanOptions struct {
GlobalSettingsFile string `json:"globalSettingsFile,omitempty"`
DatabaseCreateFlags string `json:"databaseCreateFlags,omitempty"`
DatabaseAnalyzeFlags string `json:"databaseAnalyzeFlags,omitempty"`
+ CustomCommand string `json:"customCommand,omitempty"`
}
type codeqlExecuteScanInflux struct {
@@ -271,6 +272,7 @@ func addCodeqlExecuteScanFlags(cmd *cobra.Command, stepConfig *codeqlExecuteScan
cmd.Flags().StringVar(&stepConfig.GlobalSettingsFile, "globalSettingsFile", os.Getenv("PIPER_globalSettingsFile"), "Path to the mvn settings file that should be used as global settings file.")
cmd.Flags().StringVar(&stepConfig.DatabaseCreateFlags, "databaseCreateFlags", os.Getenv("PIPER_databaseCreateFlags"), "A space-separated string of flags for the 'codeql database create' command.")
cmd.Flags().StringVar(&stepConfig.DatabaseAnalyzeFlags, "databaseAnalyzeFlags", os.Getenv("PIPER_databaseAnalyzeFlags"), "A space-separated string of flags for the 'codeql database analyze' command.")
+ cmd.Flags().StringVar(&stepConfig.CustomCommand, "customCommand", os.Getenv("PIPER_customCommand"), "A custom user-defined command to run between codeql analysis and results upload.")
cmd.MarkFlagRequired("buildTool")
}
@@ -527,6 +529,15 @@ func codeqlExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_databaseAnalyzeFlags"),
},
+ {
+ Name: "customCommand",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"STEPS", "STAGES", "PARAMETERS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: os.Getenv("PIPER_customCommand"),
+ },
},
},
Containers: []config.Container{
diff --git a/go.mod b/go.mod
index b2c2299b60..ddaceac057 100644
--- a/go.mod
+++ b/go.mod
@@ -177,7 +177,7 @@ require (
github.com/google/btree v1.0.1 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
+ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.2 // indirect
github.com/gorilla/mux v1.8.0 // indirect
diff --git a/resources/metadata/codeqlExecuteScan.yaml b/resources/metadata/codeqlExecuteScan.yaml
index f489299d71..eb9c5d9374 100644
--- a/resources/metadata/codeqlExecuteScan.yaml
+++ b/resources/metadata/codeqlExecuteScan.yaml
@@ -233,6 +233,13 @@ spec:
- STEPS
- STAGES
- PARAMETERS
+ - name: customCommand
+ type: string
+ description: "A custom user-defined command to run between codeql analysis and results upload."
+ scope:
+ - STEPS
+ - STAGES
+ - PARAMETERS
containers:
- image: ""
outputs:
From ce34dd3f3c8b6aade9efdb76d0a81bfa5c4bd0fd Mon Sep 17 00:00:00 2001
From: Jordi van Liempt <35920075+jliempt@users.noreply.github.com>
Date: Tue, 28 May 2024 14:19:17 +0200
Subject: [PATCH 08/16] fix(gcpPublishEvent): Error handling in non-standard
Vault cases (#4938)
* fix error handling in non-standard Vault cases
* handle case where Vault isn't configured and no error is thrown
* remove unnecessary return
---------
Co-authored-by: jliempt <>
---
cmd/gcpPublishEvent.go | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/cmd/gcpPublishEvent.go b/cmd/gcpPublishEvent.go
index 46600112af..595cf9d2bb 100644
--- a/cmd/gcpPublishEvent.go
+++ b/cmd/gcpPublishEvent.go
@@ -48,14 +48,16 @@ func gcpPublishEvent(config gcpPublishEventOptions, telemetryData *telemetry.Cus
}
client, err := piperConfig.GetVaultClientFromConfig(vaultConfig, vaultCreds)
- if err != nil {
- log.Entry().WithError(err).Warnf("could not create Vault client")
+ if err != nil || client == nil {
+ log.Entry().WithError(err).Warnf("could not create Vault client: incomplete Vault configuration")
+ return
}
defer client.MustRevokeToken()
vaultClient, ok := client.(vault.Client)
if !ok {
log.Entry().WithError(err).Warnf("could not create Vault client")
+ return
}
utils := gcpPublishEventUtilsBundle{
From c4019cf86035b9eecee005832a6e3299f7ccbe05 Mon Sep 17 00:00:00 2001
From: Dmitrii Pavlukhin
Date: Tue, 28 May 2024 17:52:14 +0300
Subject: [PATCH 09/16] detectExecuteScan - added parameter for diagnostic mode
(#4937)
* detectExecuteScan - added parameter for diagnostic mode
* changed-syntax
* added-custom-output-path
* amended-directory-creation
---
cmd/detectExecuteScan.go | 15 +++++++++++++++
cmd/detectExecuteScan_generated.go | 11 +++++++++++
resources/metadata/detectExecuteScan.yaml | 9 +++++++++
3 files changed, 35 insertions(+)
diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go
index 3d6e89e02d..d2a9213c36 100644
--- a/cmd/detectExecuteScan.go
+++ b/cmd/detectExecuteScan.go
@@ -528,6 +528,21 @@ func addDetectArgs(args []string, config detectExecuteScanOptions, utils detectU
args = append(args, fmt.Sprintf("--detect.tools=%v", strings.Join(config.DetectTools, ",")))
}
+ if config.EnableDiagnostics {
+ args = append(args, fmt.Sprintf("\"--detect.diagnostic=true\""))
+ args = append(args, fmt.Sprintf("\"--detect.cleanup=false\""))
+
+ err := utils.MkdirAll("./blackduckDiagnostics", 0o755)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to create diagnostics directory")
+ }
+
+ log.Entry().Info("Diagnostics enabled, output will be stored in ./blackduckDiagnostics")
+
+ args = append(args, fmt.Sprintf("\"--detect.scan.output.path=./blackduckDiagnostics\""))
+ args = append(args, fmt.Sprintf("\"--detect.output.path=./blackduckDiagnostics\""))
+ }
+
// to exclude dependency types for npm
if len(config.NpmDependencyTypesExcluded) > 0 && !checkIfArgumentIsInScanProperties(config, "detect.npm.dependency.types.excluded") {
args = append(args, fmt.Sprintf("--detect.npm.dependency.types.excluded=%v", strings.ToUpper(strings.Join(config.NpmDependencyTypesExcluded, ","))))
diff --git a/cmd/detectExecuteScan_generated.go b/cmd/detectExecuteScan_generated.go
index 356bfe4d29..7546438d9d 100644
--- a/cmd/detectExecuteScan_generated.go
+++ b/cmd/detectExecuteScan_generated.go
@@ -42,6 +42,7 @@ type detectExecuteScanOptions struct {
InstallArtifacts bool `json:"installArtifacts,omitempty"`
BuildMaven bool `json:"buildMaven,omitempty"`
BuildMTA bool `json:"buildMTA,omitempty"`
+ EnableDiagnostics bool `json:"enableDiagnostics,omitempty"`
GenerateReportsForEmptyProjects bool `json:"generateReportsForEmptyProjects,omitempty"`
MtaPlatform string `json:"mtaPlatform,omitempty"`
PomPath string `json:"pomPath,omitempty"`
@@ -297,6 +298,7 @@ func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScan
cmd.Flags().BoolVar(&stepConfig.InstallArtifacts, "installArtifacts", false, "If enabled, it will install all artifacts to the local maven repository to make them available before running detect. This is required if any maven module has dependencies to other modules in the repository and they were not installed before.")
cmd.Flags().BoolVar(&stepConfig.BuildMaven, "buildMaven", false, "Experiment parameter for maven multi-modules projects building")
cmd.Flags().BoolVar(&stepConfig.BuildMTA, "buildMTA", false, "Experiment parameter for MTA projects building")
+ cmd.Flags().BoolVar(&stepConfig.EnableDiagnostics, "enableDiagnostics", false, "Parameter to enable diagnostics file generation by detect script")
cmd.Flags().BoolVar(&stepConfig.GenerateReportsForEmptyProjects, "generateReportsForEmptyProjects", false, "If enabled, it will generate reports for empty projects. This could be useful to see the compliance reports in Sirius")
cmd.Flags().StringVar(&stepConfig.MtaPlatform, "mtaPlatform", `CF`, "The platform of the MTA project")
cmd.Flags().StringVar(&stepConfig.PomPath, "pomPath", `pom.xml`, "Path to the pom file which should be installed including all children.")
@@ -550,6 +552,15 @@ func detectExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: false,
},
+ {
+ Name: "enableDiagnostics",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"STEPS", "STAGES", "PARAMETERS"},
+ Type: "bool",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: false,
+ },
{
Name: "generateReportsForEmptyProjects",
ResourceRef: []config.ResourceReference{},
diff --git a/resources/metadata/detectExecuteScan.yaml b/resources/metadata/detectExecuteScan.yaml
index 636e688914..d92bc5dba7 100644
--- a/resources/metadata/detectExecuteScan.yaml
+++ b/resources/metadata/detectExecuteScan.yaml
@@ -266,6 +266,15 @@ spec:
- STEPS
- STAGES
- PARAMETERS
+ - name: enableDiagnostics
+ type: bool
+ default: false
+ description:
+ "Parameter to enable diagnostics file generation by detect script"
+ scope:
+ - STEPS
+ - STAGES
+ - PARAMETERS
- name: generateReportsForEmptyProjects
type: bool
default: false
From 3e86491c181e15392b5d6a37e058821452aba20b Mon Sep 17 00:00:00 2001
From: Dmitrii Pavlukhin
Date: Fri, 31 May 2024 17:43:24 +0300
Subject: [PATCH 10/16] detectExecuteScan - fix for diagnostics folder path
(#4940)
---
cmd/detectExecuteScan.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go
index d2a9213c36..eb608f0c63 100644
--- a/cmd/detectExecuteScan.go
+++ b/cmd/detectExecuteScan.go
@@ -532,15 +532,15 @@ func addDetectArgs(args []string, config detectExecuteScanOptions, utils detectU
args = append(args, fmt.Sprintf("\"--detect.diagnostic=true\""))
args = append(args, fmt.Sprintf("\"--detect.cleanup=false\""))
- err := utils.MkdirAll("./blackduckDiagnostics", 0o755)
+ err := utils.MkdirAll(".pipeline/blackduckDiagnostics", 0o755)
if err != nil {
return nil, errors.Wrap(err, "failed to create diagnostics directory")
}
- log.Entry().Info("Diagnostics enabled, output will be stored in ./blackduckDiagnostics")
+ log.Entry().Info("Diagnostics enabled, output will be stored in .pipeline/blackduckDiagnostics")
- args = append(args, fmt.Sprintf("\"--detect.scan.output.path=./blackduckDiagnostics\""))
- args = append(args, fmt.Sprintf("\"--detect.output.path=./blackduckDiagnostics\""))
+ args = append(args, fmt.Sprintf("\"--detect.scan.output.path=.pipeline/blackduckDiagnostics\""))
+ args = append(args, fmt.Sprintf("\"--detect.output.path=.pipeline/blackduckDiagnostics\""))
}
// to exclude dependency types for npm
From 22ff5717b31b9171d756ca33fa15f1367bf0c2c2 Mon Sep 17 00:00:00 2001
From: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com>
Date: Mon, 3 Jun 2024 09:45:07 +0200
Subject: [PATCH 11/16] fix(vault): consider vault flags (#4486)
* fix(vault): consider vault flags
* fix problem introduced with merge conflict resolution
---------
Co-authored-by: Jk1484 <35270240+Jk1484@users.noreply.github.com>
---
pkg/config/config.go | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 65803ec296..e41873f898 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -236,7 +236,8 @@ func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON stri
// merge command line flags
if flagValues != nil {
- stepConfig.mixIn(flagValues, filters.Parameters, metadata)
+ flagFilter := append(filters.Parameters, vaultFilter...)
+ stepConfig.mixIn(flagValues, flagFilter, metadata)
}
if verbose, ok := stepConfig.Config["verbose"].(bool); ok && verbose {
@@ -325,7 +326,6 @@ func GetStepConfigWithJSON(flagValues map[string]interface{}, stepConfigJSON str
}
func (c *Config) GetStageConfig(paramJSON string, configuration io.ReadCloser, defaults []io.ReadCloser, ignoreCustomDefaults bool, acceptedParams []string, stageName string) (StepConfig, error) {
-
filters := StepFilters{
General: acceptedParams,
Steps: []string{},
@@ -338,7 +338,6 @@ func (c *Config) GetStageConfig(paramJSON string, configuration io.ReadCloser, d
// GetJSON returns JSON representation of an object
func GetJSON(data interface{}) (string, error) {
-
result, err := json.Marshal(data)
if err != nil {
return "", errors.Wrapf(err, "error marshalling json: %v", err)
@@ -348,7 +347,6 @@ func GetJSON(data interface{}) (string, error) {
// GetYAML returns YAML representation of an object
func GetYAML(data interface{}) (string, error) {
-
result, err := yaml.Marshal(data)
if err != nil {
return "", errors.Wrapf(err, "error marshalling yaml: %v", err)
@@ -370,7 +368,6 @@ func OpenPiperFile(name string, accessTokens map[string]string) (io.ReadCloser,
}
func httpReadFile(name string, accessTokens map[string]string) (io.ReadCloser, error) {
-
u, err := url.Parse(name)
if err != nil {
return nil, fmt.Errorf("failed to read url: %w", err)
@@ -409,7 +406,6 @@ func envValues(filter []string) map[string]interface{} {
}
func (s *StepConfig) mixIn(mergeData map[string]interface{}, filter []string, metadata StepData) {
-
if s.Config == nil {
s.Config = map[string]interface{}{}
}
@@ -418,7 +414,6 @@ func (s *StepConfig) mixIn(mergeData map[string]interface{}, filter []string, me
}
func (s *StepConfig) mixInHookConfig(mergeData map[string]interface{}, metadata StepData) {
-
if s.HookConfig == nil {
s.HookConfig = map[string]interface{}{}
}
@@ -487,7 +482,6 @@ func filterMap(data map[string]interface{}, filter []string) map[string]interfac
}
func merge(base, overlay map[string]interface{}, metadata StepData) map[string]interface{} {
-
result := map[string]interface{}{}
if base == nil {
From 683ca350010f6eb5617497773974ba76e20e9cfb Mon Sep 17 00:00:00 2001
From: thtri
Date: Mon, 3 Jun 2024 10:01:50 +0200
Subject: [PATCH 12/16] CxOne: Add param to tag scan and project (#4944)
* Initial in progress
* compiling but not yet functional
* Missed file
* updated checkmarxone step
* Working up to fetching a project then breaks
* Missed file
* Breaks when retrieving projects+proxy set
* Create project & run scan working, now polling
* Fixed polling
* added back the zipfile remove command
* Fixed polling again
* Generates and downloads PDF report
* Updated and working, prep for refactor
* Added compliance steps
* Cleanup, reporting, added groovy connector
* fixed groovy file
* checkmarxone to checkmarxOne
* checkmarxone to checkmarxOne
* split credentials (id+secret, apikey), renamed pullrequestname to branch, groovy fix
* Fixed filenames & yaml
* missed the metadata_generated.go
* added json to sarif conversion
* fix:type in new checkmarxone package
* fix:type in new checkmarxone package
* removed test logs, added temp error log for creds
* extra debugging to fix crash
* improved auth logging, fixed query parse issue
* fixed bug with group fetch when using oauth user
* CWE can be -1 if not defined, can't be uint
* Query also had CweID
* Disabled predicates-fetch in sarif generation
* Removing leftover info log message
* Better error handling
* fixed default preset configuration
* removing .bat files - sorry
* Cleanup per initial review
* refactoring per Gist, fixed project find, add apps
* small fix - sorry for commit noise while testing
* Fixing issues with incremental scans.
* removing maxretries
* Updated per PR feedback, further changes todo toda
* JSON Report changes and reporting cleanup
* removing .bat (again?)
* adding docs, groovy unit test, linter fixes
* Started adding tests maybe 15% covered
* fix(checkmarxOne): test cases for pkg and reporting
* fix(checkmarxOne):fix formatting
* feat(checkmarxone): update interface with missing method
* feat(checkmarxone):change runStep signature to be able to inject dependency
* feat(checkmarxone): add tests for step (wip)
* Adding a bit more coverage
* feat(checkmarxOne): fix code review
* feat(checkmarxOne): fix code review
* feat(checkmarxOne): fix code review
* feat(checkmarxOne): fix integration test PR
* adding scan-summary bug workaround, reportgen fail
* enforceThresholds fix when no results passed in
* fixed gap when preset empty in yaml & project conf
* fixed another gap in preset selection
* fix 0-result panic
* fail when no preset is set anywhere
* removed comment
* initial project-under-app support
* fixing sarif reportgen
* some cleanup of error messages
* post-merge test fixes
* revert previous upstream merge
* adding "incremental" to "full" triggers
* wrong boolean
* project-in-application api change prep
* Fixing SARIF report without preset access
* fix sarif deeplink
* removing comments
* fix(cxone):formatting
* fix(cxone):formatting
* small sarif fixes
* fixed merge
* attempt at pulling git source repo branch
* fix(cxone):new endpoint for project creation
* fix(cxOne): taxa is an array
* fix(cxOne): get Git branch from commonPipelineEnvironment
* fix(cxOne): add params to tag a scan and a project
* fix(cxOne): unit test - update project
* fix(cxOne): unit test - update project tags
* fix(cxOne): improve logs
* fix(cxOne): improve logs
---------
Co-authored-by: michael kubiaczyk
Co-authored-by: michaelkubiaczyk <48311127+michaelkubiaczyk@users.noreply.github.com>
Co-authored-by: sumeet patil
---
cmd/checkmarxOneExecuteScan.go | 48 +++++++++++--
cmd/checkmarxOneExecuteScan_generated.go | 24 ++++++-
cmd/checkmarxOneExecuteScan_test.go | 69 ++++++++++++++++++-
pkg/checkmarxone/checkmarxone.go | 35 +++++++---
pkg/checkmarxone/checkmarxone_test.go | 46 +++++++++++++
.../metadata/checkmarxOneExecuteScan.yaml | 18 ++++-
6 files changed, 222 insertions(+), 18 deletions(-)
diff --git a/cmd/checkmarxOneExecuteScan.go b/cmd/checkmarxOneExecuteScan.go
index 24731bc674..d809304290 100644
--- a/cmd/checkmarxOneExecuteScan.go
+++ b/cmd/checkmarxOneExecuteScan.go
@@ -3,8 +3,10 @@ package cmd
import (
"archive/zip"
"context"
+ "encoding/json"
"fmt"
"io"
+ "maps"
"math"
"os"
"path/filepath"
@@ -78,9 +80,11 @@ func runStep(config checkmarxOneExecuteScanOptions, influx *checkmarxOneExecuteS
return fmt.Errorf("failed to get project: %s", err)
}
- cx1sh.Group, err = cx1sh.GetGroup() // used when creating a project and when generating a SARIF report
- if err != nil {
- log.Entry().WithError(err).Warnf("failed to get group")
+ if len(config.GroupName) > 0 {
+ cx1sh.Group, err = cx1sh.GetGroup() // used when creating a project and when generating a SARIF report
+ if err != nil {
+ log.Entry().WithError(err).Warnf("failed to get group")
+ }
}
if cx1sh.Project == nil {
@@ -112,6 +116,14 @@ func runStep(config checkmarxOneExecuteScanOptions, influx *checkmarxOneExecuteS
return fmt.Errorf("failed to set preset: %s", err)
}
+ // update project's tags
+ if (len(config.ProjectTags)) > 0 {
+ err = cx1sh.UpdateProjectTags()
+ if err != nil {
+ log.Entry().WithError(err).Warnf("failed to tags the project: %s", err)
+ }
+ }
+
scans, err := cx1sh.GetLastScans(10)
if err != nil {
log.Entry().WithError(err).Warnf("failed to get last 10 scans")
@@ -298,6 +310,23 @@ func (c *checkmarxOneExecuteScanHelper) CreateProject() (*checkmarxOne.Project,
return &project, nil
}
+func (c *checkmarxOneExecuteScanHelper) UpdateProjectTags() error {
+ if len(c.config.ProjectTags) > 0 {
+ tags := make(map[string]string, 0)
+ err := json.Unmarshal([]byte(c.config.ProjectTags), &tags)
+ if err != nil {
+ log.Entry().Infof("Failed to parse the project tags: %v", c.config.ProjectTags)
+ return err
+ }
+ // merge new tags to the existing ones
+ maps.Copy(c.Project.Tags, tags)
+
+ return c.sys.UpdateProject(c.Project)
+ }
+
+ return nil
+}
+
func (c *checkmarxOneExecuteScanHelper) SetProjectPreset() error {
projectConf, err := c.sys.GetProjectConfiguration(c.Project.ProjectID)
@@ -431,9 +460,18 @@ func (c *checkmarxOneExecuteScanHelper) CreateScanRequest(incremental bool, uplo
log.Entry().Infof("Will run a scan with the following configuration: %v", sastConfigString)
configs := []checkmarxOne.ScanConfiguration{sastConfig}
- // add more engines
- scan, err := c.sys.ScanProjectZip(c.Project.ProjectID, uploadLink, branch, configs)
+ // add scan's tags
+ tags := make(map[string]string, 0)
+ if len(c.config.ScanTags) > 0 {
+ err := json.Unmarshal([]byte(c.config.ScanTags), &tags)
+ if err != nil {
+ log.Entry().WithError(err).Warnf("Failed to parse the scan tags: %v", c.config.ScanTags)
+ }
+ }
+
+ // add more engines
+ scan, err := c.sys.ScanProjectZip(c.Project.ProjectID, uploadLink, branch, configs, tags)
if err != nil {
return nil, fmt.Errorf("Failed to run scan on project %v: %s", c.Project.Name, err)
diff --git a/cmd/checkmarxOneExecuteScan_generated.go b/cmd/checkmarxOneExecuteScan_generated.go
index 06d8d653f2..6e14070dbb 100644
--- a/cmd/checkmarxOneExecuteScan_generated.go
+++ b/cmd/checkmarxOneExecuteScan_generated.go
@@ -39,6 +39,8 @@ type checkmarxOneExecuteScanOptions struct {
LanguageMode string `json:"languageMode,omitempty"`
ProjectCriticality string `json:"projectCriticality,omitempty"`
ProjectName string `json:"projectName,omitempty"`
+ ProjectTags string `json:"projectTags,omitempty"`
+ ScanTags string `json:"scanTags,omitempty"`
Branch string `json:"branch,omitempty"`
PullRequestName string `json:"pullRequestName,omitempty"`
Repository string `json:"repository,omitempty"`
@@ -364,6 +366,8 @@ func addCheckmarxOneExecuteScanFlags(cmd *cobra.Command, stepConfig *checkmarxOn
cmd.Flags().StringVar(&stepConfig.LanguageMode, "languageMode", `multi`, "Specifies whether the scan should be run for a 'single' language or 'multi' language, default 'multi'")
cmd.Flags().StringVar(&stepConfig.ProjectCriticality, "projectCriticality", `3`, "The criticality of the checkmarxOne project, used during project creation")
cmd.Flags().StringVar(&stepConfig.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "The name of the checkmarxOne project to scan into")
+ cmd.Flags().StringVar(&stepConfig.ProjectTags, "projectTags", os.Getenv("PIPER_projectTags"), "Used to tag a project with a JSON string, e.g., {\"key\":\"value\", \"keywithoutvalue\":\"\"}")
+ cmd.Flags().StringVar(&stepConfig.ScanTags, "scanTags", os.Getenv("PIPER_scanTags"), "Used to tag a scan with a JSON string, e.g., {\"key\":\"value\", \"keywithoutvalue\":\"\"}")
cmd.Flags().StringVar(&stepConfig.Branch, "branch", os.Getenv("PIPER_branch"), "Used to supply the branch scanned in the repository, or a friendly-name set by the user")
cmd.Flags().StringVar(&stepConfig.PullRequestName, "pullRequestName", os.Getenv("PIPER_pullRequestName"), "Used to supply the name for the newly created PR project branch when being used in pull request scenarios. This is supplied by the orchestrator.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
@@ -528,7 +532,7 @@ func checkmarxOneExecuteScanMetadata() config.StepData {
ResourceRef: []config.ResourceReference{
{
Name: "commonPipelineEnvironment",
- Param: "github/branch",
+ Param: "git/branch",
},
},
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
@@ -615,6 +619,24 @@ func checkmarxOneExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_projectName"),
},
+ {
+ Name: "projectTags",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: os.Getenv("PIPER_projectTags"),
+ },
+ {
+ Name: "scanTags",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: os.Getenv("PIPER_scanTags"),
+ },
{
Name: "branch",
ResourceRef: []config.ResourceReference{},
diff --git a/cmd/checkmarxOneExecuteScan_test.go b/cmd/checkmarxOneExecuteScan_test.go
index 453e8a1780..c9206dbf8d 100644
--- a/cmd/checkmarxOneExecuteScan_test.go
+++ b/cmd/checkmarxOneExecuteScan_test.go
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
+ "maps"
"testing"
"github.com/stretchr/testify/assert"
@@ -77,15 +78,15 @@ func (sys *checkmarxOneSystemMock) GetLastScansByStatus(projectID string, limit
return []checkmarxOne.Scan{}, nil
}
-func (sys *checkmarxOneSystemMock) ScanProject(projectID, sourceUrl, branch, scanType string, settings []checkmarxOne.ScanConfiguration) (checkmarxOne.Scan, error) {
+func (sys *checkmarxOneSystemMock) ScanProject(projectID, sourceUrl, branch, scanType string, settings []checkmarxOne.ScanConfiguration, tags map[string]string) (checkmarxOne.Scan, error) {
return checkmarxOne.Scan{}, nil
}
-func (sys *checkmarxOneSystemMock) ScanProjectZip(projectID, sourceUrl, branch string, settings []checkmarxOne.ScanConfiguration) (checkmarxOne.Scan, error) {
+func (sys *checkmarxOneSystemMock) ScanProjectZip(projectID, sourceUrl, branch string, settings []checkmarxOne.ScanConfiguration, tags map[string]string) (checkmarxOne.Scan, error) {
return checkmarxOne.Scan{}, nil
}
-func (sys *checkmarxOneSystemMock) ScanProjectGit(projectID, repoUrl, branch string, settings []checkmarxOne.ScanConfiguration) (checkmarxOne.Scan, error) {
+func (sys *checkmarxOneSystemMock) ScanProjectGit(projectID, repoUrl, branch string, settings []checkmarxOne.ScanConfiguration, tags map[string]string) (checkmarxOne.Scan, error) {
return checkmarxOne.Scan{}, nil
}
@@ -240,6 +241,10 @@ func (sys *checkmarxOneSystemMock) UpdateProjectConfiguration(projectID string,
return nil
}
+func (sys *checkmarxOneSystemMock) UpdateProject(project *checkmarxOne.Project) error {
+ return nil
+}
+
func (sys *checkmarxOneSystemMock) GetVersion() (checkmarxOne.VersionInfo, error) {
return checkmarxOne.VersionInfo{}, nil
}
@@ -324,3 +329,61 @@ func TestGetGroup(t *testing.T) {
assert.Equal(t, group.Name, "Group2")
})
}
+
+func TestUpdateProjectTags(t *testing.T) {
+ t.Parallel()
+
+ sys := &checkmarxOneSystemMock{}
+
+ t.Run("project tags are not provided", func(t *testing.T) {
+ t.Parallel()
+
+ options := checkmarxOneExecuteScanOptions{ProjectName: "ssba", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "2", Incremental: true, FullScansScheduled: true, Preset: "CheckmarxDefault" /*GroupName: "NotProvided",*/, VulnerabilityThresholdEnabled: true, GeneratePdfReport: true, APIKey: "testAPIKey", ServerURL: "testURL", IamURL: "testIamURL", Tenant: "testTenant"}
+
+ cx1sh := checkmarxOneExecuteScanHelper{nil, options, sys, nil, nil, nil, nil, nil, nil}
+ err := cx1sh.UpdateProjectTags()
+ assert.NoError(t, err, "Error occurred but none expected")
+ })
+
+ t.Run("project tags are provided correctly", func(t *testing.T) {
+ t.Parallel()
+
+ projectJson := `{ "id": "702ba12b-ae61-48c0-9b6a-09b17666be32",
+ "name": "test-apr24-piper",
+ "tags": {
+ "key1": "value1",
+ "key2": "value2",
+ "keywithoutvalue1": ""
+ },
+ "groups": [],
+ "criticality": 3,
+ "mainBranch": "",
+ "privatePackage": false
+ }`
+ var project checkmarxOne.Project
+ _ = json.Unmarshal([]byte(projectJson), &project)
+
+ options := checkmarxOneExecuteScanOptions{ProjectName: "ssba", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "2", Incremental: true, FullScansScheduled: true, Preset: "CheckmarxDefault" /*GroupName: "NotProvided",*/, VulnerabilityThresholdEnabled: true, GeneratePdfReport: true, APIKey: "testAPIKey", ServerURL: "testURL", IamURL: "testIamURL", Tenant: "testTenant", ProjectTags: `{"key3":"value3", "key2":"value5", "keywithoutvalue2":""}`}
+
+ cx1sh := checkmarxOneExecuteScanHelper{nil, options, sys, nil, nil, &project, nil, nil, nil}
+ err := cx1sh.UpdateProjectTags()
+ assert.NoError(t, err, "Error occurred but none expected")
+
+ oldTagsJson := `{
+ "key1": "value1",
+ "key2": "value2",
+ "keywithoutvalue1": ""
+ }`
+ oldTags := make(map[string]string, 0)
+ _ = json.Unmarshal([]byte(oldTagsJson), &oldTags)
+
+ newTagsJson := `{"key3":"value3", "key2":"value5", "keywithoutvalue2":""}`
+ newTags := make(map[string]string, 0)
+ _ = json.Unmarshal([]byte(newTagsJson), &newTags)
+
+ // merge new tags to the existing ones
+ maps.Copy(oldTags, newTags)
+
+ assert.Equal(t, project.Tags, oldTags) // project's tags must be merged
+ })
+}
diff --git a/pkg/checkmarxone/checkmarxone.go b/pkg/checkmarxone/checkmarxone.go
index 442c14f308..f28a87a3cc 100644
--- a/pkg/checkmarxone/checkmarxone.go
+++ b/pkg/checkmarxone/checkmarxone.go
@@ -309,9 +309,10 @@ type System interface {
GetLastScans(projectID string, limit int) ([]Scan, error)
GetLastScansByStatus(projectID string, limit int, status []string) ([]Scan, error)
- ScanProject(projectID, sourceUrl, branch, scanType string, settings []ScanConfiguration) (Scan, error)
- ScanProjectZip(projectID, sourceUrl, branch string, settings []ScanConfiguration) (Scan, error)
- ScanProjectGit(projectID, repoUrl, branch string, settings []ScanConfiguration) (Scan, error)
+ ScanProject(projectID, sourceUrl, branch, scanType string, settings []ScanConfiguration, tags map[string]string) (Scan, error)
+ ScanProjectZip(projectID, sourceUrl, branch string, settings []ScanConfiguration, tags map[string]string) (Scan, error)
+ ScanProjectGit(projectID, repoUrl, branch string, settings []ScanConfiguration, tags map[string]string) (Scan, error)
+ UpdateProject(project *Project) error
UploadProjectSourceCode(projectID string, zipFile string) (string, error)
CreateProject(projectName string, groupIDs []string) (Project, error)
@@ -651,6 +652,22 @@ func (sys *SystemInstance) UpdateApplication(app *Application) error {
return nil
}
+func (sys *SystemInstance) UpdateProject(project *Project) error {
+ sys.logger.Debugf("Updating project: %v", project.Name)
+ jsonBody, err := json.Marshal(*project)
+ if err != nil {
+ return err
+ }
+
+ _, err = sendRequest(sys, http.MethodPut, fmt.Sprintf("/projects/%v", project.ProjectID), bytes.NewReader(jsonBody), nil, []int{})
+ if err != nil {
+ sys.logger.Errorf("Error while updating project: %s", err)
+ return err
+ }
+
+ return nil
+}
+
// Updated for Cx1
func (sys *SystemInstance) GetGroups() ([]Group, error) {
sys.logger.Debug("Getting Groups...")
@@ -936,7 +953,7 @@ func (sys *SystemInstance) scanProject(scanConfig map[string]interface{}) (Scan,
return scan, err
}
-func (sys *SystemInstance) ScanProjectZip(projectID, sourceUrl, branch string, settings []ScanConfiguration) (Scan, error) {
+func (sys *SystemInstance) ScanProjectZip(projectID, sourceUrl, branch string, settings []ScanConfiguration, tags map[string]string) (Scan, error) {
jsonBody := map[string]interface{}{
"project": map[string]interface{}{"id": projectID},
"type": "upload",
@@ -945,6 +962,7 @@ func (sys *SystemInstance) ScanProjectZip(projectID, sourceUrl, branch string, s
"branch": branch,
},
"config": settings,
+ "tags": tags,
}
scan, err := sys.scanProject(jsonBody)
@@ -954,7 +972,7 @@ func (sys *SystemInstance) ScanProjectZip(projectID, sourceUrl, branch string, s
return scan, err
}
-func (sys *SystemInstance) ScanProjectGit(projectID, repoUrl, branch string, settings []ScanConfiguration) (Scan, error) {
+func (sys *SystemInstance) ScanProjectGit(projectID, repoUrl, branch string, settings []ScanConfiguration, tags map[string]string) (Scan, error) {
jsonBody := map[string]interface{}{
"project": map[string]interface{}{"id": projectID},
"type": "git",
@@ -963,6 +981,7 @@ func (sys *SystemInstance) ScanProjectGit(projectID, repoUrl, branch string, set
"branch": branch,
},
"config": settings,
+ "tags": tags,
}
scan, err := sys.scanProject(jsonBody)
@@ -972,11 +991,11 @@ func (sys *SystemInstance) ScanProjectGit(projectID, repoUrl, branch string, set
return scan, err
}
-func (sys *SystemInstance) ScanProject(projectID, sourceUrl, branch, scanType string, settings []ScanConfiguration) (Scan, error) {
+func (sys *SystemInstance) ScanProject(projectID, sourceUrl, branch, scanType string, settings []ScanConfiguration, tags map[string]string) (Scan, error) {
if scanType == "upload" {
- return sys.ScanProjectZip(projectID, sourceUrl, branch, settings)
+ return sys.ScanProjectZip(projectID, sourceUrl, branch, settings, tags)
} else if scanType == "git" {
- return sys.ScanProjectGit(projectID, sourceUrl, branch, settings)
+ return sys.ScanProjectGit(projectID, sourceUrl, branch, settings, tags)
}
return Scan{}, errors.New("Invalid scanType provided, must be 'upload' or 'git'")
diff --git a/pkg/checkmarxone/checkmarxone_test.go b/pkg/checkmarxone/checkmarxone_test.go
index 63b496698e..6b7ccf499c 100644
--- a/pkg/checkmarxone/checkmarxone_test.go
+++ b/pkg/checkmarxone/checkmarxone_test.go
@@ -2,6 +2,7 @@ package checkmarxOne
import (
"bytes"
+ "encoding/json"
"errors"
"fmt"
"io"
@@ -294,3 +295,48 @@ func TestGetApplicationByName(t *testing.T) {
assert.Contains(t, fmt.Sprint(err), "Provoked technical error")
})
}
+
+func TestUpdateProject(t *testing.T) {
+ logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test")
+ opts := piperHttp.ClientOptions{}
+
+ requestJson := `{ "id": "702ba12b-ae61-48c0-9b6a-09b17666be32",
+ "name": "test-apr24-piper",
+ "tags": {
+ "\"key1\"": "\"value1\"",
+ "\"keywithoutvalue\"": "\"\""
+ },
+ "groups": [],
+ "criticality": 3,
+ "mainBranch": "",
+ "privatePackage": false
+ }`
+ var project Project
+ _ = json.Unmarshal([]byte(requestJson), &project)
+
+ t.Run("test success", func(t *testing.T) {
+ myTestClient := senderMock{responseBody: ``, httpStatusCode: 204}
+ serverURL := "https://cx1.server.com"
+ sys := SystemInstance{serverURL: serverURL, iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger}
+ myTestClient.SetOptions(opts)
+
+ err := sys.UpdateProject(&project)
+ assert.NoError(t, err, "Error occurred but none expected")
+ assert.Equal(t, serverURL+"/api/projects/"+project.ProjectID, myTestClient.urlCalled, "Called url incorrect")
+ assert.Equal(t, "PUT", myTestClient.httpMethod, "HTTP method incorrect")
+ var body Project
+ _ = json.Unmarshal([]byte(myTestClient.requestBody), &body)
+ assert.Equal(t, project, body, "Request body incorrect")
+
+ })
+
+ t.Run("test technical error", func(t *testing.T) {
+ myTestClient := senderMock{httpStatusCode: 403}
+ sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger}
+ myTestClient.SetOptions(opts)
+ myTestClient.errorExp = true
+
+ err := sys.UpdateProject(&project)
+ assert.Contains(t, fmt.Sprint(err), "Provoked technical error")
+ })
+}
diff --git a/resources/metadata/checkmarxOneExecuteScan.yaml b/resources/metadata/checkmarxOneExecuteScan.yaml
index 0807f7ff2e..ff89ea18b3 100644
--- a/resources/metadata/checkmarxOneExecuteScan.yaml
+++ b/resources/metadata/checkmarxOneExecuteScan.yaml
@@ -131,7 +131,7 @@ spec:
description: "Set the GitHub repository branch."
resourceRef:
- name: commonPipelineEnvironment
- param: github/branch
+ param: git/branch
scope:
- GENERAL
- PARAMETERS
@@ -202,6 +202,22 @@ spec:
- PARAMETERS
- STAGES
- STEPS
+ - name: projectTags
+ type: string
+ description: Used to tag a project with a JSON string, e.g., {"key":"value", "keywithoutvalue":""}
+ mandatory: false
+ scope:
+ - PARAMETERS
+ - STAGES
+ - STEPS
+ - name: scanTags
+ type: string
+ description: Used to tag a scan with a JSON string, e.g., {"key":"value", "keywithoutvalue":""}
+ mandatory: false
+ scope:
+ - PARAMETERS
+ - STAGES
+ - STEPS
- name: branch
type: string
description: Used to supply the branch scanned in the repository, or a friendly-name set by the user
From 0ca2f72699f112ba6889133d123475c7ef6637e8 Mon Sep 17 00:00:00 2001
From: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
Date: Tue, 4 Jun 2024 13:40:35 +0200
Subject: [PATCH 13/16] chore(mockery): add mockery configuration (#4941)
* update mockery config
* update mockery config
* rename mockery config
* update existing mocks
* update mockery config
* update mockery config
* move cmd mocks to cmd pkg
* add hadolint mocks to config
* use moved files
* remove comment
---
.mockery.yaml => .mockery.yml | 27 ++-
cmd/githubPublishRelease.go | 1 -
cmd/hadolintExecute.go | 2 -
cmd/hadolintExecute_test.go | 2 +-
cmd/mocks/GithubRepoClient.go | 234 +++++++++++++++++-
cmd/mocks/hadolintClient.go | 119 +++++++++
cmd/mocks/hadolintPiperFileUtils.go | 188 +++++++++++++++
pkg/config/mocks/vaultClient.go | 2 +-
pkg/hadolint/mocks/hadolintClient.go | 34 ---
pkg/hadolint/mocks/hadolintPiperFileUtils.go | 62 -----
pkg/influx/mocks/Client.go | 2 +-
pkg/influx/mocks/WriteAPIBlocking.go | 2 +-
pkg/jenkins/artifact.go | 1 -
pkg/jenkins/build.go | 1 -
pkg/jenkins/credential.go | 1 -
pkg/jenkins/jenkins.go | 1 -
pkg/jenkins/job.go | 1 -
pkg/jenkins/mocks/Artifact.go | 168 ++++++++++++-
pkg/jenkins/mocks/Build.go | 132 +++++++++-
pkg/jenkins/mocks/CredentialsManager.go | 59 ++++-
pkg/jenkins/mocks/Jenkins.go | 135 ++++++++++-
pkg/jenkins/mocks/Job.go | 130 +++++++++-
pkg/jenkins/mocks/Task.go | 166 ++++++++++++-
pkg/jenkins/task.go | 1 -
pkg/kubernetes/mocks/HelmExecutor.go | 239 ++++++++++++++++++-
25 files changed, 1562 insertions(+), 148 deletions(-)
rename .mockery.yaml => .mockery.yml (51%)
create mode 100644 cmd/mocks/hadolintClient.go
create mode 100644 cmd/mocks/hadolintPiperFileUtils.go
delete mode 100644 pkg/hadolint/mocks/hadolintClient.go
delete mode 100644 pkg/hadolint/mocks/hadolintPiperFileUtils.go
diff --git a/.mockery.yaml b/.mockery.yml
similarity index 51%
rename from .mockery.yaml
rename to .mockery.yml
index aa8812cd9b..2f61192c52 100644
--- a/.mockery.yaml
+++ b/.mockery.yml
@@ -1,8 +1,28 @@
-quiet: false
mockname: "{{.InterfaceName}}"
filename: "{{.InterfaceName}}.go"
+dir: "{{.InterfaceDir}}/mocks"
outpkg: mocks
+quiet: false
packages:
+ github.com/SAP/jenkins-library/cmd:
+ interfaces:
+ GithubRepoClient:
+ HadolintPiperFileUtils:
+ HadolintClient:
+ github.com/SAP/jenkins-library/pkg/config:
+ interfaces:
+ VaultClient:
+ github.com/SAP/jenkins-library/pkg/jenkins:
+ interfaces:
+ Artifact:
+ Build:
+ CredentialsManager:
+ Jenkins:
+ Job:
+ Task:
+ github.com/SAP/jenkins-library/pkg/kubernetes:
+ interfaces:
+ HelmExecutor:
github.com/influxdata/influxdb-client-go/v2:
config:
dir: pkg/influx/mocks
@@ -13,8 +33,3 @@ packages:
dir: pkg/influx/mocks
interfaces:
WriteAPIBlocking:
- github.com/SAP/jenkins-library/pkg/config:
- config:
- dir: pkg/config/mocks
- interfaces:
- VaultClient:
diff --git a/cmd/githubPublishRelease.go b/cmd/githubPublishRelease.go
index 8f14adc03d..2267b841cb 100644
--- a/cmd/githubPublishRelease.go
+++ b/cmd/githubPublishRelease.go
@@ -16,7 +16,6 @@ import (
piperGithub "github.com/SAP/jenkins-library/pkg/github"
)
-// mock generated with: mockery --name GithubRepoClient --dir cmd --output cmd/mocks
type GithubRepoClient interface {
CreateRelease(ctx context.Context, owner string, repo string, release *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error)
DeleteReleaseAsset(ctx context.Context, owner string, repo string, id int64) (*github.Response, error)
diff --git a/cmd/hadolintExecute.go b/cmd/hadolintExecute.go
index 6eb66bcdee..fcfcf4f3a0 100644
--- a/cmd/hadolintExecute.go
+++ b/cmd/hadolintExecute.go
@@ -18,7 +18,6 @@ import (
const hadolintCommand = "hadolint"
// HadolintPiperFileUtils abstracts piperutils.Files
-// mock generated with: mockery --name HadolintPiperFileUtils --dir cmd --output pkg/hadolint/mocks
type HadolintPiperFileUtils interface {
FileExists(filename string) (bool, error)
FileWrite(filename string, data []byte, perm os.FileMode) error
@@ -26,7 +25,6 @@ type HadolintPiperFileUtils interface {
}
// HadolintClient abstracts http.Client
-// mock generated with: mockery --name hadolintClient --dir cmd --output pkg/hadolint/mocks
type HadolintClient interface {
SetOptions(options piperhttp.ClientOptions)
DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error
diff --git a/cmd/hadolintExecute_test.go b/cmd/hadolintExecute_test.go
index f1c1c0921d..11422c157d 100644
--- a/cmd/hadolintExecute_test.go
+++ b/cmd/hadolintExecute_test.go
@@ -6,7 +6,7 @@ package cmd
import (
"testing"
- "github.com/SAP/jenkins-library/pkg/hadolint/mocks"
+ "github.com/SAP/jenkins-library/cmd/mocks"
piperMocks "github.com/SAP/jenkins-library/pkg/mock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
diff --git a/cmd/mocks/GithubRepoClient.go b/cmd/mocks/GithubRepoClient.go
index 625ed61c9f..3c8394915a 100644
--- a/cmd/mocks/GithubRepoClient.go
+++ b/cmd/mocks/GithubRepoClient.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.10.4. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -16,11 +16,28 @@ type GithubRepoClient struct {
mock.Mock
}
+type GithubRepoClient_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *GithubRepoClient) EXPECT() *GithubRepoClient_Expecter {
+ return &GithubRepoClient_Expecter{mock: &_m.Mock}
+}
+
// CreateRelease provides a mock function with given fields: ctx, owner, repo, release
func (_m *GithubRepoClient) CreateRelease(ctx context.Context, owner string, repo string, release *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error) {
ret := _m.Called(ctx, owner, repo, release)
+ if len(ret) == 0 {
+ panic("no return value specified for CreateRelease")
+ }
+
var r0 *github.RepositoryRelease
+ var r1 *github.Response
+ var r2 error
+ if rf, ok := ret.Get(0).(func(context.Context, string, string, *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error)); ok {
+ return rf(ctx, owner, repo, release)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string, string, *github.RepositoryRelease) *github.RepositoryRelease); ok {
r0 = rf(ctx, owner, repo, release)
} else {
@@ -29,7 +46,6 @@ func (_m *GithubRepoClient) CreateRelease(ctx context.Context, owner string, rep
}
}
- var r1 *github.Response
if rf, ok := ret.Get(1).(func(context.Context, string, string, *github.RepositoryRelease) *github.Response); ok {
r1 = rf(ctx, owner, repo, release)
} else {
@@ -38,7 +54,6 @@ func (_m *GithubRepoClient) CreateRelease(ctx context.Context, owner string, rep
}
}
- var r2 error
if rf, ok := ret.Get(2).(func(context.Context, string, string, *github.RepositoryRelease) error); ok {
r2 = rf(ctx, owner, repo, release)
} else {
@@ -48,11 +63,50 @@ func (_m *GithubRepoClient) CreateRelease(ctx context.Context, owner string, rep
return r0, r1, r2
}
+// GithubRepoClient_CreateRelease_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRelease'
+type GithubRepoClient_CreateRelease_Call struct {
+ *mock.Call
+}
+
+// CreateRelease is a helper method to define mock.On call
+// - ctx context.Context
+// - owner string
+// - repo string
+// - release *github.RepositoryRelease
+func (_e *GithubRepoClient_Expecter) CreateRelease(ctx interface{}, owner interface{}, repo interface{}, release interface{}) *GithubRepoClient_CreateRelease_Call {
+ return &GithubRepoClient_CreateRelease_Call{Call: _e.mock.On("CreateRelease", ctx, owner, repo, release)}
+}
+
+func (_c *GithubRepoClient_CreateRelease_Call) Run(run func(ctx context.Context, owner string, repo string, release *github.RepositoryRelease)) *GithubRepoClient_CreateRelease_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(*github.RepositoryRelease))
+ })
+ return _c
+}
+
+func (_c *GithubRepoClient_CreateRelease_Call) Return(_a0 *github.RepositoryRelease, _a1 *github.Response, _a2 error) *GithubRepoClient_CreateRelease_Call {
+ _c.Call.Return(_a0, _a1, _a2)
+ return _c
+}
+
+func (_c *GithubRepoClient_CreateRelease_Call) RunAndReturn(run func(context.Context, string, string, *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error)) *GithubRepoClient_CreateRelease_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// DeleteReleaseAsset provides a mock function with given fields: ctx, owner, repo, id
func (_m *GithubRepoClient) DeleteReleaseAsset(ctx context.Context, owner string, repo string, id int64) (*github.Response, error) {
ret := _m.Called(ctx, owner, repo, id)
+ if len(ret) == 0 {
+ panic("no return value specified for DeleteReleaseAsset")
+ }
+
var r0 *github.Response
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, string, string, int64) (*github.Response, error)); ok {
+ return rf(ctx, owner, repo, id)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string, string, int64) *github.Response); ok {
r0 = rf(ctx, owner, repo, id)
} else {
@@ -61,7 +115,6 @@ func (_m *GithubRepoClient) DeleteReleaseAsset(ctx context.Context, owner string
}
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string, string, int64) error); ok {
r1 = rf(ctx, owner, repo, id)
} else {
@@ -71,11 +124,51 @@ func (_m *GithubRepoClient) DeleteReleaseAsset(ctx context.Context, owner string
return r0, r1
}
+// GithubRepoClient_DeleteReleaseAsset_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteReleaseAsset'
+type GithubRepoClient_DeleteReleaseAsset_Call struct {
+ *mock.Call
+}
+
+// DeleteReleaseAsset is a helper method to define mock.On call
+// - ctx context.Context
+// - owner string
+// - repo string
+// - id int64
+func (_e *GithubRepoClient_Expecter) DeleteReleaseAsset(ctx interface{}, owner interface{}, repo interface{}, id interface{}) *GithubRepoClient_DeleteReleaseAsset_Call {
+ return &GithubRepoClient_DeleteReleaseAsset_Call{Call: _e.mock.On("DeleteReleaseAsset", ctx, owner, repo, id)}
+}
+
+func (_c *GithubRepoClient_DeleteReleaseAsset_Call) Run(run func(ctx context.Context, owner string, repo string, id int64)) *GithubRepoClient_DeleteReleaseAsset_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(int64))
+ })
+ return _c
+}
+
+func (_c *GithubRepoClient_DeleteReleaseAsset_Call) Return(_a0 *github.Response, _a1 error) *GithubRepoClient_DeleteReleaseAsset_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *GithubRepoClient_DeleteReleaseAsset_Call) RunAndReturn(run func(context.Context, string, string, int64) (*github.Response, error)) *GithubRepoClient_DeleteReleaseAsset_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// GetLatestRelease provides a mock function with given fields: ctx, owner, repo
func (_m *GithubRepoClient) GetLatestRelease(ctx context.Context, owner string, repo string) (*github.RepositoryRelease, *github.Response, error) {
ret := _m.Called(ctx, owner, repo)
+ if len(ret) == 0 {
+ panic("no return value specified for GetLatestRelease")
+ }
+
var r0 *github.RepositoryRelease
+ var r1 *github.Response
+ var r2 error
+ if rf, ok := ret.Get(0).(func(context.Context, string, string) (*github.RepositoryRelease, *github.Response, error)); ok {
+ return rf(ctx, owner, repo)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string, string) *github.RepositoryRelease); ok {
r0 = rf(ctx, owner, repo)
} else {
@@ -84,7 +177,6 @@ func (_m *GithubRepoClient) GetLatestRelease(ctx context.Context, owner string,
}
}
- var r1 *github.Response
if rf, ok := ret.Get(1).(func(context.Context, string, string) *github.Response); ok {
r1 = rf(ctx, owner, repo)
} else {
@@ -93,7 +185,6 @@ func (_m *GithubRepoClient) GetLatestRelease(ctx context.Context, owner string,
}
}
- var r2 error
if rf, ok := ret.Get(2).(func(context.Context, string, string) error); ok {
r2 = rf(ctx, owner, repo)
} else {
@@ -103,11 +194,50 @@ func (_m *GithubRepoClient) GetLatestRelease(ctx context.Context, owner string,
return r0, r1, r2
}
+// GithubRepoClient_GetLatestRelease_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestRelease'
+type GithubRepoClient_GetLatestRelease_Call struct {
+ *mock.Call
+}
+
+// GetLatestRelease is a helper method to define mock.On call
+// - ctx context.Context
+// - owner string
+// - repo string
+func (_e *GithubRepoClient_Expecter) GetLatestRelease(ctx interface{}, owner interface{}, repo interface{}) *GithubRepoClient_GetLatestRelease_Call {
+ return &GithubRepoClient_GetLatestRelease_Call{Call: _e.mock.On("GetLatestRelease", ctx, owner, repo)}
+}
+
+func (_c *GithubRepoClient_GetLatestRelease_Call) Run(run func(ctx context.Context, owner string, repo string)) *GithubRepoClient_GetLatestRelease_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(string))
+ })
+ return _c
+}
+
+func (_c *GithubRepoClient_GetLatestRelease_Call) Return(_a0 *github.RepositoryRelease, _a1 *github.Response, _a2 error) *GithubRepoClient_GetLatestRelease_Call {
+ _c.Call.Return(_a0, _a1, _a2)
+ return _c
+}
+
+func (_c *GithubRepoClient_GetLatestRelease_Call) RunAndReturn(run func(context.Context, string, string) (*github.RepositoryRelease, *github.Response, error)) *GithubRepoClient_GetLatestRelease_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// ListReleaseAssets provides a mock function with given fields: ctx, owner, repo, id, opt
func (_m *GithubRepoClient) ListReleaseAssets(ctx context.Context, owner string, repo string, id int64, opt *github.ListOptions) ([]*github.ReleaseAsset, *github.Response, error) {
ret := _m.Called(ctx, owner, repo, id, opt)
+ if len(ret) == 0 {
+ panic("no return value specified for ListReleaseAssets")
+ }
+
var r0 []*github.ReleaseAsset
+ var r1 *github.Response
+ var r2 error
+ if rf, ok := ret.Get(0).(func(context.Context, string, string, int64, *github.ListOptions) ([]*github.ReleaseAsset, *github.Response, error)); ok {
+ return rf(ctx, owner, repo, id, opt)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string, string, int64, *github.ListOptions) []*github.ReleaseAsset); ok {
r0 = rf(ctx, owner, repo, id, opt)
} else {
@@ -116,7 +246,6 @@ func (_m *GithubRepoClient) ListReleaseAssets(ctx context.Context, owner string,
}
}
- var r1 *github.Response
if rf, ok := ret.Get(1).(func(context.Context, string, string, int64, *github.ListOptions) *github.Response); ok {
r1 = rf(ctx, owner, repo, id, opt)
} else {
@@ -125,7 +254,6 @@ func (_m *GithubRepoClient) ListReleaseAssets(ctx context.Context, owner string,
}
}
- var r2 error
if rf, ok := ret.Get(2).(func(context.Context, string, string, int64, *github.ListOptions) error); ok {
r2 = rf(ctx, owner, repo, id, opt)
} else {
@@ -135,11 +263,52 @@ func (_m *GithubRepoClient) ListReleaseAssets(ctx context.Context, owner string,
return r0, r1, r2
}
+// GithubRepoClient_ListReleaseAssets_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListReleaseAssets'
+type GithubRepoClient_ListReleaseAssets_Call struct {
+ *mock.Call
+}
+
+// ListReleaseAssets is a helper method to define mock.On call
+// - ctx context.Context
+// - owner string
+// - repo string
+// - id int64
+// - opt *github.ListOptions
+func (_e *GithubRepoClient_Expecter) ListReleaseAssets(ctx interface{}, owner interface{}, repo interface{}, id interface{}, opt interface{}) *GithubRepoClient_ListReleaseAssets_Call {
+ return &GithubRepoClient_ListReleaseAssets_Call{Call: _e.mock.On("ListReleaseAssets", ctx, owner, repo, id, opt)}
+}
+
+func (_c *GithubRepoClient_ListReleaseAssets_Call) Run(run func(ctx context.Context, owner string, repo string, id int64, opt *github.ListOptions)) *GithubRepoClient_ListReleaseAssets_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(int64), args[4].(*github.ListOptions))
+ })
+ return _c
+}
+
+func (_c *GithubRepoClient_ListReleaseAssets_Call) Return(_a0 []*github.ReleaseAsset, _a1 *github.Response, _a2 error) *GithubRepoClient_ListReleaseAssets_Call {
+ _c.Call.Return(_a0, _a1, _a2)
+ return _c
+}
+
+func (_c *GithubRepoClient_ListReleaseAssets_Call) RunAndReturn(run func(context.Context, string, string, int64, *github.ListOptions) ([]*github.ReleaseAsset, *github.Response, error)) *GithubRepoClient_ListReleaseAssets_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// UploadReleaseAsset provides a mock function with given fields: ctx, owner, repo, id, opt, file
func (_m *GithubRepoClient) UploadReleaseAsset(ctx context.Context, owner string, repo string, id int64, opt *github.UploadOptions, file *os.File) (*github.ReleaseAsset, *github.Response, error) {
ret := _m.Called(ctx, owner, repo, id, opt, file)
+ if len(ret) == 0 {
+ panic("no return value specified for UploadReleaseAsset")
+ }
+
var r0 *github.ReleaseAsset
+ var r1 *github.Response
+ var r2 error
+ if rf, ok := ret.Get(0).(func(context.Context, string, string, int64, *github.UploadOptions, *os.File) (*github.ReleaseAsset, *github.Response, error)); ok {
+ return rf(ctx, owner, repo, id, opt, file)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string, string, int64, *github.UploadOptions, *os.File) *github.ReleaseAsset); ok {
r0 = rf(ctx, owner, repo, id, opt, file)
} else {
@@ -148,7 +317,6 @@ func (_m *GithubRepoClient) UploadReleaseAsset(ctx context.Context, owner string
}
}
- var r1 *github.Response
if rf, ok := ret.Get(1).(func(context.Context, string, string, int64, *github.UploadOptions, *os.File) *github.Response); ok {
r1 = rf(ctx, owner, repo, id, opt, file)
} else {
@@ -157,7 +325,6 @@ func (_m *GithubRepoClient) UploadReleaseAsset(ctx context.Context, owner string
}
}
- var r2 error
if rf, ok := ret.Get(2).(func(context.Context, string, string, int64, *github.UploadOptions, *os.File) error); ok {
r2 = rf(ctx, owner, repo, id, opt, file)
} else {
@@ -166,3 +333,50 @@ func (_m *GithubRepoClient) UploadReleaseAsset(ctx context.Context, owner string
return r0, r1, r2
}
+
+// GithubRepoClient_UploadReleaseAsset_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UploadReleaseAsset'
+type GithubRepoClient_UploadReleaseAsset_Call struct {
+ *mock.Call
+}
+
+// UploadReleaseAsset is a helper method to define mock.On call
+// - ctx context.Context
+// - owner string
+// - repo string
+// - id int64
+// - opt *github.UploadOptions
+// - file *os.File
+func (_e *GithubRepoClient_Expecter) UploadReleaseAsset(ctx interface{}, owner interface{}, repo interface{}, id interface{}, opt interface{}, file interface{}) *GithubRepoClient_UploadReleaseAsset_Call {
+ return &GithubRepoClient_UploadReleaseAsset_Call{Call: _e.mock.On("UploadReleaseAsset", ctx, owner, repo, id, opt, file)}
+}
+
+func (_c *GithubRepoClient_UploadReleaseAsset_Call) Run(run func(ctx context.Context, owner string, repo string, id int64, opt *github.UploadOptions, file *os.File)) *GithubRepoClient_UploadReleaseAsset_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(int64), args[4].(*github.UploadOptions), args[5].(*os.File))
+ })
+ return _c
+}
+
+func (_c *GithubRepoClient_UploadReleaseAsset_Call) Return(_a0 *github.ReleaseAsset, _a1 *github.Response, _a2 error) *GithubRepoClient_UploadReleaseAsset_Call {
+ _c.Call.Return(_a0, _a1, _a2)
+ return _c
+}
+
+func (_c *GithubRepoClient_UploadReleaseAsset_Call) RunAndReturn(run func(context.Context, string, string, int64, *github.UploadOptions, *os.File) (*github.ReleaseAsset, *github.Response, error)) *GithubRepoClient_UploadReleaseAsset_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewGithubRepoClient creates a new instance of GithubRepoClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewGithubRepoClient(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *GithubRepoClient {
+ mock := &GithubRepoClient{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/cmd/mocks/hadolintClient.go b/cmd/mocks/hadolintClient.go
new file mode 100644
index 0000000000..4c8eb7131b
--- /dev/null
+++ b/cmd/mocks/hadolintClient.go
@@ -0,0 +1,119 @@
+// Code generated by mockery v2.43.0. DO NOT EDIT.
+
+package mocks
+
+import (
+ http "net/http"
+
+ pkghttp "github.com/SAP/jenkins-library/pkg/http"
+ mock "github.com/stretchr/testify/mock"
+)
+
+// HadolintClient is an autogenerated mock type for the HadolintClient type
+type HadolintClient struct {
+ mock.Mock
+}
+
+type HadolintClient_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *HadolintClient) EXPECT() *HadolintClient_Expecter {
+ return &HadolintClient_Expecter{mock: &_m.Mock}
+}
+
+// DownloadFile provides a mock function with given fields: url, filename, header, cookies
+func (_m *HadolintClient) DownloadFile(url string, filename string, header http.Header, cookies []*http.Cookie) error {
+ ret := _m.Called(url, filename, header, cookies)
+
+ if len(ret) == 0 {
+ panic("no return value specified for DownloadFile")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(string, string, http.Header, []*http.Cookie) error); ok {
+ r0 = rf(url, filename, header, cookies)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// HadolintClient_DownloadFile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DownloadFile'
+type HadolintClient_DownloadFile_Call struct {
+ *mock.Call
+}
+
+// DownloadFile is a helper method to define mock.On call
+// - url string
+// - filename string
+// - header http.Header
+// - cookies []*http.Cookie
+func (_e *HadolintClient_Expecter) DownloadFile(url interface{}, filename interface{}, header interface{}, cookies interface{}) *HadolintClient_DownloadFile_Call {
+ return &HadolintClient_DownloadFile_Call{Call: _e.mock.On("DownloadFile", url, filename, header, cookies)}
+}
+
+func (_c *HadolintClient_DownloadFile_Call) Run(run func(url string, filename string, header http.Header, cookies []*http.Cookie)) *HadolintClient_DownloadFile_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(string), args[1].(string), args[2].(http.Header), args[3].([]*http.Cookie))
+ })
+ return _c
+}
+
+func (_c *HadolintClient_DownloadFile_Call) Return(_a0 error) *HadolintClient_DownloadFile_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HadolintClient_DownloadFile_Call) RunAndReturn(run func(string, string, http.Header, []*http.Cookie) error) *HadolintClient_DownloadFile_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// SetOptions provides a mock function with given fields: options
+func (_m *HadolintClient) SetOptions(options pkghttp.ClientOptions) {
+ _m.Called(options)
+}
+
+// HadolintClient_SetOptions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOptions'
+type HadolintClient_SetOptions_Call struct {
+ *mock.Call
+}
+
+// SetOptions is a helper method to define mock.On call
+// - options pkghttp.ClientOptions
+func (_e *HadolintClient_Expecter) SetOptions(options interface{}) *HadolintClient_SetOptions_Call {
+ return &HadolintClient_SetOptions_Call{Call: _e.mock.On("SetOptions", options)}
+}
+
+func (_c *HadolintClient_SetOptions_Call) Run(run func(options pkghttp.ClientOptions)) *HadolintClient_SetOptions_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(pkghttp.ClientOptions))
+ })
+ return _c
+}
+
+func (_c *HadolintClient_SetOptions_Call) Return() *HadolintClient_SetOptions_Call {
+ _c.Call.Return()
+ return _c
+}
+
+func (_c *HadolintClient_SetOptions_Call) RunAndReturn(run func(pkghttp.ClientOptions)) *HadolintClient_SetOptions_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewHadolintClient creates a new instance of HadolintClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewHadolintClient(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *HadolintClient {
+ mock := &HadolintClient{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/cmd/mocks/hadolintPiperFileUtils.go b/cmd/mocks/hadolintPiperFileUtils.go
new file mode 100644
index 0000000000..5ef9b46edb
--- /dev/null
+++ b/cmd/mocks/hadolintPiperFileUtils.go
@@ -0,0 +1,188 @@
+// Code generated by mockery v2.43.0. DO NOT EDIT.
+
+package mocks
+
+import (
+ fs "io/fs"
+
+ mock "github.com/stretchr/testify/mock"
+)
+
+// HadolintPiperFileUtils is an autogenerated mock type for the HadolintPiperFileUtils type
+type HadolintPiperFileUtils struct {
+ mock.Mock
+}
+
+type HadolintPiperFileUtils_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *HadolintPiperFileUtils) EXPECT() *HadolintPiperFileUtils_Expecter {
+ return &HadolintPiperFileUtils_Expecter{mock: &_m.Mock}
+}
+
+// FileExists provides a mock function with given fields: filename
+func (_m *HadolintPiperFileUtils) FileExists(filename string) (bool, error) {
+ ret := _m.Called(filename)
+
+ if len(ret) == 0 {
+ panic("no return value specified for FileExists")
+ }
+
+ var r0 bool
+ var r1 error
+ if rf, ok := ret.Get(0).(func(string) (bool, error)); ok {
+ return rf(filename)
+ }
+ if rf, ok := ret.Get(0).(func(string) bool); ok {
+ r0 = rf(filename)
+ } else {
+ r0 = ret.Get(0).(bool)
+ }
+
+ if rf, ok := ret.Get(1).(func(string) error); ok {
+ r1 = rf(filename)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// HadolintPiperFileUtils_FileExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FileExists'
+type HadolintPiperFileUtils_FileExists_Call struct {
+ *mock.Call
+}
+
+// FileExists is a helper method to define mock.On call
+// - filename string
+func (_e *HadolintPiperFileUtils_Expecter) FileExists(filename interface{}) *HadolintPiperFileUtils_FileExists_Call {
+ return &HadolintPiperFileUtils_FileExists_Call{Call: _e.mock.On("FileExists", filename)}
+}
+
+func (_c *HadolintPiperFileUtils_FileExists_Call) Run(run func(filename string)) *HadolintPiperFileUtils_FileExists_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(string))
+ })
+ return _c
+}
+
+func (_c *HadolintPiperFileUtils_FileExists_Call) Return(_a0 bool, _a1 error) *HadolintPiperFileUtils_FileExists_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *HadolintPiperFileUtils_FileExists_Call) RunAndReturn(run func(string) (bool, error)) *HadolintPiperFileUtils_FileExists_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// FileWrite provides a mock function with given fields: filename, data, perm
+func (_m *HadolintPiperFileUtils) FileWrite(filename string, data []byte, perm fs.FileMode) error {
+ ret := _m.Called(filename, data, perm)
+
+ if len(ret) == 0 {
+ panic("no return value specified for FileWrite")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(string, []byte, fs.FileMode) error); ok {
+ r0 = rf(filename, data, perm)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// HadolintPiperFileUtils_FileWrite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FileWrite'
+type HadolintPiperFileUtils_FileWrite_Call struct {
+ *mock.Call
+}
+
+// FileWrite is a helper method to define mock.On call
+// - filename string
+// - data []byte
+// - perm fs.FileMode
+func (_e *HadolintPiperFileUtils_Expecter) FileWrite(filename interface{}, data interface{}, perm interface{}) *HadolintPiperFileUtils_FileWrite_Call {
+ return &HadolintPiperFileUtils_FileWrite_Call{Call: _e.mock.On("FileWrite", filename, data, perm)}
+}
+
+func (_c *HadolintPiperFileUtils_FileWrite_Call) Run(run func(filename string, data []byte, perm fs.FileMode)) *HadolintPiperFileUtils_FileWrite_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(string), args[1].([]byte), args[2].(fs.FileMode))
+ })
+ return _c
+}
+
+func (_c *HadolintPiperFileUtils_FileWrite_Call) Return(_a0 error) *HadolintPiperFileUtils_FileWrite_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HadolintPiperFileUtils_FileWrite_Call) RunAndReturn(run func(string, []byte, fs.FileMode) error) *HadolintPiperFileUtils_FileWrite_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// WriteFile provides a mock function with given fields: filename, data, perm
+func (_m *HadolintPiperFileUtils) WriteFile(filename string, data []byte, perm fs.FileMode) error {
+ ret := _m.Called(filename, data, perm)
+
+ if len(ret) == 0 {
+ panic("no return value specified for WriteFile")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(string, []byte, fs.FileMode) error); ok {
+ r0 = rf(filename, data, perm)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// HadolintPiperFileUtils_WriteFile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFile'
+type HadolintPiperFileUtils_WriteFile_Call struct {
+ *mock.Call
+}
+
+// WriteFile is a helper method to define mock.On call
+// - filename string
+// - data []byte
+// - perm fs.FileMode
+func (_e *HadolintPiperFileUtils_Expecter) WriteFile(filename interface{}, data interface{}, perm interface{}) *HadolintPiperFileUtils_WriteFile_Call {
+ return &HadolintPiperFileUtils_WriteFile_Call{Call: _e.mock.On("WriteFile", filename, data, perm)}
+}
+
+func (_c *HadolintPiperFileUtils_WriteFile_Call) Run(run func(filename string, data []byte, perm fs.FileMode)) *HadolintPiperFileUtils_WriteFile_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(string), args[1].([]byte), args[2].(fs.FileMode))
+ })
+ return _c
+}
+
+func (_c *HadolintPiperFileUtils_WriteFile_Call) Return(_a0 error) *HadolintPiperFileUtils_WriteFile_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HadolintPiperFileUtils_WriteFile_Call) RunAndReturn(run func(string, []byte, fs.FileMode) error) *HadolintPiperFileUtils_WriteFile_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewHadolintPiperFileUtils creates a new instance of HadolintPiperFileUtils. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewHadolintPiperFileUtils(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *HadolintPiperFileUtils {
+ mock := &HadolintPiperFileUtils{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/config/mocks/vaultClient.go b/pkg/config/mocks/vaultClient.go
index 3b6b8f9adb..ad6b788578 100644
--- a/pkg/config/mocks/vaultClient.go
+++ b/pkg/config/mocks/vaultClient.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.42.3. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
diff --git a/pkg/hadolint/mocks/hadolintClient.go b/pkg/hadolint/mocks/hadolintClient.go
deleted file mode 100644
index 465d062a50..0000000000
--- a/pkg/hadolint/mocks/hadolintClient.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Code generated by mockery v2.0.0-alpha.13. DO NOT EDIT.
-
-package mocks
-
-import (
- http "net/http"
-
- pkghttp "github.com/SAP/jenkins-library/pkg/http"
- mock "github.com/stretchr/testify/mock"
-)
-
-// HadolintClient is an autogenerated mock type for the HadolintClient type
-type HadolintClient struct {
- mock.Mock
-}
-
-// DownloadFile provides a mock function with given fields: url, filename, header, cookies
-func (_m *HadolintClient) DownloadFile(url string, filename string, header http.Header, cookies []*http.Cookie) error {
- ret := _m.Called(url, filename, header, cookies)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(string, string, http.Header, []*http.Cookie) error); ok {
- r0 = rf(url, filename, header, cookies)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// SetOptions provides a mock function with given fields: options
-func (_m *HadolintClient) SetOptions(options pkghttp.ClientOptions) {
- _m.Called(options)
-}
diff --git a/pkg/hadolint/mocks/hadolintPiperFileUtils.go b/pkg/hadolint/mocks/hadolintPiperFileUtils.go
deleted file mode 100644
index a16993e8ca..0000000000
--- a/pkg/hadolint/mocks/hadolintPiperFileUtils.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Code generated by mockery v2.0.0-alpha.13. DO NOT EDIT.
-
-package mocks
-
-import (
- os "os"
-
- mock "github.com/stretchr/testify/mock"
-)
-
-// HadolintPiperFileUtils is an autogenerated mock type for the HadolintPiperFileUtils type
-type HadolintPiperFileUtils struct {
- mock.Mock
-}
-
-// FileExists provides a mock function with given fields: filename
-func (_m *HadolintPiperFileUtils) FileExists(filename string) (bool, error) {
- ret := _m.Called(filename)
-
- var r0 bool
- if rf, ok := ret.Get(0).(func(string) bool); ok {
- r0 = rf(filename)
- } else {
- r0 = ret.Get(0).(bool)
- }
-
- var r1 error
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(filename)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// FileWrite provides a mock function with given fields: filename, data, perm
-func (_m *HadolintPiperFileUtils) FileWrite(filename string, data []byte, perm os.FileMode) error {
- ret := _m.Called(filename, data, perm)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(string, []byte, os.FileMode) error); ok {
- r0 = rf(filename, data, perm)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-func (_m *HadolintPiperFileUtils) WriteFile(filename string, data []byte, perm os.FileMode) error {
- ret := _m.Called(filename, data, perm)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(string, []byte, os.FileMode) error); ok {
- r0 = rf(filename, data, perm)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
diff --git a/pkg/influx/mocks/Client.go b/pkg/influx/mocks/Client.go
index ad616fdefd..491d0f59a1 100644
--- a/pkg/influx/mocks/Client.go
+++ b/pkg/influx/mocks/Client.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
diff --git a/pkg/influx/mocks/WriteAPIBlocking.go b/pkg/influx/mocks/WriteAPIBlocking.go
index bf2549831f..4e898bef17 100644
--- a/pkg/influx/mocks/WriteAPIBlocking.go
+++ b/pkg/influx/mocks/WriteAPIBlocking.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
diff --git a/pkg/jenkins/artifact.go b/pkg/jenkins/artifact.go
index 478b1e0b0f..6097e9bdf0 100644
--- a/pkg/jenkins/artifact.go
+++ b/pkg/jenkins/artifact.go
@@ -7,7 +7,6 @@ import (
)
// Artifact is an interface to abstract gojenkins.Artifact.
-// mock generated with: mockery --name Artifact --dir pkg/jenkins --output pkg/jenkins/mocks
type Artifact interface {
Save(ctx context.Context, path string) (bool, error)
SaveToDir(ctx context.Context, dir string) (bool, error)
diff --git a/pkg/jenkins/build.go b/pkg/jenkins/build.go
index 4f693fa4a0..e1278e1ea4 100644
--- a/pkg/jenkins/build.go
+++ b/pkg/jenkins/build.go
@@ -10,7 +10,6 @@ import (
)
// Build is an interface to abstract gojenkins.Build.
-// mock generated with: mockery --name Build --dir pkg/jenkins --output pkg/jenkins/mocks
type Build interface {
GetArtifacts() []gojenkins.Artifact
IsRunning(ctx context.Context) bool
diff --git a/pkg/jenkins/credential.go b/pkg/jenkins/credential.go
index eb3f6af2ef..4495f727c4 100644
--- a/pkg/jenkins/credential.go
+++ b/pkg/jenkins/credential.go
@@ -22,7 +22,6 @@ type SSHCredentials = gojenkins.SSHCredentials
type DockerServerCredentials = gojenkins.DockerServerCredentials
// CredentialsManager is utility to control credential plugin
-// mock generated with: mockery --name CredentialsManager --dir pkg/jenkins --output pkg/jenkins/mocks
type CredentialsManager interface {
Update(context.Context, string, string, interface{}) error
}
diff --git a/pkg/jenkins/jenkins.go b/pkg/jenkins/jenkins.go
index 4cf9c92510..a654fef918 100644
--- a/pkg/jenkins/jenkins.go
+++ b/pkg/jenkins/jenkins.go
@@ -11,7 +11,6 @@ import (
)
// Jenkins is an interface to abstract gojenkins.Jenkins.
-// mock generated with: mockery --name Jenkins --dir pkg/jenkins --output pkg/jenkins/mocks
type Jenkins interface {
GetJobObj(ctx context.Context, name string) *gojenkins.Job
BuildJob(ctx context.Context, name string, params map[string]string) (int64, error)
diff --git a/pkg/jenkins/job.go b/pkg/jenkins/job.go
index 721aa9e01e..a379a63ba6 100644
--- a/pkg/jenkins/job.go
+++ b/pkg/jenkins/job.go
@@ -7,7 +7,6 @@ import (
)
// Task is an interface to abstract gojenkins.Task.
-// mock generated with: mockery --name Job --dir pkg/jenkins --output pkg/jenkins/mocks
type Job interface {
Poll(context.Context) (int, error)
InvokeSimple(ctx context.Context, params map[string]string) (int64, error)
diff --git a/pkg/jenkins/mocks/Artifact.go b/pkg/jenkins/mocks/Artifact.go
index 74598f017a..629dcc6897 100644
--- a/pkg/jenkins/mocks/Artifact.go
+++ b/pkg/jenkins/mocks/Artifact.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.5. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -13,10 +13,22 @@ type Artifact struct {
mock.Mock
}
+type Artifact_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *Artifact) EXPECT() *Artifact_Expecter {
+ return &Artifact_Expecter{mock: &_m.Mock}
+}
+
// FileName provides a mock function with given fields:
func (_m *Artifact) FileName() string {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for FileName")
+ }
+
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
@@ -27,11 +39,46 @@ func (_m *Artifact) FileName() string {
return r0
}
+// Artifact_FileName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FileName'
+type Artifact_FileName_Call struct {
+ *mock.Call
+}
+
+// FileName is a helper method to define mock.On call
+func (_e *Artifact_Expecter) FileName() *Artifact_FileName_Call {
+ return &Artifact_FileName_Call{Call: _e.mock.On("FileName")}
+}
+
+func (_c *Artifact_FileName_Call) Run(run func()) *Artifact_FileName_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Artifact_FileName_Call) Return(_a0 string) *Artifact_FileName_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Artifact_FileName_Call) RunAndReturn(run func() string) *Artifact_FileName_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// GetData provides a mock function with given fields: ctx
func (_m *Artifact) GetData(ctx context.Context) ([]byte, error) {
ret := _m.Called(ctx)
+ if len(ret) == 0 {
+ panic("no return value specified for GetData")
+ }
+
var r0 []byte
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context) ([]byte, error)); ok {
+ return rf(ctx)
+ }
if rf, ok := ret.Get(0).(func(context.Context) []byte); ok {
r0 = rf(ctx)
} else {
@@ -40,7 +87,6 @@ func (_m *Artifact) GetData(ctx context.Context) ([]byte, error) {
}
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
@@ -50,18 +96,53 @@ func (_m *Artifact) GetData(ctx context.Context) ([]byte, error) {
return r0, r1
}
+// Artifact_GetData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetData'
+type Artifact_GetData_Call struct {
+ *mock.Call
+}
+
+// GetData is a helper method to define mock.On call
+// - ctx context.Context
+func (_e *Artifact_Expecter) GetData(ctx interface{}) *Artifact_GetData_Call {
+ return &Artifact_GetData_Call{Call: _e.mock.On("GetData", ctx)}
+}
+
+func (_c *Artifact_GetData_Call) Run(run func(ctx context.Context)) *Artifact_GetData_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context))
+ })
+ return _c
+}
+
+func (_c *Artifact_GetData_Call) Return(_a0 []byte, _a1 error) *Artifact_GetData_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Artifact_GetData_Call) RunAndReturn(run func(context.Context) ([]byte, error)) *Artifact_GetData_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// Save provides a mock function with given fields: ctx, path
func (_m *Artifact) Save(ctx context.Context, path string) (bool, error) {
ret := _m.Called(ctx, path)
+ if len(ret) == 0 {
+ panic("no return value specified for Save")
+ }
+
var r0 bool
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok {
+ return rf(ctx, path)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok {
r0 = rf(ctx, path)
} else {
r0 = ret.Get(0).(bool)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
@@ -71,18 +152,54 @@ func (_m *Artifact) Save(ctx context.Context, path string) (bool, error) {
return r0, r1
}
+// Artifact_Save_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Save'
+type Artifact_Save_Call struct {
+ *mock.Call
+}
+
+// Save is a helper method to define mock.On call
+// - ctx context.Context
+// - path string
+func (_e *Artifact_Expecter) Save(ctx interface{}, path interface{}) *Artifact_Save_Call {
+ return &Artifact_Save_Call{Call: _e.mock.On("Save", ctx, path)}
+}
+
+func (_c *Artifact_Save_Call) Run(run func(ctx context.Context, path string)) *Artifact_Save_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string))
+ })
+ return _c
+}
+
+func (_c *Artifact_Save_Call) Return(_a0 bool, _a1 error) *Artifact_Save_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Artifact_Save_Call) RunAndReturn(run func(context.Context, string) (bool, error)) *Artifact_Save_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// SaveToDir provides a mock function with given fields: ctx, dir
func (_m *Artifact) SaveToDir(ctx context.Context, dir string) (bool, error) {
ret := _m.Called(ctx, dir)
+ if len(ret) == 0 {
+ panic("no return value specified for SaveToDir")
+ }
+
var r0 bool
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok {
+ return rf(ctx, dir)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok {
r0 = rf(ctx, dir)
} else {
r0 = ret.Get(0).(bool)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, dir)
} else {
@@ -91,3 +208,46 @@ func (_m *Artifact) SaveToDir(ctx context.Context, dir string) (bool, error) {
return r0, r1
}
+
+// Artifact_SaveToDir_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveToDir'
+type Artifact_SaveToDir_Call struct {
+ *mock.Call
+}
+
+// SaveToDir is a helper method to define mock.On call
+// - ctx context.Context
+// - dir string
+func (_e *Artifact_Expecter) SaveToDir(ctx interface{}, dir interface{}) *Artifact_SaveToDir_Call {
+ return &Artifact_SaveToDir_Call{Call: _e.mock.On("SaveToDir", ctx, dir)}
+}
+
+func (_c *Artifact_SaveToDir_Call) Run(run func(ctx context.Context, dir string)) *Artifact_SaveToDir_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string))
+ })
+ return _c
+}
+
+func (_c *Artifact_SaveToDir_Call) Return(_a0 bool, _a1 error) *Artifact_SaveToDir_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Artifact_SaveToDir_Call) RunAndReturn(run func(context.Context, string) (bool, error)) *Artifact_SaveToDir_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewArtifact creates a new instance of Artifact. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewArtifact(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *Artifact {
+ mock := &Artifact{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/jenkins/mocks/Build.go b/pkg/jenkins/mocks/Build.go
index 302bbeaf70..03c8731c4b 100644
--- a/pkg/jenkins/mocks/Build.go
+++ b/pkg/jenkins/mocks/Build.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.5. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -15,10 +15,22 @@ type Build struct {
mock.Mock
}
+type Build_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *Build) EXPECT() *Build_Expecter {
+ return &Build_Expecter{mock: &_m.Mock}
+}
+
// GetArtifacts provides a mock function with given fields:
func (_m *Build) GetArtifacts() []gojenkins.Artifact {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for GetArtifacts")
+ }
+
var r0 []gojenkins.Artifact
if rf, ok := ret.Get(0).(func() []gojenkins.Artifact); ok {
r0 = rf()
@@ -31,10 +43,41 @@ func (_m *Build) GetArtifacts() []gojenkins.Artifact {
return r0
}
+// Build_GetArtifacts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetArtifacts'
+type Build_GetArtifacts_Call struct {
+ *mock.Call
+}
+
+// GetArtifacts is a helper method to define mock.On call
+func (_e *Build_Expecter) GetArtifacts() *Build_GetArtifacts_Call {
+ return &Build_GetArtifacts_Call{Call: _e.mock.On("GetArtifacts")}
+}
+
+func (_c *Build_GetArtifacts_Call) Run(run func()) *Build_GetArtifacts_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Build_GetArtifacts_Call) Return(_a0 []gojenkins.Artifact) *Build_GetArtifacts_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Build_GetArtifacts_Call) RunAndReturn(run func() []gojenkins.Artifact) *Build_GetArtifacts_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// IsRunning provides a mock function with given fields: ctx
func (_m *Build) IsRunning(ctx context.Context) bool {
ret := _m.Called(ctx)
+ if len(ret) == 0 {
+ panic("no return value specified for IsRunning")
+ }
+
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context) bool); ok {
r0 = rf(ctx)
@@ -45,6 +88,34 @@ func (_m *Build) IsRunning(ctx context.Context) bool {
return r0
}
+// Build_IsRunning_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsRunning'
+type Build_IsRunning_Call struct {
+ *mock.Call
+}
+
+// IsRunning is a helper method to define mock.On call
+// - ctx context.Context
+func (_e *Build_Expecter) IsRunning(ctx interface{}) *Build_IsRunning_Call {
+ return &Build_IsRunning_Call{Call: _e.mock.On("IsRunning", ctx)}
+}
+
+func (_c *Build_IsRunning_Call) Run(run func(ctx context.Context)) *Build_IsRunning_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context))
+ })
+ return _c
+}
+
+func (_c *Build_IsRunning_Call) Return(_a0 bool) *Build_IsRunning_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Build_IsRunning_Call) RunAndReturn(run func(context.Context) bool) *Build_IsRunning_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// Poll provides a mock function with given fields: ctx, options
func (_m *Build) Poll(ctx context.Context, options ...interface{}) (int, error) {
var _ca []interface{}
@@ -52,14 +123,21 @@ func (_m *Build) Poll(ctx context.Context, options ...interface{}) (int, error)
_ca = append(_ca, options...)
ret := _m.Called(_ca...)
+ if len(ret) == 0 {
+ panic("no return value specified for Poll")
+ }
+
var r0 int
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, ...interface{}) (int, error)); ok {
+ return rf(ctx, options...)
+ }
if rf, ok := ret.Get(0).(func(context.Context, ...interface{}) int); ok {
r0 = rf(ctx, options...)
} else {
r0 = ret.Get(0).(int)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, ...interface{}) error); ok {
r1 = rf(ctx, options...)
} else {
@@ -68,3 +146,53 @@ func (_m *Build) Poll(ctx context.Context, options ...interface{}) (int, error)
return r0, r1
}
+
+// Build_Poll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Poll'
+type Build_Poll_Call struct {
+ *mock.Call
+}
+
+// Poll is a helper method to define mock.On call
+// - ctx context.Context
+// - options ...interface{}
+func (_e *Build_Expecter) Poll(ctx interface{}, options ...interface{}) *Build_Poll_Call {
+ return &Build_Poll_Call{Call: _e.mock.On("Poll",
+ append([]interface{}{ctx}, options...)...)}
+}
+
+func (_c *Build_Poll_Call) Run(run func(ctx context.Context, options ...interface{})) *Build_Poll_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ variadicArgs := make([]interface{}, len(args)-1)
+ for i, a := range args[1:] {
+ if a != nil {
+ variadicArgs[i] = a.(interface{})
+ }
+ }
+ run(args[0].(context.Context), variadicArgs...)
+ })
+ return _c
+}
+
+func (_c *Build_Poll_Call) Return(_a0 int, _a1 error) *Build_Poll_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Build_Poll_Call) RunAndReturn(run func(context.Context, ...interface{}) (int, error)) *Build_Poll_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewBuild creates a new instance of Build. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewBuild(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *Build {
+ mock := &Build{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/jenkins/mocks/CredentialsManager.go b/pkg/jenkins/mocks/CredentialsManager.go
index c1bd2b21d6..b4f4392099 100644
--- a/pkg/jenkins/mocks/CredentialsManager.go
+++ b/pkg/jenkins/mocks/CredentialsManager.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.5. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -13,10 +13,22 @@ type CredentialsManager struct {
mock.Mock
}
+type CredentialsManager_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *CredentialsManager) EXPECT() *CredentialsManager_Expecter {
+ return &CredentialsManager_Expecter{mock: &_m.Mock}
+}
+
// Update provides a mock function with given fields: _a0, _a1, _a2, _a3
func (_m *CredentialsManager) Update(_a0 context.Context, _a1 string, _a2 string, _a3 interface{}) error {
ret := _m.Called(_a0, _a1, _a2, _a3)
+ if len(ret) == 0 {
+ panic("no return value specified for Update")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, string, interface{}) error); ok {
r0 = rf(_a0, _a1, _a2, _a3)
@@ -26,3 +38,48 @@ func (_m *CredentialsManager) Update(_a0 context.Context, _a1 string, _a2 string
return r0
}
+
+// CredentialsManager_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update'
+type CredentialsManager_Update_Call struct {
+ *mock.Call
+}
+
+// Update is a helper method to define mock.On call
+// - _a0 context.Context
+// - _a1 string
+// - _a2 string
+// - _a3 interface{}
+func (_e *CredentialsManager_Expecter) Update(_a0 interface{}, _a1 interface{}, _a2 interface{}, _a3 interface{}) *CredentialsManager_Update_Call {
+ return &CredentialsManager_Update_Call{Call: _e.mock.On("Update", _a0, _a1, _a2, _a3)}
+}
+
+func (_c *CredentialsManager_Update_Call) Run(run func(_a0 context.Context, _a1 string, _a2 string, _a3 interface{})) *CredentialsManager_Update_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(interface{}))
+ })
+ return _c
+}
+
+func (_c *CredentialsManager_Update_Call) Return(_a0 error) *CredentialsManager_Update_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *CredentialsManager_Update_Call) RunAndReturn(run func(context.Context, string, string, interface{}) error) *CredentialsManager_Update_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewCredentialsManager creates a new instance of CredentialsManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewCredentialsManager(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *CredentialsManager {
+ mock := &CredentialsManager{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/jenkins/mocks/Jenkins.go b/pkg/jenkins/mocks/Jenkins.go
index 2903b97a92..8fb92f5bcc 100644
--- a/pkg/jenkins/mocks/Jenkins.go
+++ b/pkg/jenkins/mocks/Jenkins.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.5. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -15,18 +15,33 @@ type Jenkins struct {
mock.Mock
}
+type Jenkins_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *Jenkins) EXPECT() *Jenkins_Expecter {
+ return &Jenkins_Expecter{mock: &_m.Mock}
+}
+
// BuildJob provides a mock function with given fields: ctx, name, params
func (_m *Jenkins) BuildJob(ctx context.Context, name string, params map[string]string) (int64, error) {
ret := _m.Called(ctx, name, params)
+ if len(ret) == 0 {
+ panic("no return value specified for BuildJob")
+ }
+
var r0 int64
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, string, map[string]string) (int64, error)); ok {
+ return rf(ctx, name, params)
+ }
if rf, ok := ret.Get(0).(func(context.Context, string, map[string]string) int64); ok {
r0 = rf(ctx, name, params)
} else {
r0 = ret.Get(0).(int64)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string, map[string]string) error); ok {
r1 = rf(ctx, name, params)
} else {
@@ -36,11 +51,49 @@ func (_m *Jenkins) BuildJob(ctx context.Context, name string, params map[string]
return r0, r1
}
+// Jenkins_BuildJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BuildJob'
+type Jenkins_BuildJob_Call struct {
+ *mock.Call
+}
+
+// BuildJob is a helper method to define mock.On call
+// - ctx context.Context
+// - name string
+// - params map[string]string
+func (_e *Jenkins_Expecter) BuildJob(ctx interface{}, name interface{}, params interface{}) *Jenkins_BuildJob_Call {
+ return &Jenkins_BuildJob_Call{Call: _e.mock.On("BuildJob", ctx, name, params)}
+}
+
+func (_c *Jenkins_BuildJob_Call) Run(run func(ctx context.Context, name string, params map[string]string)) *Jenkins_BuildJob_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string), args[2].(map[string]string))
+ })
+ return _c
+}
+
+func (_c *Jenkins_BuildJob_Call) Return(_a0 int64, _a1 error) *Jenkins_BuildJob_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Jenkins_BuildJob_Call) RunAndReturn(run func(context.Context, string, map[string]string) (int64, error)) *Jenkins_BuildJob_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// GetBuildFromQueueID provides a mock function with given fields: ctx, job, queueid
func (_m *Jenkins) GetBuildFromQueueID(ctx context.Context, job *gojenkins.Job, queueid int64) (*gojenkins.Build, error) {
ret := _m.Called(ctx, job, queueid)
+ if len(ret) == 0 {
+ panic("no return value specified for GetBuildFromQueueID")
+ }
+
var r0 *gojenkins.Build
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *gojenkins.Job, int64) (*gojenkins.Build, error)); ok {
+ return rf(ctx, job, queueid)
+ }
if rf, ok := ret.Get(0).(func(context.Context, *gojenkins.Job, int64) *gojenkins.Build); ok {
r0 = rf(ctx, job, queueid)
} else {
@@ -49,7 +102,6 @@ func (_m *Jenkins) GetBuildFromQueueID(ctx context.Context, job *gojenkins.Job,
}
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *gojenkins.Job, int64) error); ok {
r1 = rf(ctx, job, queueid)
} else {
@@ -59,10 +111,44 @@ func (_m *Jenkins) GetBuildFromQueueID(ctx context.Context, job *gojenkins.Job,
return r0, r1
}
+// Jenkins_GetBuildFromQueueID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBuildFromQueueID'
+type Jenkins_GetBuildFromQueueID_Call struct {
+ *mock.Call
+}
+
+// GetBuildFromQueueID is a helper method to define mock.On call
+// - ctx context.Context
+// - job *gojenkins.Job
+// - queueid int64
+func (_e *Jenkins_Expecter) GetBuildFromQueueID(ctx interface{}, job interface{}, queueid interface{}) *Jenkins_GetBuildFromQueueID_Call {
+ return &Jenkins_GetBuildFromQueueID_Call{Call: _e.mock.On("GetBuildFromQueueID", ctx, job, queueid)}
+}
+
+func (_c *Jenkins_GetBuildFromQueueID_Call) Run(run func(ctx context.Context, job *gojenkins.Job, queueid int64)) *Jenkins_GetBuildFromQueueID_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(*gojenkins.Job), args[2].(int64))
+ })
+ return _c
+}
+
+func (_c *Jenkins_GetBuildFromQueueID_Call) Return(_a0 *gojenkins.Build, _a1 error) *Jenkins_GetBuildFromQueueID_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Jenkins_GetBuildFromQueueID_Call) RunAndReturn(run func(context.Context, *gojenkins.Job, int64) (*gojenkins.Build, error)) *Jenkins_GetBuildFromQueueID_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// GetJobObj provides a mock function with given fields: ctx, name
func (_m *Jenkins) GetJobObj(ctx context.Context, name string) *gojenkins.Job {
ret := _m.Called(ctx, name)
+ if len(ret) == 0 {
+ panic("no return value specified for GetJobObj")
+ }
+
var r0 *gojenkins.Job
if rf, ok := ret.Get(0).(func(context.Context, string) *gojenkins.Job); ok {
r0 = rf(ctx, name)
@@ -74,3 +160,46 @@ func (_m *Jenkins) GetJobObj(ctx context.Context, name string) *gojenkins.Job {
return r0
}
+
+// Jenkins_GetJobObj_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetJobObj'
+type Jenkins_GetJobObj_Call struct {
+ *mock.Call
+}
+
+// GetJobObj is a helper method to define mock.On call
+// - ctx context.Context
+// - name string
+func (_e *Jenkins_Expecter) GetJobObj(ctx interface{}, name interface{}) *Jenkins_GetJobObj_Call {
+ return &Jenkins_GetJobObj_Call{Call: _e.mock.On("GetJobObj", ctx, name)}
+}
+
+func (_c *Jenkins_GetJobObj_Call) Run(run func(ctx context.Context, name string)) *Jenkins_GetJobObj_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(string))
+ })
+ return _c
+}
+
+func (_c *Jenkins_GetJobObj_Call) Return(_a0 *gojenkins.Job) *Jenkins_GetJobObj_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Jenkins_GetJobObj_Call) RunAndReturn(run func(context.Context, string) *gojenkins.Job) *Jenkins_GetJobObj_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewJenkins creates a new instance of Jenkins. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewJenkins(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *Jenkins {
+ mock := &Jenkins{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/jenkins/mocks/Job.go b/pkg/jenkins/mocks/Job.go
index 729c7581c4..89cb925cd8 100644
--- a/pkg/jenkins/mocks/Job.go
+++ b/pkg/jenkins/mocks/Job.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.5. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -15,10 +15,22 @@ type Job struct {
mock.Mock
}
+type Job_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *Job) EXPECT() *Job_Expecter {
+ return &Job_Expecter{mock: &_m.Mock}
+}
+
// GetJob provides a mock function with given fields:
func (_m *Job) GetJob() *gojenkins.Job {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for GetJob")
+ }
+
var r0 *gojenkins.Job
if rf, ok := ret.Get(0).(func() *gojenkins.Job); ok {
r0 = rf()
@@ -31,18 +43,52 @@ func (_m *Job) GetJob() *gojenkins.Job {
return r0
}
+// Job_GetJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetJob'
+type Job_GetJob_Call struct {
+ *mock.Call
+}
+
+// GetJob is a helper method to define mock.On call
+func (_e *Job_Expecter) GetJob() *Job_GetJob_Call {
+ return &Job_GetJob_Call{Call: _e.mock.On("GetJob")}
+}
+
+func (_c *Job_GetJob_Call) Run(run func()) *Job_GetJob_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Job_GetJob_Call) Return(_a0 *gojenkins.Job) *Job_GetJob_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Job_GetJob_Call) RunAndReturn(run func() *gojenkins.Job) *Job_GetJob_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// InvokeSimple provides a mock function with given fields: ctx, params
func (_m *Job) InvokeSimple(ctx context.Context, params map[string]string) (int64, error) {
ret := _m.Called(ctx, params)
+ if len(ret) == 0 {
+ panic("no return value specified for InvokeSimple")
+ }
+
var r0 int64
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, map[string]string) (int64, error)); ok {
+ return rf(ctx, params)
+ }
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) int64); ok {
r0 = rf(ctx, params)
} else {
r0 = ret.Get(0).(int64)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
r1 = rf(ctx, params)
} else {
@@ -52,18 +98,54 @@ func (_m *Job) InvokeSimple(ctx context.Context, params map[string]string) (int6
return r0, r1
}
+// Job_InvokeSimple_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InvokeSimple'
+type Job_InvokeSimple_Call struct {
+ *mock.Call
+}
+
+// InvokeSimple is a helper method to define mock.On call
+// - ctx context.Context
+// - params map[string]string
+func (_e *Job_Expecter) InvokeSimple(ctx interface{}, params interface{}) *Job_InvokeSimple_Call {
+ return &Job_InvokeSimple_Call{Call: _e.mock.On("InvokeSimple", ctx, params)}
+}
+
+func (_c *Job_InvokeSimple_Call) Run(run func(ctx context.Context, params map[string]string)) *Job_InvokeSimple_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(map[string]string))
+ })
+ return _c
+}
+
+func (_c *Job_InvokeSimple_Call) Return(_a0 int64, _a1 error) *Job_InvokeSimple_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Job_InvokeSimple_Call) RunAndReturn(run func(context.Context, map[string]string) (int64, error)) *Job_InvokeSimple_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// Poll provides a mock function with given fields: _a0
func (_m *Job) Poll(_a0 context.Context) (int, error) {
ret := _m.Called(_a0)
+ if len(ret) == 0 {
+ panic("no return value specified for Poll")
+ }
+
var r0 int
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context) (int, error)); ok {
+ return rf(_a0)
+ }
if rf, ok := ret.Get(0).(func(context.Context) int); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(int)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
@@ -72,3 +154,45 @@ func (_m *Job) Poll(_a0 context.Context) (int, error) {
return r0, r1
}
+
+// Job_Poll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Poll'
+type Job_Poll_Call struct {
+ *mock.Call
+}
+
+// Poll is a helper method to define mock.On call
+// - _a0 context.Context
+func (_e *Job_Expecter) Poll(_a0 interface{}) *Job_Poll_Call {
+ return &Job_Poll_Call{Call: _e.mock.On("Poll", _a0)}
+}
+
+func (_c *Job_Poll_Call) Run(run func(_a0 context.Context)) *Job_Poll_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context))
+ })
+ return _c
+}
+
+func (_c *Job_Poll_Call) Return(_a0 int, _a1 error) *Job_Poll_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Job_Poll_Call) RunAndReturn(run func(context.Context) (int, error)) *Job_Poll_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewJob creates a new instance of Job. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewJob(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *Job {
+ mock := &Job{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/jenkins/mocks/Task.go b/pkg/jenkins/mocks/Task.go
index 9efa542e1a..fa8e01681f 100644
--- a/pkg/jenkins/mocks/Task.go
+++ b/pkg/jenkins/mocks/Task.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.5. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -15,18 +15,33 @@ type Task struct {
mock.Mock
}
+type Task_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *Task) EXPECT() *Task_Expecter {
+ return &Task_Expecter{mock: &_m.Mock}
+}
+
// BuildNumber provides a mock function with given fields:
func (_m *Task) BuildNumber() (int64, error) {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for BuildNumber")
+ }
+
var r0 int64
+ var r1 error
+ if rf, ok := ret.Get(0).(func() (int64, error)); ok {
+ return rf()
+ }
if rf, ok := ret.Get(0).(func() int64); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(int64)
}
- var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
@@ -36,10 +51,41 @@ func (_m *Task) BuildNumber() (int64, error) {
return r0, r1
}
+// Task_BuildNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BuildNumber'
+type Task_BuildNumber_Call struct {
+ *mock.Call
+}
+
+// BuildNumber is a helper method to define mock.On call
+func (_e *Task_Expecter) BuildNumber() *Task_BuildNumber_Call {
+ return &Task_BuildNumber_Call{Call: _e.mock.On("BuildNumber")}
+}
+
+func (_c *Task_BuildNumber_Call) Run(run func()) *Task_BuildNumber_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Task_BuildNumber_Call) Return(_a0 int64, _a1 error) *Task_BuildNumber_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Task_BuildNumber_Call) RunAndReturn(run func() (int64, error)) *Task_BuildNumber_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// HasStarted provides a mock function with given fields:
func (_m *Task) HasStarted() bool {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for HasStarted")
+ }
+
var r0 bool
if rf, ok := ret.Get(0).(func() bool); ok {
r0 = rf()
@@ -50,18 +96,52 @@ func (_m *Task) HasStarted() bool {
return r0
}
+// Task_HasStarted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HasStarted'
+type Task_HasStarted_Call struct {
+ *mock.Call
+}
+
+// HasStarted is a helper method to define mock.On call
+func (_e *Task_Expecter) HasStarted() *Task_HasStarted_Call {
+ return &Task_HasStarted_Call{Call: _e.mock.On("HasStarted")}
+}
+
+func (_c *Task_HasStarted_Call) Run(run func()) *Task_HasStarted_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Task_HasStarted_Call) Return(_a0 bool) *Task_HasStarted_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *Task_HasStarted_Call) RunAndReturn(run func() bool) *Task_HasStarted_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// Poll provides a mock function with given fields: _a0
func (_m *Task) Poll(_a0 context.Context) (int, error) {
ret := _m.Called(_a0)
+ if len(ret) == 0 {
+ panic("no return value specified for Poll")
+ }
+
var r0 int
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context) (int, error)); ok {
+ return rf(_a0)
+ }
if rf, ok := ret.Get(0).(func(context.Context) int); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(int)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
@@ -71,18 +151,53 @@ func (_m *Task) Poll(_a0 context.Context) (int, error) {
return r0, r1
}
+// Task_Poll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Poll'
+type Task_Poll_Call struct {
+ *mock.Call
+}
+
+// Poll is a helper method to define mock.On call
+// - _a0 context.Context
+func (_e *Task_Expecter) Poll(_a0 interface{}) *Task_Poll_Call {
+ return &Task_Poll_Call{Call: _e.mock.On("Poll", _a0)}
+}
+
+func (_c *Task_Poll_Call) Run(run func(_a0 context.Context)) *Task_Poll_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context))
+ })
+ return _c
+}
+
+func (_c *Task_Poll_Call) Return(_a0 int, _a1 error) *Task_Poll_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Task_Poll_Call) RunAndReturn(run func(context.Context) (int, error)) *Task_Poll_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// WaitToStart provides a mock function with given fields: ctx, pollInterval
func (_m *Task) WaitToStart(ctx context.Context, pollInterval time.Duration) (int64, error) {
ret := _m.Called(ctx, pollInterval)
+ if len(ret) == 0 {
+ panic("no return value specified for WaitToStart")
+ }
+
var r0 int64
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, time.Duration) (int64, error)); ok {
+ return rf(ctx, pollInterval)
+ }
if rf, ok := ret.Get(0).(func(context.Context, time.Duration) int64); ok {
r0 = rf(ctx, pollInterval)
} else {
r0 = ret.Get(0).(int64)
}
- var r1 error
if rf, ok := ret.Get(1).(func(context.Context, time.Duration) error); ok {
r1 = rf(ctx, pollInterval)
} else {
@@ -91,3 +206,46 @@ func (_m *Task) WaitToStart(ctx context.Context, pollInterval time.Duration) (in
return r0, r1
}
+
+// Task_WaitToStart_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WaitToStart'
+type Task_WaitToStart_Call struct {
+ *mock.Call
+}
+
+// WaitToStart is a helper method to define mock.On call
+// - ctx context.Context
+// - pollInterval time.Duration
+func (_e *Task_Expecter) WaitToStart(ctx interface{}, pollInterval interface{}) *Task_WaitToStart_Call {
+ return &Task_WaitToStart_Call{Call: _e.mock.On("WaitToStart", ctx, pollInterval)}
+}
+
+func (_c *Task_WaitToStart_Call) Run(run func(ctx context.Context, pollInterval time.Duration)) *Task_WaitToStart_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run(args[0].(context.Context), args[1].(time.Duration))
+ })
+ return _c
+}
+
+func (_c *Task_WaitToStart_Call) Return(_a0 int64, _a1 error) *Task_WaitToStart_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *Task_WaitToStart_Call) RunAndReturn(run func(context.Context, time.Duration) (int64, error)) *Task_WaitToStart_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// NewTask creates a new instance of Task. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewTask(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *Task {
+ mock := &Task{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/pkg/jenkins/task.go b/pkg/jenkins/task.go
index deaa5ef51e..a796e198c3 100644
--- a/pkg/jenkins/task.go
+++ b/pkg/jenkins/task.go
@@ -9,7 +9,6 @@ import (
)
// Task is an interface to abstract gojenkins.Task.
-// mock generated with: mockery --name Task --dir pkg/jenkins --output pkg/jenkins/mocks
type Task interface {
Poll(context.Context) (int, error)
BuildNumber() (int64, error)
diff --git a/pkg/kubernetes/mocks/HelmExecutor.go b/pkg/kubernetes/mocks/HelmExecutor.go
index 4232366115..38cb8de580 100644
--- a/pkg/kubernetes/mocks/HelmExecutor.go
+++ b/pkg/kubernetes/mocks/HelmExecutor.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery v2.43.0. DO NOT EDIT.
package mocks
@@ -9,10 +9,22 @@ type HelmExecutor struct {
mock.Mock
}
+type HelmExecutor_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *HelmExecutor) EXPECT() *HelmExecutor_Expecter {
+ return &HelmExecutor_Expecter{mock: &_m.Mock}
+}
+
// RunHelmDependency provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmDependency() error {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmDependency")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
@@ -23,10 +35,41 @@ func (_m *HelmExecutor) RunHelmDependency() error {
return r0
}
+// HelmExecutor_RunHelmDependency_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmDependency'
+type HelmExecutor_RunHelmDependency_Call struct {
+ *mock.Call
+}
+
+// RunHelmDependency is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmDependency() *HelmExecutor_RunHelmDependency_Call {
+ return &HelmExecutor_RunHelmDependency_Call{Call: _e.mock.On("RunHelmDependency")}
+}
+
+func (_c *HelmExecutor_RunHelmDependency_Call) Run(run func()) *HelmExecutor_RunHelmDependency_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmDependency_Call) Return(_a0 error) *HelmExecutor_RunHelmDependency_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmDependency_Call) RunAndReturn(run func() error) *HelmExecutor_RunHelmDependency_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RunHelmInstall provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmInstall() error {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmInstall")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
@@ -37,10 +80,41 @@ func (_m *HelmExecutor) RunHelmInstall() error {
return r0
}
+// HelmExecutor_RunHelmInstall_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmInstall'
+type HelmExecutor_RunHelmInstall_Call struct {
+ *mock.Call
+}
+
+// RunHelmInstall is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmInstall() *HelmExecutor_RunHelmInstall_Call {
+ return &HelmExecutor_RunHelmInstall_Call{Call: _e.mock.On("RunHelmInstall")}
+}
+
+func (_c *HelmExecutor_RunHelmInstall_Call) Run(run func()) *HelmExecutor_RunHelmInstall_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmInstall_Call) Return(_a0 error) *HelmExecutor_RunHelmInstall_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmInstall_Call) RunAndReturn(run func() error) *HelmExecutor_RunHelmInstall_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RunHelmLint provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmLint() error {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmLint")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
@@ -51,18 +125,52 @@ func (_m *HelmExecutor) RunHelmLint() error {
return r0
}
+// HelmExecutor_RunHelmLint_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmLint'
+type HelmExecutor_RunHelmLint_Call struct {
+ *mock.Call
+}
+
+// RunHelmLint is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmLint() *HelmExecutor_RunHelmLint_Call {
+ return &HelmExecutor_RunHelmLint_Call{Call: _e.mock.On("RunHelmLint")}
+}
+
+func (_c *HelmExecutor_RunHelmLint_Call) Run(run func()) *HelmExecutor_RunHelmLint_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmLint_Call) Return(_a0 error) *HelmExecutor_RunHelmLint_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmLint_Call) RunAndReturn(run func() error) *HelmExecutor_RunHelmLint_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RunHelmPublish provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmPublish() (string, error) {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmPublish")
+ }
+
var r0 string
+ var r1 error
+ if rf, ok := ret.Get(0).(func() (string, error)); ok {
+ return rf()
+ }
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
- var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
@@ -72,10 +180,41 @@ func (_m *HelmExecutor) RunHelmPublish() (string, error) {
return r0, r1
}
+// HelmExecutor_RunHelmPublish_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmPublish'
+type HelmExecutor_RunHelmPublish_Call struct {
+ *mock.Call
+}
+
+// RunHelmPublish is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmPublish() *HelmExecutor_RunHelmPublish_Call {
+ return &HelmExecutor_RunHelmPublish_Call{Call: _e.mock.On("RunHelmPublish")}
+}
+
+func (_c *HelmExecutor_RunHelmPublish_Call) Run(run func()) *HelmExecutor_RunHelmPublish_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmPublish_Call) Return(_a0 string, _a1 error) *HelmExecutor_RunHelmPublish_Call {
+ _c.Call.Return(_a0, _a1)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmPublish_Call) RunAndReturn(run func() (string, error)) *HelmExecutor_RunHelmPublish_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RunHelmTest provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmTest() error {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmTest")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
@@ -86,10 +225,41 @@ func (_m *HelmExecutor) RunHelmTest() error {
return r0
}
+// HelmExecutor_RunHelmTest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmTest'
+type HelmExecutor_RunHelmTest_Call struct {
+ *mock.Call
+}
+
+// RunHelmTest is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmTest() *HelmExecutor_RunHelmTest_Call {
+ return &HelmExecutor_RunHelmTest_Call{Call: _e.mock.On("RunHelmTest")}
+}
+
+func (_c *HelmExecutor_RunHelmTest_Call) Run(run func()) *HelmExecutor_RunHelmTest_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmTest_Call) Return(_a0 error) *HelmExecutor_RunHelmTest_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmTest_Call) RunAndReturn(run func() error) *HelmExecutor_RunHelmTest_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RunHelmUninstall provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmUninstall() error {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmUninstall")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
@@ -100,10 +270,41 @@ func (_m *HelmExecutor) RunHelmUninstall() error {
return r0
}
+// HelmExecutor_RunHelmUninstall_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmUninstall'
+type HelmExecutor_RunHelmUninstall_Call struct {
+ *mock.Call
+}
+
+// RunHelmUninstall is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmUninstall() *HelmExecutor_RunHelmUninstall_Call {
+ return &HelmExecutor_RunHelmUninstall_Call{Call: _e.mock.On("RunHelmUninstall")}
+}
+
+func (_c *HelmExecutor_RunHelmUninstall_Call) Run(run func()) *HelmExecutor_RunHelmUninstall_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmUninstall_Call) Return(_a0 error) *HelmExecutor_RunHelmUninstall_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmUninstall_Call) RunAndReturn(run func() error) *HelmExecutor_RunHelmUninstall_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
// RunHelmUpgrade provides a mock function with given fields:
func (_m *HelmExecutor) RunHelmUpgrade() error {
ret := _m.Called()
+ if len(ret) == 0 {
+ panic("no return value specified for RunHelmUpgrade")
+ }
+
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
@@ -114,13 +315,39 @@ func (_m *HelmExecutor) RunHelmUpgrade() error {
return r0
}
-type mockConstructorTestingTNewHelmExecutor interface {
- mock.TestingT
- Cleanup(func())
+// HelmExecutor_RunHelmUpgrade_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunHelmUpgrade'
+type HelmExecutor_RunHelmUpgrade_Call struct {
+ *mock.Call
+}
+
+// RunHelmUpgrade is a helper method to define mock.On call
+func (_e *HelmExecutor_Expecter) RunHelmUpgrade() *HelmExecutor_RunHelmUpgrade_Call {
+ return &HelmExecutor_RunHelmUpgrade_Call{Call: _e.mock.On("RunHelmUpgrade")}
+}
+
+func (_c *HelmExecutor_RunHelmUpgrade_Call) Run(run func()) *HelmExecutor_RunHelmUpgrade_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmUpgrade_Call) Return(_a0 error) *HelmExecutor_RunHelmUpgrade_Call {
+ _c.Call.Return(_a0)
+ return _c
+}
+
+func (_c *HelmExecutor_RunHelmUpgrade_Call) RunAndReturn(run func() error) *HelmExecutor_RunHelmUpgrade_Call {
+ _c.Call.Return(run)
+ return _c
}
// NewHelmExecutor creates a new instance of HelmExecutor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-func NewHelmExecutor(t mockConstructorTestingTNewHelmExecutor) *HelmExecutor {
+// The first argument is typically a *testing.T value.
+func NewHelmExecutor(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *HelmExecutor {
mock := &HelmExecutor{}
mock.Mock.Test(t)
From df1db9eed77475f3aece0531eab6458b6f62395d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tilo=20K=C3=B6rner?=
<70266685+tiloKo@users.noreply.github.com>
Date: Wed, 5 Jun 2024 13:51:58 +0200
Subject: [PATCH 14/16] ABAP aakaas and build steps: Parse odata error json
(#4946)
* parseErrorBody Implemented
---
pkg/abap/build/connector.go | 10 +--
pkg/abap/build/gwError.go | 68 +++++++++++++++++++
pkg/abap/build/gwError_test.go | 117 +++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+), 5 deletions(-)
create mode 100644 pkg/abap/build/gwError.go
create mode 100644 pkg/abap/build/gwError_test.go
diff --git a/pkg/abap/build/connector.go b/pkg/abap/build/connector.go
index 2ee1109664..a5d52accdf 100644
--- a/pkg/abap/build/connector.go
+++ b/pkg/abap/build/connector.go
@@ -66,7 +66,7 @@ func (conn *Connector) GetToken(appendum string) error {
}
defer response.Body.Close()
errorbody, _ := io.ReadAll(response.Body)
- return errors.Wrapf(err, "Fetching X-CSRF-Token failed: %v", string(errorbody))
+ return errors.Wrapf(err, "Fetching X-CSRF-Token failed: %v", extractErrorStackFromJsonData(errorbody))
}
defer response.Body.Close()
@@ -85,7 +85,7 @@ func (conn Connector) Get(appendum string) ([]byte, error) {
}
defer response.Body.Close()
errorbody, _ := io.ReadAll(response.Body)
- return errorbody, errors.Wrapf(err, "Get failed: %v", string(errorbody))
+ return errorbody, errors.Wrapf(err, "Get failed: %v", extractErrorStackFromJsonData(errorbody))
}
defer response.Body.Close()
@@ -109,7 +109,7 @@ func (conn Connector) Post(appendum string, importBody string) ([]byte, error) {
}
defer response.Body.Close()
errorbody, _ := io.ReadAll(response.Body)
- return errorbody, errors.Wrapf(err, "Post failed: %v", string(errorbody))
+ return errorbody, errors.Wrapf(err, "Post failed: %v", extractErrorStackFromJsonData(errorbody))
}
defer response.Body.Close()
@@ -268,7 +268,7 @@ func (conn Connector) UploadSarFile(appendum string, sarFile []byte) error {
if err != nil {
defer response.Body.Close()
errorbody, _ := io.ReadAll(response.Body)
- return errors.Wrapf(err, "Upload of SAR file failed: %v", string(errorbody))
+ return errors.Wrapf(err, "Upload of SAR file failed: %v", extractErrorStackFromJsonData(errorbody))
}
defer response.Body.Close()
return nil
@@ -304,7 +304,7 @@ func (conn Connector) UploadSarFileInChunks(appendum string, fileName string, sa
if response != nil && response.Body != nil {
errorbody, _ := io.ReadAll(response.Body)
response.Body.Close()
- return errors.Wrapf(err, "Upload of SAR file failed: %v", string(errorbody))
+ return errors.Wrapf(err, "Upload of SAR file failed: %v", extractErrorStackFromJsonData(errorbody))
} else {
return err
}
diff --git a/pkg/abap/build/gwError.go b/pkg/abap/build/gwError.go
new file mode 100644
index 0000000000..ee019c08d6
--- /dev/null
+++ b/pkg/abap/build/gwError.go
@@ -0,0 +1,68 @@
+package build
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+type GW_error struct {
+ Error struct {
+ Code string
+ Message struct {
+ Lang string
+ Value string
+ }
+ Innererror struct {
+ Application struct {
+ Component_id string
+ Service_namespace string
+ Service_id string
+ Service_version string
+ }
+ Transactionid string
+ Timestamp string
+ Error_Resolution struct {
+ SAP_Transaction string
+ SAP_Note string
+ }
+ Errordetails []struct {
+ ContentID string
+ Code string
+ Message string
+ Propertyref string
+ Severity string
+ Transition bool
+ Target string
+ }
+ }
+ }
+}
+
+func extractErrorStackFromJsonData(jsonData []byte) string {
+ my_error := new(GW_error)
+ if err := my_error.FromJson(jsonData); err != nil {
+ return string(jsonData)
+ }
+ return my_error.ExtractStack()
+}
+
+func (my_error *GW_error) FromJson(inputJson []byte) error {
+ if err := json.Unmarshal(inputJson, my_error); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (my_error *GW_error) ExtractStack() string {
+ var stack strings.Builder
+ var previousMessage string
+ for index, detail := range my_error.Error.Innererror.Errordetails {
+ if previousMessage == detail.Message {
+ continue
+ }
+ previousMessage = detail.Message
+ stack.WriteString(fmt.Sprintf("[%v] %s\n", index, detail.Message))
+ }
+ return stack.String()
+}
diff --git a/pkg/abap/build/gwError_test.go b/pkg/abap/build/gwError_test.go
new file mode 100644
index 0000000000..2c85e39a8b
--- /dev/null
+++ b/pkg/abap/build/gwError_test.go
@@ -0,0 +1,117 @@
+package build
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestExtractErrorStack(t *testing.T) {
+ t.Run("Valid Json String", func(t *testing.T) {
+ //act
+ errorString := extractErrorStackFromJsonData([]byte(validResponse))
+ //assert
+ assert.Equal(t, `[0] Data Provider: SOME_PACKAGE and 0 other packages do not exist in system XXX
+[1] Reading SCs of Packages failed
+`, errorString)
+ })
+
+ t.Run("No Json String", func(t *testing.T) {
+ //arrange
+ var noJson = "ERROR 404: Unauthorized"
+ //act
+ errorString := extractErrorStackFromJsonData([]byte(noJson))
+ //assert
+ assert.Equal(t, noJson, errorString)
+ })
+
+ t.Run("step by step", func(t *testing.T) {
+ my_error := new(GW_error)
+ err := my_error.FromJson([]byte(validResponse))
+ assert.NoError(t, err)
+
+ assert.Equal(t, "/IWBEP/CM_MGW_RT/022", my_error.Error.Code)
+ assert.Equal(t, "en", my_error.Error.Message.Lang)
+ assert.Equal(t, "Data Provider: SOME_PACKAGE and 0 other packages do not exist in system XXX", my_error.Error.Message.Value)
+ assert.Equal(t, "BC-UPG-ADDON", my_error.Error.Innererror.Application.Component_id)
+ assert.Equal(t, "/BUILD/", my_error.Error.Innererror.Application.Service_namespace)
+ assert.Equal(t, "CORE_SRV", my_error.Error.Innererror.Application.Service_id)
+ assert.Equal(t, "0001", my_error.Error.Innererror.Application.Service_version)
+ assert.Equal(t, "1801B32D512B00C0E0066215B8D723B5", my_error.Error.Innererror.Transactionid)
+ assert.Equal(t, "", my_error.Error.Innererror.Timestamp)
+ assert.Equal(t, "", my_error.Error.Innererror.Error_Resolution.SAP_Transaction)
+ assert.Equal(t, "See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)", my_error.Error.Innererror.Error_Resolution.SAP_Note)
+ assert.Equal(t, 3, len(my_error.Error.Innererror.Errordetails))
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[0].ContentID)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[0].Propertyref)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[0].Target)
+ assert.Equal(t, "error", my_error.Error.Innererror.Errordetails[0].Severity)
+ assert.Equal(t, false, my_error.Error.Innererror.Errordetails[0].Transition)
+ assert.Equal(t, "/BUILD/CX_EXTERNAL", my_error.Error.Innererror.Errordetails[0].Code)
+ assert.Equal(t, "Data Provider: SOME_PACKAGE and 0 other packages do not exist in system XXX", my_error.Error.Innererror.Errordetails[0].Message)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[1].ContentID)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[1].Propertyref)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[1].Target)
+ assert.Equal(t, "error", my_error.Error.Innererror.Errordetails[1].Severity)
+ assert.Equal(t, false, my_error.Error.Innererror.Errordetails[1].Transition)
+ assert.Equal(t, "/BUILD/CX_BUILD", my_error.Error.Innererror.Errordetails[1].Code)
+ assert.Equal(t, "Reading SCs of Packages failed", my_error.Error.Innererror.Errordetails[1].Message)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[2].ContentID)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[2].Propertyref)
+ assert.Equal(t, "", my_error.Error.Innererror.Errordetails[2].Target)
+ assert.Equal(t, "error", my_error.Error.Innererror.Errordetails[2].Severity)
+ assert.Equal(t, false, my_error.Error.Innererror.Errordetails[2].Transition)
+ assert.Equal(t, "/IWBEP/CX_MGW_BUSI_EXCEPTION", my_error.Error.Innererror.Errordetails[2].Code)
+ assert.Equal(t, "Reading SCs of Packages failed", my_error.Error.Innererror.Errordetails[2].Message)
+ })
+}
+
+var validResponse = `{
+ "error": {
+ "code": "/IWBEP/CM_MGW_RT/022",
+ "message": {
+ "lang": "en",
+ "value": "Data Provider: SOME_PACKAGE and 0 other packages do not exist in system XXX"
+ },
+ "innererror": {
+ "application": {
+ "component_id": "BC-UPG-ADDON",
+ "service_namespace": "/BUILD/",
+ "service_id": "CORE_SRV",
+ "service_version": "0001"
+ },
+ "transactionid": "1801B32D512B00C0E0066215B8D723B5",
+ "timestamp": "",
+ "Error_Resolution": {
+ "SAP_Transaction": "",
+ "SAP_Note": "See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)"
+ },
+ "errordetails": [{
+ "ContentID": "",
+ "code": "/BUILD/CX_EXTERNAL",
+ "message": "Data Provider: SOME_PACKAGE and 0 other packages do not exist in system XXX",
+ "propertyref": "",
+ "severity": "error",
+ "transition": false,
+ "target": ""
+ }, {
+ "ContentID": "",
+ "code": "/BUILD/CX_BUILD",
+ "message": "Reading SCs of Packages failed",
+ "propertyref": "",
+ "severity": "error",
+ "transition": false,
+ "target": ""
+ }, {
+ "ContentID": "",
+ "code": "/IWBEP/CX_MGW_BUSI_EXCEPTION",
+ "message": "Reading SCs of Packages failed",
+ "propertyref": "",
+ "severity": "error",
+ "transition": false,
+ "target": ""
+ }
+ ]
+ }
+ }
+}`
From e2a5b0928a8ec653f6bd7b3700b5b97ba25e60f9 Mon Sep 17 00:00:00 2001
From: Andrei Kireev
Date: Thu, 6 Jun 2024 09:20:08 +0200
Subject: [PATCH 15/16] feat(detectExecuteScan) Added npm install step for
detectExectueScan (#4949)
* Added npm install step for detectExectueScan
---
cmd/detectExecuteScan.go | 17 ++++++++++++
cmd/detectExecuteScan_generated.go | 33 +++++++++++++++++++++++
resources/metadata/detectExecuteScan.yaml | 26 ++++++++++++++++++
3 files changed, 76 insertions(+)
diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go
index eb608f0c63..a6c07d335d 100644
--- a/cmd/detectExecuteScan.go
+++ b/cmd/detectExecuteScan.go
@@ -20,6 +20,7 @@ import (
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/maven"
+ "github.com/SAP/jenkins-library/pkg/npm"
"github.com/SAP/jenkins-library/pkg/orchestrator"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/reporting"
@@ -213,6 +214,22 @@ func runDetect(ctx context.Context, config detectExecuteScanOptions, utils detec
}
}
+ // Install NPM dependencies
+ if config.InstallNPM {
+ log.Entry().Debugf("running npm install")
+ npmExecutor := npm.NewExecutor(npm.ExecutorOptions{DefaultNpmRegistry: config.DefaultNpmRegistry})
+
+ buildDescriptorList := config.BuildDescriptorList
+ if len(buildDescriptorList) == 0 {
+ buildDescriptorList = []string{"package.json"}
+ }
+
+ err := npmExecutor.InstallAllDependencies(buildDescriptorList)
+ if err != nil {
+ return err
+ }
+ }
+
// for MTA
if config.BuildMTA {
log.Entry().Infof("running MTA Build")
diff --git a/cmd/detectExecuteScan_generated.go b/cmd/detectExecuteScan_generated.go
index 7546438d9d..52db429574 100644
--- a/cmd/detectExecuteScan_generated.go
+++ b/cmd/detectExecuteScan_generated.go
@@ -42,6 +42,9 @@ type detectExecuteScanOptions struct {
InstallArtifacts bool `json:"installArtifacts,omitempty"`
BuildMaven bool `json:"buildMaven,omitempty"`
BuildMTA bool `json:"buildMTA,omitempty"`
+ InstallNPM bool `json:"installNPM,omitempty"`
+ DefaultNpmRegistry string `json:"defaultNpmRegistry,omitempty"`
+ BuildDescriptorList []string `json:"buildDescriptorList,omitempty"`
EnableDiagnostics bool `json:"enableDiagnostics,omitempty"`
GenerateReportsForEmptyProjects bool `json:"generateReportsForEmptyProjects,omitempty"`
MtaPlatform string `json:"mtaPlatform,omitempty"`
@@ -298,6 +301,9 @@ func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScan
cmd.Flags().BoolVar(&stepConfig.InstallArtifacts, "installArtifacts", false, "If enabled, it will install all artifacts to the local maven repository to make them available before running detect. This is required if any maven module has dependencies to other modules in the repository and they were not installed before.")
cmd.Flags().BoolVar(&stepConfig.BuildMaven, "buildMaven", false, "Experiment parameter for maven multi-modules projects building")
cmd.Flags().BoolVar(&stepConfig.BuildMTA, "buildMTA", false, "Experiment parameter for MTA projects building")
+ cmd.Flags().BoolVar(&stepConfig.InstallNPM, "installNPM", false, "Experiment parameter for downloading npm dependencies")
+ cmd.Flags().StringVar(&stepConfig.DefaultNpmRegistry, "defaultNpmRegistry", os.Getenv("PIPER_defaultNpmRegistry"), "URL of the npm registry to use. Defaults to https://registry.npmjs.org/")
+ cmd.Flags().StringSliceVar(&stepConfig.BuildDescriptorList, "buildDescriptorList", []string{}, "List of build descriptors and therefore modules for execution of the npm scripts. The elements have to be paths to the build descriptors.")
cmd.Flags().BoolVar(&stepConfig.EnableDiagnostics, "enableDiagnostics", false, "Parameter to enable diagnostics file generation by detect script")
cmd.Flags().BoolVar(&stepConfig.GenerateReportsForEmptyProjects, "generateReportsForEmptyProjects", false, "If enabled, it will generate reports for empty projects. This could be useful to see the compliance reports in Sirius")
cmd.Flags().StringVar(&stepConfig.MtaPlatform, "mtaPlatform", `CF`, "The platform of the MTA project")
@@ -552,6 +558,33 @@ func detectExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: false,
},
+ {
+ Name: "installNPM",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"STEPS", "STAGES", "PARAMETERS"},
+ Type: "bool",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: false,
+ },
+ {
+ Name: "defaultNpmRegistry",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"PARAMETERS", "GENERAL", "STAGES", "STEPS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{{Name: "npm/defaultNpmRegistry"}},
+ Default: os.Getenv("PIPER_defaultNpmRegistry"),
+ },
+ {
+ Name: "buildDescriptorList",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
+ Type: "[]string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: []string{},
+ },
{
Name: "enableDiagnostics",
ResourceRef: []config.ResourceReference{},
diff --git a/resources/metadata/detectExecuteScan.yaml b/resources/metadata/detectExecuteScan.yaml
index d92bc5dba7..743ab2419e 100644
--- a/resources/metadata/detectExecuteScan.yaml
+++ b/resources/metadata/detectExecuteScan.yaml
@@ -266,6 +266,32 @@ spec:
- STEPS
- STAGES
- PARAMETERS
+ - name: installNPM
+ type: bool
+ default: false
+ description:
+ "Experiment parameter for downloading npm dependencies"
+ scope:
+ - STEPS
+ - STAGES
+ - PARAMETERS
+ - name: defaultNpmRegistry
+ type: string
+ description: "URL of the npm registry to use. Defaults to https://registry.npmjs.org/"
+ scope:
+ - PARAMETERS
+ - GENERAL
+ - STAGES
+ - STEPS
+ aliases:
+ - name: npm/defaultNpmRegistry
+ - name: buildDescriptorList
+ type: "[]string"
+ description: List of build descriptors and therefore modules for execution of the npm scripts. The elements have to be paths to the build descriptors.
+ scope:
+ - PARAMETERS
+ - STAGES
+ - STEPS
- name: enableDiagnostics
type: bool
default: false
From 67ed27f07dc275d89ec1485b068fe9331aff6b4b Mon Sep 17 00:00:00 2001
From: Daria Kuznetsova
Date: Thu, 6 Jun 2024 14:14:03 +0200
Subject: [PATCH 16/16] added sed cmd to transform querySuite (#4945)
* added sed cmd to transform querySuite
* changed sh to bash
* added checking os
* fixed tests by mocking utils
* fixed tests
* renamed param
---------
Co-authored-by: sumeet patil
---
cmd/codeqlExecuteScan.go | 26 ++++++---
cmd/codeqlExecuteScan_generated.go | 11 ++++
cmd/codeqlExecuteScan_test.go | 66 ++++++++++++++++++-----
resources/metadata/codeqlExecuteScan.yaml | 7 +++
4 files changed, 91 insertions(+), 19 deletions(-)
diff --git a/cmd/codeqlExecuteScan.go b/cmd/codeqlExecuteScan.go
index 546a310dd5..cd97f0a981 100644
--- a/cmd/codeqlExecuteScan.go
+++ b/cmd/codeqlExecuteScan.go
@@ -59,9 +59,23 @@ func codeqlExecuteScan(config codeqlExecuteScanOptions, telemetryData *telemetry
influx.step_data.fields.codeql = true
}
-func appendCodeqlQuery(cmd []string, codeqlQuery string) []string {
- if len(codeqlQuery) > 0 {
- cmd = append(cmd, codeqlQuery)
+func appendCodeqlQuerySuite(utils codeqlExecuteScanUtils, cmd []string, querySuite, transformString string) []string {
+ if len(querySuite) > 0 {
+ if len(transformString) > 0 {
+ var bufferOut, bufferErr bytes.Buffer
+ utils.Stdout(&bufferOut)
+ defer utils.Stdout(log.Writer())
+ utils.Stderr(&bufferErr)
+ defer utils.Stderr(log.Writer())
+ if err := utils.RunExecutable("sh", []string{"-c", fmt.Sprintf("echo %s | sed -E \"%s\"", querySuite, transformString)}...); err != nil {
+ log.Entry().WithError(err).Error("failed to transform querySuite")
+ e := bufferErr.String()
+ log.Entry().Error(e)
+ } else {
+ querySuite = strings.TrimSpace(bufferOut.String())
+ }
+ }
+ cmd = append(cmd, querySuite)
}
return cmd
@@ -271,7 +285,7 @@ func runGithubUploadResults(config *codeqlExecuteScanOptions, repoInfo *codeql.R
func executeAnalysis(format, reportName string, customFlags map[string]string, config *codeqlExecuteScanOptions, utils codeqlExecuteScanUtils) ([]piperutils.Path, error) {
moduleTargetPath := filepath.Join(config.ModulePath, "target")
report := filepath.Join(moduleTargetPath, reportName)
- cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, format, report)
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, customFlags, config, format, report)
if err != nil {
log.Entry().Errorf("failed to prepare command for codeql database analyze (format=%s)", format)
return nil, err
@@ -323,11 +337,11 @@ func prepareCmdForDatabaseCreate(customFlags map[string]string, config *codeqlEx
return cmd, nil
}
-func prepareCmdForDatabaseAnalyze(customFlags map[string]string, config *codeqlExecuteScanOptions, format, reportName string) ([]string, error) {
+func prepareCmdForDatabaseAnalyze(utils codeqlExecuteScanUtils, customFlags map[string]string, config *codeqlExecuteScanOptions, format, reportName string) ([]string, error) {
cmd := []string{"database", "analyze", "--format=" + format, "--output=" + reportName, config.Database}
cmd = codeql.AppendThreadsAndRam(cmd, config.Threads, config.Ram, customFlags)
cmd = codeql.AppendCustomFlags(cmd, customFlags)
- cmd = appendCodeqlQuery(cmd, config.QuerySuite)
+ cmd = appendCodeqlQuerySuite(utils, cmd, config.QuerySuite, config.TransformQuerySuite)
return cmd, nil
}
diff --git a/cmd/codeqlExecuteScan_generated.go b/cmd/codeqlExecuteScan_generated.go
index bd4ac20aba..91e6118d12 100644
--- a/cmd/codeqlExecuteScan_generated.go
+++ b/cmd/codeqlExecuteScan_generated.go
@@ -46,6 +46,7 @@ type codeqlExecuteScanOptions struct {
DatabaseCreateFlags string `json:"databaseCreateFlags,omitempty"`
DatabaseAnalyzeFlags string `json:"databaseAnalyzeFlags,omitempty"`
CustomCommand string `json:"customCommand,omitempty"`
+ TransformQuerySuite string `json:"transformQuerySuite,omitempty"`
}
type codeqlExecuteScanInflux struct {
@@ -273,6 +274,7 @@ func addCodeqlExecuteScanFlags(cmd *cobra.Command, stepConfig *codeqlExecuteScan
cmd.Flags().StringVar(&stepConfig.DatabaseCreateFlags, "databaseCreateFlags", os.Getenv("PIPER_databaseCreateFlags"), "A space-separated string of flags for the 'codeql database create' command.")
cmd.Flags().StringVar(&stepConfig.DatabaseAnalyzeFlags, "databaseAnalyzeFlags", os.Getenv("PIPER_databaseAnalyzeFlags"), "A space-separated string of flags for the 'codeql database analyze' command.")
cmd.Flags().StringVar(&stepConfig.CustomCommand, "customCommand", os.Getenv("PIPER_customCommand"), "A custom user-defined command to run between codeql analysis and results upload.")
+ cmd.Flags().StringVar(&stepConfig.TransformQuerySuite, "transformQuerySuite", os.Getenv("PIPER_transformQuerySuite"), "A transform string that will be applied to the querySuite using the sed command.")
cmd.MarkFlagRequired("buildTool")
}
@@ -538,6 +540,15 @@ func codeqlExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_customCommand"),
},
+ {
+ Name: "transformQuerySuite",
+ ResourceRef: []config.ResourceReference{},
+ Scope: []string{"STEPS", "STAGES", "PARAMETERS"},
+ Type: "string",
+ Mandatory: false,
+ Aliases: []config.Alias{},
+ Default: os.Getenv("PIPER_transformQuerySuite"),
+ },
},
},
Containers: []config.Container{
diff --git a/cmd/codeqlExecuteScan_test.go b/cmd/codeqlExecuteScan_test.go
index 775ddea346..2270c6b106 100644
--- a/cmd/codeqlExecuteScan_test.go
+++ b/cmd/codeqlExecuteScan_test.go
@@ -4,6 +4,8 @@
package cmd
import (
+ "fmt"
+ "io"
"os"
"strings"
"testing"
@@ -21,7 +23,11 @@ type codeqlExecuteScanMockUtils struct {
func newCodeqlExecuteScanTestsUtils() codeqlExecuteScanMockUtils {
utils := codeqlExecuteScanMockUtils{
- ExecMockRunner: &mock.ExecMockRunner{},
+ ExecMockRunner: &mock.ExecMockRunner{
+ Stub: func(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error {
+ return nil
+ },
+ },
FilesMock: &mock.FilesMock{},
HttpClientMock: &mock.HttpClientMock{},
}
@@ -406,12 +412,13 @@ func TestPrepareCmdForDatabaseCreate(t *testing.T) {
func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
t.Parallel()
+ utils := codeqlExecuteScanMockUtils{}
t.Run("No additional flags, no querySuite, sarif format", func(t *testing.T) {
config := &codeqlExecuteScanOptions{
Database: "codeqlDB",
}
- cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 5, len(cmd))
@@ -422,7 +429,7 @@ func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
config := &codeqlExecuteScanOptions{
Database: "codeqlDB",
}
- cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "csv", "target/codeqlReport.csv")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, map[string]string{}, config, "csv", "target/codeqlReport.csv")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 5, len(cmd))
@@ -434,7 +441,7 @@ func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
Database: "codeqlDB",
QuerySuite: "security.ql",
}
- cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 6, len(cmd))
@@ -448,7 +455,7 @@ func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
Threads: "1",
Ram: "2000",
}
- cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 8, len(cmd))
@@ -465,7 +472,7 @@ func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
customFlags := map[string]string{
"--threads": "--threads=2",
}
- cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, "sarif-latest", "target/codeqlReport.sarif")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, customFlags, config, "sarif-latest", "target/codeqlReport.sarif")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 8, len(cmd))
@@ -482,7 +489,7 @@ func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
customFlags := map[string]string{
"-j": "-j=2",
}
- cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, "sarif-latest", "target/codeqlReport.sarif")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, customFlags, config, "sarif-latest", "target/codeqlReport.sarif")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 8, len(cmd))
@@ -499,7 +506,7 @@ func TestPrepareCmdForDatabaseAnalyze(t *testing.T) {
customFlags := map[string]string{
"--no-download": "--no-download",
}
- cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, "sarif-latest", "target/codeqlReport.sarif")
+ cmd, err := prepareCmdForDatabaseAnalyze(utils, customFlags, config, "sarif-latest", "target/codeqlReport.sarif")
assert.NoError(t, err)
assert.NotEmpty(t, cmd)
assert.Equal(t, 9, len(cmd))
@@ -559,21 +566,54 @@ func TestPrepareCmdForUploadResults(t *testing.T) {
})
}
-func TestAppendCodeqlQuery(t *testing.T) {
+func TestAppendCodeqlQuerySuite(t *testing.T) {
t.Parallel()
t.Run("Empty query", func(t *testing.T) {
+ utils := newCodeqlExecuteScanTestsUtils()
cmd := []string{"database", "analyze"}
- query := ""
- cmd = appendCodeqlQuery(cmd, query)
+ querySuite := ""
+ cmd = appendCodeqlQuerySuite(utils, cmd, querySuite, "")
assert.Equal(t, 2, len(cmd))
})
t.Run("Not empty query", func(t *testing.T) {
+ utils := newCodeqlExecuteScanTestsUtils()
+ cmd := []string{"database", "analyze"}
+ querySuite := "java-extended.ql"
+ cmd = appendCodeqlQuerySuite(utils, cmd, querySuite, "")
+ assert.Equal(t, 3, len(cmd))
+ })
+
+ t.Run("Add prefix to querySuite", func(t *testing.T) {
+ utils := codeqlExecuteScanMockUtils{
+ ExecMockRunner: &mock.ExecMockRunner{
+ Stub: func(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error {
+ stdout.Write([]byte("test-java-security-extended.qls"))
+ return nil
+ },
+ },
+ }
+ cmd := []string{"database", "analyze"}
+ querySuite := "java-security-extended.qls"
+ cmd = appendCodeqlQuerySuite(utils, cmd, querySuite, `s/^(java|python)-(security-extended\.qls|security-and-quality\.qls)/test-\1-\2/`)
+ assert.Equal(t, 3, len(cmd))
+ assert.Equal(t, "test-java-security-extended.qls", cmd[2])
+ })
+
+ t.Run("Don't add prefix to querySuite", func(t *testing.T) {
+ utils := codeqlExecuteScanMockUtils{
+ ExecMockRunner: &mock.ExecMockRunner{
+ Stub: func(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error {
+ return fmt.Errorf("error")
+ },
+ },
+ }
cmd := []string{"database", "analyze"}
- query := "java-extended.ql"
- cmd = appendCodeqlQuery(cmd, query)
+ querySuite := "php-security-extended.qls"
+ cmd = appendCodeqlQuerySuite(utils, cmd, querySuite, `s/^(java|python)-(security-extended\.qls|security-and-quality\.qls)/test-\1-\2/`)
assert.Equal(t, 3, len(cmd))
+ assert.Equal(t, "php-security-extended.qls", cmd[2])
})
}
diff --git a/resources/metadata/codeqlExecuteScan.yaml b/resources/metadata/codeqlExecuteScan.yaml
index eb9c5d9374..a35952d976 100644
--- a/resources/metadata/codeqlExecuteScan.yaml
+++ b/resources/metadata/codeqlExecuteScan.yaml
@@ -240,6 +240,13 @@ spec:
- STEPS
- STAGES
- PARAMETERS
+ - name: transformQuerySuite
+ type: string
+ description: "A transform string that will be applied to the querySuite using the sed command."
+ scope:
+ - STEPS
+ - STAGES
+ - PARAMETERS
containers:
- image: ""
outputs: