From 0d8234e81bbcf4f5d080c0df70d7e70b106aa4fe Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Thu, 4 Apr 2024 16:00:37 +0200 Subject: [PATCH] Update golangci version and configuration, and fix errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a relatively huge commit that updates the golangci-lint version as well as configuration. ``` make golangci-lint šŸ± running golangci-lintā€¦ WARN [linters_context] copyloopvar: this linter is disabled because the Go version (1.21) of your project is lower than Go 1.22 Compilation finished at Thu Apr 4 13:44:19 ``` Signed-off-by: Vincent Demeester --- .golangci.yml | 26 +- Makefile | 4 +- cmd/entrypoint/subcommands/subcommands.go | 2 +- .../subcommands/subcommands_test.go | 4 +- hack/spec-gen/main.go | 2 +- .../sidecarlogresults/sidecarlogresults.go | 8 +- .../sidecarlogresults_test.go | 20 +- pkg/apis/config/events.go | 8 +- pkg/apis/config/feature_flags.go | 12 +- pkg/apis/config/resolver/store.go | 3 +- pkg/apis/pipeline/pod/template.go | 4 +- pkg/apis/pipeline/v1/container_types.go | 20 +- pkg/apis/pipeline/v1/container_validation.go | 2 +- pkg/apis/pipeline/v1/merge.go | 2 + pkg/apis/pipeline/v1/param_types_test.go | 6 +- pkg/apis/pipeline/v1/pipeline_validation.go | 15 +- .../pipeline/v1/pipelinerun_validation.go | 10 +- pkg/apis/pipeline/v1/result_validation.go | 16 +- .../pipeline/v1/result_validation_test.go | 3 +- pkg/apis/pipeline/v1/task_validation.go | 24 +- pkg/apis/pipeline/v1/task_validation_test.go | 833 +-- pkg/apis/pipeline/v1/taskref_validation.go | 2 +- pkg/apis/pipeline/v1/taskrun_types.go | 3 +- pkg/apis/pipeline/v1/taskrun_validation.go | 14 +- .../pipeline/v1/taskrun_validation_test.go | 3 +- .../pipeline/v1alpha1/run_validation_test.go | 3 +- .../pipeline/v1alpha1/stepaction_types.go | 4 +- .../v1alpha1/stepaction_validation.go | 9 +- pkg/apis/pipeline/v1beta1/container_types.go | 24 +- .../pipeline/v1beta1/container_validation.go | 2 +- .../v1beta1/customrun_validation_test.go | 3 +- pkg/apis/pipeline/v1beta1/merge.go | 2 + pkg/apis/pipeline/v1beta1/param_types_test.go | 6 +- .../pipeline/v1beta1/pipeline_validation.go | 12 +- .../v1beta1/pipelineref_validation.go | 2 +- .../v1beta1/pipelinerun_validation.go | 12 +- .../pipeline/v1beta1/result_validation.go | 12 +- pkg/apis/pipeline/v1beta1/task_conversion.go | 7 +- pkg/apis/pipeline/v1beta1/task_validation.go | 24 +- .../pipeline/v1beta1/task_validation_test.go | 621 +- .../pipeline/v1beta1/taskref_validation.go | 2 +- pkg/apis/pipeline/v1beta1/taskrun_types.go | 3 +- .../pipeline/v1beta1/taskrun_validation.go | 14 +- .../v1beta1/taskrun_validation_test.go | 6 +- pkg/credentials/dockercreds/creds.go | 14 +- pkg/credentials/dockercreds/creds_test.go | 42 +- pkg/credentials/gitcreds/creds_test.go | 46 +- pkg/credentials/initialize.go | 8 +- pkg/credentials/initialize_test.go | 6 +- pkg/entrypoint/entrypointer.go | 4 +- pkg/entrypoint/entrypointer_test.go | 147 +- pkg/internal/resultref/resultref_test.go | 20 +- pkg/pod/creds_init.go | 5 +- pkg/pod/pod.go | 2 +- pkg/pod/pod_test.go | 2328 ++++---- pkg/pod/script.go | 3 +- pkg/pod/status.go | 2 +- .../cloudevent/cloudeventsfakeclient.go | 2 +- .../pipelinerun/affinity_assistant.go | 13 +- .../pipelinerun/pipelinerun_test.go | 237 +- .../pipelinerun_updatestatus_test.go | 5 +- .../pipelinerun/resources/apply_test.go | 5211 +++++++++-------- .../pipelinerun/resources/pipelineref_test.go | 286 +- .../resources/pipelinerunresolution.go | 8 +- .../resources/pipelinerunresolution_test.go | 141 +- .../resources/validate_params_test.go | 706 +-- pkg/reconciler/pipelinerun/tracing.go | 6 +- .../taskrun/resources/taskref_test.go | 13 +- .../taskrun/resources/taskspec_test.go | 9 +- pkg/reconciler/taskrun/taskrun_test.go | 237 +- .../taskrun/validate_taskrun_test.go | 20 +- pkg/reconciler/volumeclaim/pvchandler.go | 3 +- pkg/remote/oci/resolver.go | 2 +- pkg/resolution/common/interface.go | 2 +- pkg/resolution/resolver/bundle/bundle.go | 2 +- pkg/resolution/resolver/bundle/params.go | 3 +- pkg/resolution/resolver/cluster/resolver.go | 2 +- .../resolver/framework/interface.go | 14 +- pkg/resolution/resolver/git/resolver.go | 4 +- pkg/resolution/resolver/git/resolver_test.go | 6 +- pkg/resolution/resolver/http/resolver.go | 4 +- pkg/resolution/resolver/http/resolver_test.go | 8 +- pkg/resolution/resolver/hub/resolver.go | 14 +- pkg/resolution/resolver/hub/resolver_test.go | 13 +- pkg/spire/config/config.go | 3 +- pkg/spire/controller.go | 30 +- pkg/spire/verify.go | 1 + pkg/tracing/tracing.go | 3 +- pkg/trustedresources/verify_test.go | 16 +- pkg/workspace/validate.go | 3 +- test/conversion_test.go | 2 +- test/custom_task_test.go | 2 +- test/diff/print.go | 4 +- test/gohelloworld/main.go | 1 + test/hermetic_taskrun_test.go | 4 +- test/matrix_test.go | 12 +- test/pipelinerun_test.go | 4 +- test/remote.go | 21 +- test/serviceaccount_test.go | 8 +- test/sidecar_test.go | 6 +- test/step_output_test.go | 4 +- test/tektonbundles_test.go | 10 +- test/timeout_test.go | 7 +- test/trustedresources.go | 35 +- test/util.go | 4 +- 105 files changed, 5950 insertions(+), 5642 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 5081f5c9d3f..72e9dbee8e5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,6 +16,20 @@ linters-settings: - github.com/ghodss/yaml: recommendations: - sigs.k8s.io/yaml + depguard: + rules: + prevent_unmaintained_packages: + list-mode: lax # allow unless explicitely denied + files: + - $all + - "!$test" + allow: + - $gostd + deny: + - pkg: io/ioutil + desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil" + - pkg: github.com/ghodss/yaml + desc: "use sigs.k8s.io/yaml instead, to be consistent" linters: enable: - bodyclose @@ -174,16 +188,16 @@ issues: # Enable off-by-default rules for revive requiring that all exported elements have a properly formatted comment. - EXC0012 # https://golangci-lint.run/usage/false-positives/#exc0012 - EXC0014 # https://golangci-lint.run/usage/false-positives/#exc0014 -run: - issues-exit-code: 1 - build-tags: - - e2e - skip-files: + exclude-files: - .*/zz_generated.deepcopy.go - pkg/apis/pipeline/v1beta1/openapi_generated.go - skip-dirs: + exclude-dirs: - vendor - pkg/client - pkg/spire/test +run: + issues-exit-code: 1 + build-tags: + - e2e timeout: 20m modules-download-mode: vendor diff --git a/Makefile b/Makefile index f89a880e5cd..09969e5e834 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TESTPKGS = $(shell env GO111MODULE=on $(GO) list -f \ BIN = $(CURDIR)/.bin WOKE ?= go run -modfile go.mod github.com/get-woke/woke -GOLANGCI_VERSION = v1.52.2 +GOLANGCI_VERSION = v1.57.2 WOKE_VERSION = v0.19.0 GO = go @@ -170,7 +170,7 @@ $(BIN)/golangci-lint: ; $(info $(M) getting golangci-lint $(GOLANGCI_VERSION)) .PHONY: golangci-lint golangci-lint: | $(GOLANGCILINT) ; $(info $(M) running golangci-lintā€¦) @ ## Run golangci-lint - $Q $(GOLANGCILINT) run --modules-download-mode=vendor --max-issues-per-linter=0 --max-same-issues=0 --deadline 5m + $Q $(GOLANGCILINT) run --modules-download-mode=vendor --max-issues-per-linter=0 --max-same-issues=0 --timeout 5m .PHONY: golangci-lint-check golangci-lint-check: | $(GOLANGCILINT) ; $(info $(M) Testing if golint has been doneā€¦) @ ## Run golangci-lint for build tests CI job diff --git a/cmd/entrypoint/subcommands/subcommands.go b/cmd/entrypoint/subcommands/subcommands.go index 4a2bf3b50dc..b9229546d8d 100644 --- a/cmd/entrypoint/subcommands/subcommands.go +++ b/cmd/entrypoint/subcommands/subcommands.go @@ -95,7 +95,7 @@ func Process(args []string) error { if err := decodeScript(src); err != nil { return SubcommandError{subcommand: DecodeScriptCommand, message: err.Error()} } - return OK{message: fmt.Sprintf("Decoded script %s", src)} + return OK{message: "Decoded script " + src} } case StepInitCommand: if err := stepInit(args[1:]); err != nil { diff --git a/cmd/entrypoint/subcommands/subcommands_test.go b/cmd/entrypoint/subcommands/subcommands_test.go index 188c7431f04..5f82863e424 100644 --- a/cmd/entrypoint/subcommands/subcommands_test.go +++ b/cmd/entrypoint/subcommands/subcommands_test.go @@ -32,12 +32,12 @@ func TestProcessSuccessfulSubcommands(t *testing.T) { src := filepath.Join(tmp, "foo.txt") dst := filepath.Join(tmp, "bar.txt") - srcFile, err := os.OpenFile(src, os.O_WRONLY|os.O_CREATE, 0666) + srcFile, err := os.OpenFile(src, os.O_WRONLY|os.O_CREATE, 0o666) if err != nil { t.Fatalf("error opening temp file for writing: %v", err) } defer srcFile.Close() - if _, err := srcFile.Write([]byte(helloWorldBase64)); err != nil { + if _, err := srcFile.WriteString(helloWorldBase64); err != nil { t.Fatalf("error writing source file: %v", err) } diff --git a/hack/spec-gen/main.go b/hack/spec-gen/main.go index 68d378496de..c4db45260e9 100644 --- a/hack/spec-gen/main.go +++ b/hack/spec-gen/main.go @@ -53,7 +53,7 @@ func main() { return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(swaggify(name))) }) default: - panic(fmt.Sprintf("Unsupported API version: %s", *apiVersion)) + panic("Unsupported API version: " + *apiVersion) } defs := spec.Definitions{} for defName, val := range oAPIDefs { diff --git a/internal/sidecarlogresults/sidecarlogresults.go b/internal/sidecarlogresults/sidecarlogresults.go index 12382d50458..e9ce11b86db 100644 --- a/internal/sidecarlogresults/sidecarlogresults.go +++ b/internal/sidecarlogresults/sidecarlogresults.go @@ -47,9 +47,9 @@ const ( // SidecarLogResult holds fields for storing extracted results type SidecarLogResult struct { - Name string - Value string - Type SidecarLogResultType + Name string `json:"name"` + Value string `json:"value"` + Type SidecarLogResultType `json:"type"` } func fileExists(filename string) (bool, error) { @@ -91,7 +91,7 @@ func waitForStepsToFinish(runDir string) error { // in either case, existence of out.err marks that the step errored and the following steps will // not run. We want the function to break out with nil error in that case so that // the existing results can be logged. - if exists, err = fileExists(fmt.Sprintf("%s.err", stepFile)); exists || err != nil { + if exists, err = fileExists(stepFile + ".err"); exists || err != nil { return err } } diff --git a/internal/sidecarlogresults/sidecarlogresults_test.go b/internal/sidecarlogresults/sidecarlogresults_test.go index 8543b780a62..2f6a3de8dad 100644 --- a/internal/sidecarlogresults/sidecarlogresults_test.go +++ b/internal/sidecarlogresults/sidecarlogresults_test.go @@ -40,10 +40,10 @@ import ( func TestLookForResults_FanOutAndWait(t *testing.T) { for _, c := range []struct { desc string - results []SidecarLogResult + Results []SidecarLogResult `json:"result"` }{{ desc: "multiple results", - results: []SidecarLogResult{{ + Results: []SidecarLogResult{{ Name: "foo", Value: "bar", Type: "task", @@ -57,7 +57,7 @@ func TestLookForResults_FanOutAndWait(t *testing.T) { dir := t.TempDir() resultNames := []string{} wantResults := []byte{} - for _, result := range c.results { + for _, result := range c.Results { createResult(t, dir, result.Name, result.Value) resultNames = append(resultNames, result.Name) encodedResult, err := json.Marshal(result) @@ -363,7 +363,7 @@ func TestParseResults_InvalidType(t *testing.T) { } for _, plog := range podLogs { _, err := parseResults([]byte(plog), 4096) - wantErr := fmt.Errorf("invalid sidecar result type not task or step. Must be task or step") + wantErr := errors.New("invalid sidecar result type not task or step. Must be task or step") if d := cmp.Diff(wantErr.Error(), err.Error()); d != "" { t.Fatal(diff.PrintWantGot(d)) } @@ -468,7 +468,7 @@ func TestExtractStepAndResultFromSidecarResultName(t *testing.T) { func TestExtractStepAndResultFromSidecarResultName_Error(t *testing.T) { sidecarResultName := "step-foo-resultName" _, _, err := ExtractStepAndResultFromSidecarResultName(sidecarResultName) - wantErr := fmt.Errorf("invalid string step-foo-resultName : expected somtthing that looks like .") + wantErr := errors.New("invalid string step-foo-resultName : expected somtthing that looks like .") if d := cmp.Diff(wantErr.Error(), err.Error()); d != "" { t.Fatal(diff.PrintWantGot(d)) } @@ -477,9 +477,9 @@ func TestExtractStepAndResultFromSidecarResultName_Error(t *testing.T) { func createStepResult(t *testing.T, dir, stepName, resultName, resultValue string) { t.Helper() resultDir := filepath.Join(dir, stepName, "results") - _ = os.MkdirAll(resultDir, 0755) + _ = os.MkdirAll(resultDir, 0o755) resultFile := filepath.Join(resultDir, resultName) - err := os.WriteFile(resultFile, []byte(resultValue), 0644) + err := os.WriteFile(resultFile, []byte(resultValue), 0o644) if err != nil { t.Fatal(err) } @@ -488,7 +488,7 @@ func createStepResult(t *testing.T, dir, stepName, resultName, resultValue strin func createResult(t *testing.T, dir string, resultName string, resultValue string) { t.Helper() resultFile := filepath.Join(dir, resultName) - err := os.WriteFile(resultFile, []byte(resultValue), 0644) + err := os.WriteFile(resultFile, []byte(resultValue), 0o644) if err != nil { t.Fatal(err) } @@ -497,12 +497,12 @@ func createResult(t *testing.T, dir string, resultName string, resultValue strin func createRun(t *testing.T, dir string, causeErr bool) { t.Helper() stepFile := filepath.Join(dir, "1") - _ = os.Mkdir(stepFile, 0755) + _ = os.Mkdir(stepFile, 0o755) stepFile = filepath.Join(stepFile, "out") if causeErr { stepFile += ".err" } - err := os.WriteFile(stepFile, []byte(""), 0644) + err := os.WriteFile(stepFile, []byte(""), 0o644) if err != nil { t.Fatal(err) } diff --git a/pkg/apis/config/events.go b/pkg/apis/config/events.go index fca87c4aa7e..0ae07b35e2a 100644 --- a/pkg/apis/config/events.go +++ b/pkg/apis/config/events.go @@ -17,7 +17,7 @@ limitations under the License. package config import ( - "fmt" + "errors" "os" "sort" "strings" @@ -106,17 +106,17 @@ func (efs EventFormats) Equals(other EventFormats) bool { func ParseEventFormats(formats string) (EventFormats, error) { // An empty string is not a valid configuration if formats == "" { - return EventFormats{}, fmt.Errorf("formats cannot be empty") + return EventFormats{}, errors.New("formats cannot be empty") } stringFormats := strings.Split(formats, ",") var eventFormats EventFormats = make(map[EventFormat]struct{}, len(stringFormats)) for _, format := range stringFormats { if !EventFormat(format).IsValid() { - return EventFormats{}, fmt.Errorf("invalid format: %s", format) + return EventFormats{}, errors.New("invalid format: " + format) } // If already in the map (duplicate), fail if _, ok := eventFormats[EventFormat(format)]; ok { - return EventFormats{}, fmt.Errorf("duplicate format: %s", format) + return EventFormats{}, errors.New("duplicate format: " + format) } eventFormats[EventFormat(format)] = struct{}{} } diff --git a/pkg/apis/config/feature_flags.go b/pkg/apis/config/feature_flags.go index d4be3c024ee..deda086727f 100644 --- a/pkg/apis/config/feature_flags.go +++ b/pkg/apis/config/feature_flags.go @@ -146,13 +146,15 @@ var ( DefaultEnableStepActions = PerFeatureFlag{ Name: EnableStepActions, Stability: AlphaAPIFields, - Enabled: DefaultAlphaFeatureEnabled} + Enabled: DefaultAlphaFeatureEnabled, + } // DefaultEnableArtifacts is the default PerFeatureFlag value for EnableStepActions DefaultEnableArtifacts = PerFeatureFlag{ Name: EnableStepActions, Stability: AlphaAPIFields, - Enabled: DefaultAlphaFeatureEnabled} + Enabled: DefaultAlphaFeatureEnabled, + } // DefaultEnableParamEnum is the default PerFeatureFlag value for EnableParamEnum DefaultEnableParamEnum = PerFeatureFlag{ @@ -164,8 +166,6 @@ var ( // FeatureFlags holds the features configurations // +k8s:deepcopy-gen=true -// -//nolint:musttag type FeatureFlags struct { DisableAffinityAssistant bool DisableCredsInit bool @@ -349,7 +349,7 @@ func setCoschedule(cfgMap map[string]string, defaultValue string, disabledAffini // setEnforceNonFalsifiability sets the "enforce-nonfalsifiability" flag based on the content of a given map. // If the feature gate is invalid, then an error is returned. func setEnforceNonFalsifiability(cfgMap map[string]string, feature *string) error { - var value = DefaultEnforceNonfalsifiability + value := DefaultEnforceNonfalsifiability if cfg, ok := cfgMap[enforceNonfalsifiability]; ok { value = strings.ToLower(cfg) } @@ -393,7 +393,7 @@ func setMaxResultSize(cfgMap map[string]string, defaultValue int, feature *int) } // if max limit is > 1.5 MB (CRD limit). if value >= 1572864 { - return fmt.Errorf("invalid value for feature flag %q: %q. This is exceeding the CRD limit", resultExtractionMethod, fmt.Sprint(value)) + return fmt.Errorf("invalid value for feature flag %q: %q. This is exceeding the CRD limit", resultExtractionMethod, strconv.Itoa(value)) } *feature = value return nil diff --git a/pkg/apis/config/resolver/store.go b/pkg/apis/config/resolver/store.go index 9d48ba1b29a..62f14af7540 100644 --- a/pkg/apis/config/resolver/store.go +++ b/pkg/apis/config/resolver/store.go @@ -18,7 +18,6 @@ package resolver import ( "context" - "fmt" "knative.dev/pkg/configmap" ) @@ -33,7 +32,7 @@ type Config struct { // ResolversNamespace takes the pipelines namespace and appends "-resolvers" to it. func ResolversNamespace(baseNS string) string { - return fmt.Sprintf("%s-resolvers", baseNS) + return baseNS + "-resolvers" } // FromContext extracts a Config from the provided context. diff --git a/pkg/apis/pipeline/pod/template.go b/pkg/apis/pipeline/pod/template.go index e551e6efdee..855a6ea9b8d 100644 --- a/pkg/apis/pipeline/pod/template.go +++ b/pkg/apis/pipeline/pod/template.go @@ -37,7 +37,7 @@ type Template struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // If specified, the pod's tolerations. // +optional @@ -59,7 +59,7 @@ type Template struct { // +patchMergeKey=name // +patchStrategy=merge,retainKeys // +listType=atomic - Volumes []corev1.Volume `json:"volumes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,1,rep,name=volumes"` + Volumes []corev1.Volume `json:"volumes,omitempty" patchMergeKey:"name" patchStrategy:"merge,retainKeys" protobuf:"bytes,1,rep,name=volumes"` // RuntimeClassName refers to a RuntimeClass object in the node.k8s.io // group, which should be used to run this pod. If no RuntimeClass resource diff --git a/pkg/apis/pipeline/v1/container_types.go b/pkg/apis/pipeline/v1/container_types.go index b7da45e0b57..9f0c48ae9af 100644 --- a/pkg/apis/pipeline/v1/container_types.go +++ b/pkg/apis/pipeline/v1/container_types.go @@ -72,7 +72,7 @@ type Step struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // ComputeResources required by this Step. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ @@ -84,13 +84,13 @@ type Step struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` // volumeDevices is the list of block devices to be used by the Step. // +patchMergeKey=devicePath // +patchStrategy=merge // +optional // +listType=atomic - VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchMergeKey:"devicePath" patchStrategy:"merge" protobuf:"bytes,21,rep,name=volumeDevices"` // Image pull policy. // One of Always, Never, IfNotPresent. // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. @@ -294,7 +294,7 @@ type StepTemplate struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // ComputeResources required by this Step. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ @@ -306,13 +306,13 @@ type StepTemplate struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` // volumeDevices is the list of block devices to be used by the Step. // +patchMergeKey=devicePath // +patchStrategy=merge // +optional // +listType=atomic - VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchMergeKey:"devicePath" patchStrategy:"merge" protobuf:"bytes,21,rep,name=volumeDevices"` // Image pull policy. // One of Always, Never, IfNotPresent. // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. @@ -410,7 +410,7 @@ type Sidecar struct { // +listType=map // +listMapKey=containerPort // +listMapKey=protocol - Ports []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + Ports []corev1.ContainerPort `json:"ports,omitempty" patchMergeKey:"containerPort" patchStrategy:"merge" protobuf:"bytes,6,rep,name=ports"` // List of sources to populate environment variables in the Sidecar. // The keys defined within a source must be a C_IDENTIFIER. All invalid keys // will be reported as an event when the container is starting. When a key exists in multiple @@ -426,7 +426,7 @@ type Sidecar struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // ComputeResources required by this Sidecar. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ @@ -438,13 +438,13 @@ type Sidecar struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` // volumeDevices is the list of block devices to be used by the Sidecar. // +patchMergeKey=devicePath // +patchStrategy=merge // +optional // +listType=atomic - VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchMergeKey:"devicePath" patchStrategy:"merge" protobuf:"bytes,21,rep,name=volumeDevices"` // Periodic probe of Sidecar liveness. // Container will be restarted if the probe fails. // Cannot be updated. diff --git a/pkg/apis/pipeline/v1/container_validation.go b/pkg/apis/pipeline/v1/container_validation.go index 56108b63db8..bfee6884b0b 100644 --- a/pkg/apis/pipeline/v1/container_validation.go +++ b/pkg/apis/pipeline/v1/container_validation.go @@ -29,7 +29,7 @@ import ( // correctly. No errors are returned for a nil Ref. func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { - return + return errs } switch { diff --git a/pkg/apis/pipeline/v1/merge.go b/pkg/apis/pipeline/v1/merge.go index 8d44d724a3f..83054f5f9e3 100644 --- a/pkg/apis/pipeline/v1/merge.go +++ b/pkg/apis/pipeline/v1/merge.go @@ -76,6 +76,7 @@ func MergeStepsWithSpecs(steps []Step, overrides []TaskRunStepSpec) ([]Step, err stepNameToOverride[o.Name] = o } for i, s := range steps { + s := s o, found := stepNameToOverride[s.Name] if !found { continue @@ -102,6 +103,7 @@ func MergeSidecarsWithSpecs(sidecars []Sidecar, overrides []TaskRunSidecarSpec) sidecarNameToOverride[o.Name] = o } for i, s := range sidecars { + s := s o, found := sidecarNameToOverride[s.Name] if !found { continue diff --git a/pkg/apis/pipeline/v1/param_types_test.go b/pkg/apis/pipeline/v1/param_types_test.go index 9a67bd00ca3..ae7d779f437 100644 --- a/pkg/apis/pipeline/v1/param_types_test.go +++ b/pkg/apis/pipeline/v1/param_types_test.go @@ -308,6 +308,7 @@ type ParamValuesHolder struct { AOrS v1.ParamValue `json:"val"` } +//nolint:musttag func TestParamValues_UnmarshalJSON(t *testing.T) { cases := []struct { input map[string]interface{} @@ -398,6 +399,7 @@ func TestParamValues_UnmarshalJSON_Directly(t *testing.T) { } } +//nolint:musttag func TestParamValues_UnmarshalJSON_Error(t *testing.T) { cases := []struct { desc string @@ -415,6 +417,7 @@ func TestParamValues_UnmarshalJSON_Error(t *testing.T) { } } +//nolint:musttag func TestParamValues_MarshalJSON(t *testing.T) { cases := []struct { input v1.ParamValue @@ -471,7 +474,8 @@ func TestExtractNames(t *testing.T) { params: v1.Params{{ Name: "IMAGE", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "image-1"}, }, { - Name: "DOCKERFILE", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "path/to/Dockerfile1"}}}, + Name: "DOCKERFILE", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "path/to/Dockerfile1"}, + }}, want: sets.NewString("IMAGE", "DOCKERFILE"), }, { name: "extract param names from ParamTypeArray", diff --git a/pkg/apis/pipeline/v1/pipeline_validation.go b/pkg/apis/pipeline/v1/pipeline_validation.go index a6e89030bf3..5ff738ad372 100644 --- a/pkg/apis/pipeline/v1/pipeline_validation.go +++ b/pkg/apis/pipeline/v1/pipeline_validation.go @@ -34,8 +34,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*Pipeline)(nil) -var _ resourcesemantics.VerbLimited = (*Pipeline)(nil) +var ( + _ apis.Validatable = (*Pipeline)(nil) + _ resourcesemantics.VerbLimited = (*Pipeline)(nil) +) const ( taskRef = "taskRef" @@ -421,6 +423,7 @@ func ValidatePipelineParameterVariables(ctx context.Context, tasks []PipelineTas } return errs } + func validatePipelineParametersVariables(tasks []PipelineTask, prefix string, paramNames sets.String, arrayParamNames sets.String, objectParamNameKeys map[string][]string) (errs *apis.FieldError) { for idx, task := range tasks { errs = errs.Also(validatePipelineParametersVariablesInTaskParameters(task.Params, prefix, paramNames, arrayParamNames, objectParamNameKeys).ViaIndex(idx)) @@ -552,8 +555,8 @@ func (pt *PipelineTask) validateExecutionStatusVariablesAllowed(ptNames sets.Str func validateContainsExecutionStatusVariablesDisallowed(expressions []string, path string) (errs *apis.FieldError) { if containsExecutionStatusReferences(expressions) { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("pipeline tasks can not refer to execution status"+ - " of any other pipeline task or aggregate status of tasks"), path)) + errs = errs.Also(apis.ErrInvalidValue("pipeline tasks can not refer to execution status"+ + " of any other pipeline task or aggregate status of tasks", path)) } return errs } @@ -593,6 +596,7 @@ func validateExecutionStatusVariablesExpressions(expressions []string, ptNames s } return errs } + func validatePipelineContextVariablesInParamValues(paramValues []string, prefix string, contextNames sets.String) (errs *apis.FieldError) { for _, paramValue := range paramValues { errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(paramValue, prefix, contextNames).ViaField("value")) @@ -662,7 +666,6 @@ func taskContainsResult(resultExpression string, pipelineTaskNames sets.String, if expression != "" { value := stripVarSubExpression("$" + expression) pr, err := resultref.ParseTaskExpression(value) - if err != nil { return false } @@ -792,7 +795,7 @@ func validateMatrixedPipelineTaskConsumed(expressions []string, taskMapping map[ taskConsumed := taskMapping[pipelineTask] if taskConsumed.IsMatrixed() { if !strings.HasSuffix(expression, "[*]") { - errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("A matrixed pipelineTask can only be consumed in aggregate using [*] notation, but is currently set to %s", expression))) + errs = errs.Also(apis.ErrGeneric("A matrixed pipelineTask can only be consumed in aggregate using [*] notation, but is currently set to " + expression)) } filteredExpressions = append(filteredExpressions, expression) } diff --git a/pkg/apis/pipeline/v1/pipelinerun_validation.go b/pkg/apis/pipeline/v1/pipelinerun_validation.go index 84698b06644..aea583b940b 100644 --- a/pkg/apis/pipeline/v1/pipelinerun_validation.go +++ b/pkg/apis/pipeline/v1/pipelinerun_validation.go @@ -30,8 +30,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*PipelineRun)(nil) -var _ resourcesemantics.VerbLimited = (*PipelineRun)(nil) +var ( + _ apis.Validatable = (*PipelineRun)(nil) + _ resourcesemantics.VerbLimited = (*PipelineRun)(nil) +) // SupportedVerbs returns the operations that validation should be called for func (pr *PipelineRun) SupportedVerbs() []admissionregistrationv1.OperationType { @@ -230,8 +232,8 @@ func validateSpecStatus(status PipelineRunSpecStatus) *apis.FieldError { func validateTimeoutDuration(field string, d *metav1.Duration) (errs *apis.FieldError) { if d != nil && d.Duration < 0 { - fieldPath := fmt.Sprintf("timeouts.%s", field) - return errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s should be >= 0", d.Duration.String()), fieldPath)) + fieldPath := "timeouts." + field + return errs.Also(apis.ErrInvalidValue(d.Duration.String()+" should be >= 0", fieldPath)) } return nil } diff --git a/pkg/apis/pipeline/v1/result_validation.go b/pkg/apis/pipeline/v1/result_validation.go index 233c48b5083..0ce08fc174e 100644 --- a/pkg/apis/pipeline/v1/result_validation.go +++ b/pkg/apis/pipeline/v1/result_validation.go @@ -47,7 +47,7 @@ func (tr TaskResult) Validate(ctx context.Context) (errs *apis.FieldError) { // for Properties values it will check if the type is string. func validateObjectResult(tr TaskResult) (errs *apis.FieldError) { if ParamType(tr.Type) == ParamTypeObject && tr.Properties == nil { - return apis.ErrMissingField(fmt.Sprintf("%s.properties", tr.Name)) + return apis.ErrMissingField(tr.Name + ".properties") } invalidKeys := []string{} @@ -60,7 +60,7 @@ func validateObjectResult(tr TaskResult) (errs *apis.FieldError) { if len(invalidKeys) != 0 { return &apis.FieldError{ Message: fmt.Sprintf("The value type specified for these keys %v is invalid, the type must be string", invalidKeys), - Paths: []string{fmt.Sprintf("%s.properties", tr.Name)}, + Paths: []string{tr.Name + ".properties"}, } } return nil @@ -81,7 +81,7 @@ func (tr TaskResult) validateValue(ctx context.Context) (errs *apis.FieldError) Message: fmt.Sprintf( "Invalid Type. Wanted string but got: \"%v\"", tr.Value.Type), Paths: []string{ - fmt.Sprintf("%s.type", tr.Name), + tr.Name + ".type", }, } } @@ -90,20 +90,20 @@ func (tr TaskResult) validateValue(ctx context.Context) (errs *apis.FieldError) if err != nil { return &apis.FieldError{ Message: fmt.Sprintf("%v", err), - Paths: []string{fmt.Sprintf("%s.value", tr.Name)}, + Paths: []string{tr.Name + ".value"}, } } if e := validation.IsDNS1123Label(stepName); len(e) > 0 { errs = errs.Also(&apis.FieldError{ Message: fmt.Sprintf("invalid extracted step name %q", stepName), - Paths: []string{fmt.Sprintf("%s.value", tr.Name)}, + Paths: []string{tr.Name + ".value"}, Details: "stepName in $(steps..results.) must be a valid DNS Label, For more info refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", }) } if !resultNameFormatRegex.MatchString(resultName) { errs = errs.Also(&apis.FieldError{ Message: fmt.Sprintf("invalid extracted result name %q", resultName), - Paths: []string{fmt.Sprintf("%s.value", tr.Name)}, + Paths: []string{tr.Name + ".value"}, Details: fmt.Sprintf("resultName in $(steps..results.) must consist of alphanumeric characters, '-', '_', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my-name', or 'my_name', regex used for validation is '%s')", ResultNameFormat), }) } @@ -136,7 +136,7 @@ func (sr StepResult) Validate(ctx context.Context) (errs *apis.FieldError) { // for Properties values it will check if the type is string. func validateObjectStepResult(sr StepResult) (errs *apis.FieldError) { if ParamType(sr.Type) == ParamTypeObject && sr.Properties == nil { - return apis.ErrMissingField(fmt.Sprintf("%s.properties", sr.Name)) + return apis.ErrMissingField(sr.Name + ".properties") } invalidKeys := []string{} @@ -150,7 +150,7 @@ func validateObjectStepResult(sr StepResult) (errs *apis.FieldError) { if len(invalidKeys) != 0 { return &apis.FieldError{ Message: fmt.Sprintf("the value type specified for these keys %v is invalid, the type must be string", invalidKeys), - Paths: []string{fmt.Sprintf("%s.properties", sr.Name)}, + Paths: []string{sr.Name + ".properties"}, } } return nil diff --git a/pkg/apis/pipeline/v1/result_validation_test.go b/pkg/apis/pipeline/v1/result_validation_test.go index 10f4f3c1f08..ed71596b90b 100644 --- a/pkg/apis/pipeline/v1/result_validation_test.go +++ b/pkg/apis/pipeline/v1/result_validation_test.go @@ -18,6 +18,7 @@ package v1_test import ( "context" + "errors" "fmt" "testing" @@ -313,7 +314,7 @@ func TestExtractStepResultNameError(t *testing.T) { }{{ name: "invalid string format", value: "not valid", - wantErr: fmt.Errorf(`Could not extract step name and result name. Expected value to look like $(steps..results.) but got "not valid"`), + wantErr: errors.New(`Could not extract step name and result name. Expected value to look like $(steps..results.) but got "not valid"`), }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1/task_validation.go b/pkg/apis/pipeline/v1/task_validation.go index 5c6b8b27edc..5c7addf54fb 100644 --- a/pkg/apis/pipeline/v1/task_validation.go +++ b/pkg/apis/pipeline/v1/task_validation.go @@ -49,16 +49,20 @@ const ( objectVariableNameFormat = "^[_a-zA-Z][_a-zA-Z0-9-]*$" ) -var _ apis.Validatable = (*Task)(nil) -var _ resourcesemantics.VerbLimited = (*Task)(nil) +var ( + _ apis.Validatable = (*Task)(nil) + _ resourcesemantics.VerbLimited = (*Task)(nil) +) // SupportedVerbs returns the operations that validation should be called for func (t *Task) SupportedVerbs() []admissionregistrationv1.OperationType { return []admissionregistrationv1.OperationType{admissionregistrationv1.Create, admissionregistrationv1.Update} } -var stringAndArrayVariableNameFormatRegex = regexp.MustCompile(stringAndArrayVariableNameFormat) -var objectVariableNameFormatRegex = regexp.MustCompile(objectVariableNameFormat) +var ( + stringAndArrayVariableNameFormatRegex = regexp.MustCompile(stringAndArrayVariableNameFormat) + objectVariableNameFormatRegex = regexp.MustCompile(objectVariableNameFormat) +) // Validate implements apis.Validatable func (t *Task) Validate(ctx context.Context) *apis.FieldError { @@ -114,7 +118,7 @@ func ValidateObjectParamsHaveProperties(ctx context.Context, params ParamSpecs) var errs *apis.FieldError for _, p := range params { if p.Type == ParamTypeObject && p.Properties == nil { - errs = errs.Also(apis.ErrMissingField(fmt.Sprintf("%s.properties", p.Name))) + errs = errs.Also(apis.ErrMissingField(p.Name + ".properties")) } } return errs @@ -493,7 +497,7 @@ func (p ParamSpec) ValidateType(ctx context.Context) *apis.FieldError { } } if !validType { - return apis.ErrInvalidValue(p.Type, fmt.Sprintf("%s.type", p.Name)) + return apis.ErrInvalidValue(p.Type, p.Name+".type") } // If a default value is provided, ensure its type matches param's declared type. @@ -502,8 +506,8 @@ func (p ParamSpec) ValidateType(ctx context.Context) *apis.FieldError { Message: fmt.Sprintf( "\"%v\" type does not match default value's type: \"%v\"", p.Type, p.Default.Type), Paths: []string{ - fmt.Sprintf("%s.type", p.Name), - fmt.Sprintf("%s.default.type", p.Name), + p.Name + ".type", + p.Name + ".default.type", }, } } @@ -526,7 +530,7 @@ func (p ParamSpec) ValidateObjectType(ctx context.Context) *apis.FieldError { if len(invalidKeys) != 0 { return &apis.FieldError{ Message: fmt.Sprintf("The value type specified for these keys %v is invalid", invalidKeys), - Paths: []string{fmt.Sprintf("%s.properties", p.Name)}, + Paths: []string{p.Name + ".properties"}, } } @@ -586,7 +590,7 @@ func validateObjectUsage(ctx context.Context, steps []Step, params []ParamSpec) } // check if the object's key names are referenced correctly i.e. param.objectParam.key1 - errs = errs.Also(validateVariables(ctx, steps, fmt.Sprintf("params\\.%s", p.Name), objectKeys)) + errs = errs.Also(validateVariables(ctx, steps, "params\\."+p.Name, objectKeys)) } return errs.Also(validateObjectUsageAsWhole(steps, "params", objectParameterNames)) diff --git a/pkg/apis/pipeline/v1/task_validation_test.go b/pkg/apis/pipeline/v1/task_validation_test.go index e8a1d1f0427..77942ca1751 100644 --- a/pkg/apis/pipeline/v1/task_validation_test.go +++ b/pkg/apis/pipeline/v1/task_validation_test.go @@ -15,6 +15,7 @@ package v1_test import ( "context" + "errors" "fmt" "testing" "time" @@ -755,7 +756,8 @@ func TestTaskValidateError(t *testing.T) { Spec: v1.TaskSpec{ Params: tt.fields.Params, Steps: tt.fields.Steps, - }} + }, + } ctx := cfgtesting.EnableAlphaAPIFields(context.Background()) task.SetDefaults(ctx) err := task.Validate(ctx) @@ -1074,7 +1076,8 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "mystep", Image: "my-image", WorkingDir: "/foo/bar/src/", - }}, + }, + }, }, expectedError: apis.FieldError{ Message: `variable type invalid in "$(params.baz[*])"`, @@ -1419,43 +1422,44 @@ func TestTaskSpecValidateErrorWithStepActionRef_CreateUpdateEvent(t *testing.T) isCreate bool isUpdate bool expectedError apis.FieldError - }{{ - name: "is create ctx", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }{ + { + name: "is create ctx", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + }}, + isCreate: true, + isUpdate: false, + expectedError: apis.FieldError{ + Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", + Paths: []string{"steps[0]"}, }, - }}, - isCreate: true, - isUpdate: false, - expectedError: apis.FieldError{ - Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", - Paths: []string{"steps[0]"}, - }, - }, { - name: "is update ctx", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }, { + name: "is update ctx", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + }}, + isCreate: false, + isUpdate: true, + expectedError: apis.FieldError{ + Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", + Paths: []string{"steps[0]"}, }, - }}, - isCreate: false, - isUpdate: true, - expectedError: apis.FieldError{ - Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", - Paths: []string{"steps[0]"}, + }, { + name: "ctx is not create or update", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + }}, + isCreate: false, + isUpdate: false, + expectedError: apis.FieldError{}, }, - }, { - name: "ctx is not create or update", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", - }, - }}, - isCreate: false, - isUpdate: false, - expectedError: apis.FieldError{}, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1487,123 +1491,124 @@ func TestTaskSpecValidateErrorWithStepActionRef(t *testing.T) { name string Steps []v1.Step expectedError apis.FieldError - }{{ - name: "Cannot use image with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", - }, - Image: "foo", - }}, - expectedError: apis.FieldError{ - Message: "image cannot be used with Ref", - Paths: []string{"steps[0].image"}, - }, - }, { - name: "Cannot use command with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }{ + { + name: "Cannot use image with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Image: "foo", + }}, + expectedError: apis.FieldError{ + Message: "image cannot be used with Ref", + Paths: []string{"steps[0].image"}, }, - Command: []string{"foo"}, - }}, - expectedError: apis.FieldError{ - Message: "command cannot be used with Ref", - Paths: []string{"steps[0].command"}, - }, - }, { - name: "Cannot use args with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }, { + name: "Cannot use command with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Command: []string{"foo"}, + }}, + expectedError: apis.FieldError{ + Message: "command cannot be used with Ref", + Paths: []string{"steps[0].command"}, }, - Args: []string{"foo"}, - }}, - expectedError: apis.FieldError{ - Message: "args cannot be used with Ref", - Paths: []string{"steps[0].args"}, - }, - }, { - name: "Cannot use script with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }, { + name: "Cannot use args with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Args: []string{"foo"}, + }}, + expectedError: apis.FieldError{ + Message: "args cannot be used with Ref", + Paths: []string{"steps[0].args"}, }, - Script: "echo hi", - }}, - expectedError: apis.FieldError{ - Message: "script cannot be used with Ref", - Paths: []string{"steps[0].script"}, - }, - }, { - name: "Cannot use workingDir with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }, { + name: "Cannot use script with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Script: "echo hi", + }}, + expectedError: apis.FieldError{ + Message: "script cannot be used with Ref", + Paths: []string{"steps[0].script"}, }, - WorkingDir: "/workspace", - }}, - expectedError: apis.FieldError{ - Message: "working dir cannot be used with Ref", - Paths: []string{"steps[0].workingDir"}, - }, - }, { - name: "Cannot use env with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + }, { + name: "Cannot use workingDir with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + WorkingDir: "/workspace", + }}, + expectedError: apis.FieldError{ + Message: "working dir cannot be used with Ref", + Paths: []string{"steps[0].workingDir"}, }, - Env: []corev1.EnvVar{{ - Name: "env1", - Value: "value1", + }, { + name: "Cannot use env with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Env: []corev1.EnvVar{{ + Name: "env1", + Value: "value1", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "env cannot be used with Ref", - Paths: []string{"steps[0].env"}, - }, - }, { - name: "Cannot use params without Ref", - Steps: []v1.Step{{ - Image: "my-image", - Params: v1.Params{{ - Name: "param", + expectedError: apis.FieldError{ + Message: "env cannot be used with Ref", + Paths: []string{"steps[0].env"}, + }, + }, { + name: "Cannot use params without Ref", + Steps: []v1.Step{{ + Image: "my-image", + Params: v1.Params{{ + Name: "param", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "params cannot be used without Ref", - Paths: []string{"steps[0].params"}, - }, - }, { - name: "Cannot use volumeMounts with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + expectedError: apis.FieldError{ + Message: "params cannot be used without Ref", + Paths: []string{"steps[0].params"}, }, - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(params.foo)", - MountPath: "/registry-config", + }, { + name: "Cannot use volumeMounts with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.foo)", + MountPath: "/registry-config", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "volumeMounts cannot be used with Ref", - Paths: []string{"steps[0].volumeMounts"}, - }, - }, { - name: "Cannot use results with Ref", - Steps: []v1.Step{{ - Ref: &v1.Ref{ - Name: "stepAction", + expectedError: apis.FieldError{ + Message: "volumeMounts cannot be used with Ref", + Paths: []string{"steps[0].volumeMounts"}, }, - Results: []v1.StepResult{{ - Name: "result", + }, { + name: "Cannot use results with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Results: []v1.StepResult{{ + Name: "result", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "results cannot be used with Ref", - Paths: []string{"steps[0].results"}, + expectedError: apis.FieldError{ + Message: "results cannot be used with Ref", + Paths: []string{"steps[0].results"}, + }, }, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1633,85 +1638,86 @@ func TestTaskSpecValidateErrorWithStepResultRef(t *testing.T) { name string Steps []v1.Step expectedError apis.FieldError - }{{ - name: "Cannot reference step results in image", - Steps: []v1.Step{{ - Image: "$(steps.prevStep.results.resultName)", - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].image"}, - }, - }, { - name: "Cannot reference step results in script", - Steps: []v1.Step{{ - Image: "my-img", - Script: "echo $(steps.prevStep.results.resultName)", - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].script"}, - }, - }, { - name: "Cannot reference step results in workingDir", - Steps: []v1.Step{{ - Image: "my-img", - WorkingDir: "$(steps.prevStep.results.resultName)", - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].workingDir"}, - }, - }, { - name: "Cannot reference step results in envFrom", - Steps: []v1.Step{{ - Image: "my-img", - EnvFrom: []corev1.EnvFromSource{{ - Prefix: "$(steps.prevStep.results.resultName)", - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(steps.prevStep.results.resultName)", + }{ + { + name: "Cannot reference step results in image", + Steps: []v1.Step{{ + Image: "$(steps.prevStep.results.resultName)", + }}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].image"}, + }, + }, { + name: "Cannot reference step results in script", + Steps: []v1.Step{{ + Image: "my-img", + Script: "echo $(steps.prevStep.results.resultName)", + }}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].script"}, + }, + }, { + name: "Cannot reference step results in workingDir", + Steps: []v1.Step{{ + Image: "my-img", + WorkingDir: "$(steps.prevStep.results.resultName)", + }}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].workingDir"}, + }, + }, { + name: "Cannot reference step results in envFrom", + Steps: []v1.Step{{ + Image: "my-img", + EnvFrom: []corev1.EnvFromSource{{ + Prefix: "$(steps.prevStep.results.resultName)", + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(steps.prevStep.results.resultName)", + }, }, - }, - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(steps.prevStep.results.resultName)", + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(steps.prevStep.results.resultName)", + }, }, - }, + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].envFrom.configMapRef", "steps[0].envFrom.prefix", "steps[0].envFrom.secretRef"}, - }, - }, { - name: "Cannot reference step results in VolumeMounts", - Steps: []v1.Step{{ - Image: "my-img", - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(steps.prevStep.results.resultName)", - MountPath: "$(steps.prevStep.results.resultName)", - SubPath: "$(steps.prevStep.results.resultName)", + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].envFrom.configMapRef", "steps[0].envFrom.prefix", "steps[0].envFrom.secretRef"}, + }, + }, { + name: "Cannot reference step results in VolumeMounts", + Steps: []v1.Step{{ + Image: "my-img", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(steps.prevStep.results.resultName)", + MountPath: "$(steps.prevStep.results.resultName)", + SubPath: "$(steps.prevStep.results.resultName)", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].volumeMounts.name", "steps[0].volumeMounts.mountPath", "steps[0].volumeMounts.subPath"}, - }, - }, { - name: "Cannot reference step results in VolumeDevices", - Steps: []v1.Step{{ - Image: "my-img", - VolumeDevices: []corev1.VolumeDevice{{ - Name: "$(steps.prevStep.results.resultName)", - DevicePath: "$(steps.prevStep.results.resultName)", + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].volumeMounts.name", "steps[0].volumeMounts.mountPath", "steps[0].volumeMounts.subPath"}, + }, + }, { + name: "Cannot reference step results in VolumeDevices", + Steps: []v1.Step{{ + Image: "my-img", + VolumeDevices: []corev1.VolumeDevice{{ + Name: "$(steps.prevStep.results.resultName)", + DevicePath: "$(steps.prevStep.results.resultName)", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].volumeDevices.name", "steps[0].volumeDevices.devicePath"}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].volumeDevices.name", "steps[0].volumeDevices.devicePath"}, + }, }, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1735,6 +1741,7 @@ func TestTaskSpecValidateErrorWithStepResultRef(t *testing.T) { }) } } + func TestTaskSpecValidateErrorSidecars(t *testing.T) { tests := []struct { name string @@ -2013,70 +2020,72 @@ func TestIncompatibleAPIVersions(t *testing.T) { name string requiredVersion string spec v1.TaskSpec - }{{ - name: "step workspace requires beta", - requiredVersion: "beta", - spec: v1.TaskSpec{ - Workspaces: []v1.WorkspaceDeclaration{{ - Name: "foo", - }}, - Steps: []v1.Step{{ - Image: "foo", - Workspaces: []v1.WorkspaceUsage{{ + }{ + { + name: "step workspace requires beta", + requiredVersion: "beta", + spec: v1.TaskSpec{ + Workspaces: []v1.WorkspaceDeclaration{{ Name: "foo", }}, - }}, - }, - }, { - name: "sidecar workspace requires beta", - requiredVersion: "beta", - spec: v1.TaskSpec{ - Workspaces: []v1.WorkspaceDeclaration{{ - Name: "foo", - }}, - Steps: []v1.Step{{ - Image: "foo", - }}, - Sidecars: []v1.Sidecar{{ - Image: "foo", - Workspaces: []v1.WorkspaceUsage{{ + Steps: []v1.Step{{ + Image: "foo", + Workspaces: []v1.WorkspaceUsage{{ + Name: "foo", + }}, + }}, + }, + }, { + name: "sidecar workspace requires beta", + requiredVersion: "beta", + spec: v1.TaskSpec{ + Workspaces: []v1.WorkspaceDeclaration{{ Name: "foo", }}, - }}, - }, - }, { - name: "windows script support requires alpha", - requiredVersion: "alpha", - spec: v1.TaskSpec{ - Steps: []v1.Step{{ - Image: "my-image", - Script: ` + Steps: []v1.Step{{ + Image: "foo", + }}, + Sidecars: []v1.Sidecar{{ + Image: "foo", + Workspaces: []v1.WorkspaceUsage{{ + Name: "foo", + }}, + }}, + }, + }, { + name: "windows script support requires alpha", + requiredVersion: "alpha", + spec: v1.TaskSpec{ + Steps: []v1.Step{{ + Image: "my-image", + Script: ` #!win powershell -File script-1`, - }}, - }, - }, { - name: "stdout stream support requires alpha", - requiredVersion: "alpha", - spec: v1.TaskSpec{ - Steps: []v1.Step{{ - Image: "foo", - StdoutConfig: &v1.StepOutputConfig{ - Path: "/tmp/stdout.txt", - }, - }}, + }}, + }, + }, { + name: "stdout stream support requires alpha", + requiredVersion: "alpha", + spec: v1.TaskSpec{ + Steps: []v1.Step{{ + Image: "foo", + StdoutConfig: &v1.StepOutputConfig{ + Path: "/tmp/stdout.txt", + }, + }}, + }, + }, { + name: "stderr stream support requires alpha", + requiredVersion: "alpha", + spec: v1.TaskSpec{ + Steps: []v1.Step{{ + Image: "foo", + StderrConfig: &v1.StepOutputConfig{ + Path: "/tmp/stderr.txt", + }, + }}, + }, }, - }, { - name: "stderr stream support requires alpha", - requiredVersion: "alpha", - spec: v1.TaskSpec{ - Steps: []v1.Step{{ - Image: "foo", - StderrConfig: &v1.StepOutputConfig{ - Path: "/tmp/stderr.txt", - }, - }}, - }}, } { for _, version := range versions { testName := fmt.Sprintf("(using %s) %s", version, tt.name) @@ -2290,161 +2299,165 @@ func TestGetArrayIndexParamRefs(t *testing.T) { name string taskspec *v1.TaskSpec want sets.String - }{{ - name: "steps reference", - taskspec: &v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "array-params", - Default: v1.NewStructuredValues("bar", "foo"), - }}, - Steps: []v1.Step{{ - Name: "$(params.array-params[10])", - Image: "$(params.array-params[11])", - Command: []string{"$(params.array-params[12])"}, - Args: []string{"$(params.array-params[13])"}, - Script: "echo $(params.array-params[14])", - Env: []corev1.EnvVar{{ - Value: "$(params.array-params[15])", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - Key: "$(params.array-params[16])", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[17])", + }{ + { + name: "steps reference", + taskspec: &v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "array-params", + Default: v1.NewStructuredValues("bar", "foo"), + }}, + Steps: []v1.Step{{ + Name: "$(params.array-params[10])", + Image: "$(params.array-params[11])", + Command: []string{"$(params.array-params[12])"}, + Args: []string{"$(params.array-params[13])"}, + Script: "echo $(params.array-params[14])", + Env: []corev1.EnvVar{{ + Value: "$(params.array-params[15])", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "$(params.array-params[16])", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[17])", + }, + }, + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + Key: "$(params.array-params[18])", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[19])", + }, }, }, - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - Key: "$(params.array-params[18])", + }}, + EnvFrom: []corev1.EnvFromSource{{ + Prefix: "$(params.array-params[20])", + ConfigMapRef: &corev1.ConfigMapEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[19])", + Name: "$(params.array-params[21])", }, }, - }, - }}, - EnvFrom: []corev1.EnvFromSource{{ - Prefix: "$(params.array-params[20])", - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[21])", - }, - }, - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[22])", + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[22])", + }, }, - }, - }}, - WorkingDir: "$(params.array-params[23])", - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(params.array-params[24])", - MountPath: "$(params.array-params[25])", - SubPath: "$(params.array-params[26])", + }}, + WorkingDir: "$(params.array-params[23])", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.array-params[24])", + MountPath: "$(params.array-params[25])", + SubPath: "$(params.array-params[26])", + }}, }}, - }}, - StepTemplate: &v1.StepTemplate{ - Image: "$(params.array-params[27])", + StepTemplate: &v1.StepTemplate{ + Image: "$(params.array-params[27])", + }, }, - }, - want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", - "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", - "$(params.array-params[21])", "$(params.array-params[22])", "$(params.array-params[23])", "$(params.array-params[24])", "$(params.array-params[25])", "$(params.array-params[26])", "$(params.array-params[27])"), - }, { - name: "stepTemplate reference", - taskspec: &v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "array-params", - Default: v1.NewStructuredValues("bar", "foo"), - }}, - StepTemplate: &v1.StepTemplate{ - Image: "$(params.array-params[3])", + want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", + "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", + "$(params.array-params[21])", "$(params.array-params[22])", "$(params.array-params[23])", "$(params.array-params[24])", "$(params.array-params[25])", "$(params.array-params[26])", "$(params.array-params[27])"), + }, { + name: "stepTemplate reference", + taskspec: &v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "array-params", + Default: v1.NewStructuredValues("bar", "foo"), + }}, + StepTemplate: &v1.StepTemplate{ + Image: "$(params.array-params[3])", + }, }, - }, - want: sets.NewString("$(params.array-params[3])"), - }, { - name: "volumes references", - taskspec: &v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "array-params", - Default: v1.NewStructuredValues("bar", "foo"), - }}, - Volumes: []corev1.Volume{{ - Name: "$(params.array-params[10])", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[11])", - }, - Items: []corev1.KeyToPath{{ - Key: "$(params.array-params[12])", - Path: "$(params.array-params[13])", - }, - }, - }, - Secret: &corev1.SecretVolumeSource{ - SecretName: "$(params.array-params[14])", - Items: []corev1.KeyToPath{{ - Key: "$(params.array-params[15])", - Path: "$(params.array-params[16])", - }}, - }, - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: "$(params.array-params[17])", - }, - Projected: &corev1.ProjectedVolumeSource{ - Sources: []corev1.VolumeProjection{{ - ConfigMap: &corev1.ConfigMapProjection{ + want: sets.NewString("$(params.array-params[3])"), + }, { + name: "volumes references", + taskspec: &v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "array-params", + Default: v1.NewStructuredValues("bar", "foo"), + }}, + Volumes: []corev1.Volume{ + { + Name: "$(params.array-params[10])", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[18])", + Name: "$(params.array-params[11])", }, - }, - Secret: &corev1.SecretProjection{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[19])", + Items: []corev1.KeyToPath{ + { + Key: "$(params.array-params[12])", + Path: "$(params.array-params[13])", + }, }, }, - ServiceAccountToken: &corev1.ServiceAccountTokenProjection{ - Audience: "$(params.array-params[20])", + Secret: &corev1.SecretVolumeSource{ + SecretName: "$(params.array-params[14])", + Items: []corev1.KeyToPath{{ + Key: "$(params.array-params[15])", + Path: "$(params.array-params[16])", + }}, + }, + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: "$(params.array-params[17])", + }, + Projected: &corev1.ProjectedVolumeSource{ + Sources: []corev1.VolumeProjection{{ + ConfigMap: &corev1.ConfigMapProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[18])", + }, + }, + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[19])", + }, + }, + ServiceAccountToken: &corev1.ServiceAccountTokenProjection{ + Audience: "$(params.array-params[20])", + }, + }}, + }, + CSI: &corev1.CSIVolumeSource{ + NodePublishSecretRef: &corev1.LocalObjectReference{ + Name: "$(params.array-params[21])", + }, + VolumeAttributes: map[string]string{"key": "$(params.array-params[22])"}, }, - }}, - }, - CSI: &corev1.CSIVolumeSource{ - NodePublishSecretRef: &corev1.LocalObjectReference{ - Name: "$(params.array-params[21])", }, - VolumeAttributes: map[string]string{"key": "$(params.array-params[22])"}, }, }, }, + want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", + "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", + "$(params.array-params[21])", "$(params.array-params[22])"), + }, { + name: "workspaces references", + taskspec: &v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "array-params", + Default: v1.NewStructuredValues("bar", "foo"), + }}, + Workspaces: []v1.WorkspaceDeclaration{{ + MountPath: "$(params.array-params[3])", + }}, }, - }, - want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", - "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", - "$(params.array-params[21])", "$(params.array-params[22])"), - }, { - name: "workspaces references", - taskspec: &v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "array-params", - Default: v1.NewStructuredValues("bar", "foo"), - }}, - Workspaces: []v1.WorkspaceDeclaration{{ - MountPath: "$(params.array-params[3])", - }}, - }, - want: sets.NewString("$(params.array-params[3])"), - }, { - name: "sidecar references", - taskspec: &v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "array-params", - Default: v1.NewStructuredValues("bar", "foo"), - }}, - Sidecars: []v1.Sidecar{{ - Script: "$(params.array-params[3])", - }, + want: sets.NewString("$(params.array-params[3])"), + }, { + name: "sidecar references", + taskspec: &v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "array-params", + Default: v1.NewStructuredValues("bar", "foo"), + }}, + Sidecars: []v1.Sidecar{ + { + Script: "$(params.array-params[3])", + }, + }, }, + want: sets.NewString("$(params.array-params[3])"), }, - want: sets.NewString("$(params.array-params[3])"), - }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { @@ -2514,7 +2527,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("param default value v4 not in the enum list: params[param1]"), + expectedErr: errors.New("param default value v4 not in the enum list: params[param1]"), }, { name: "param enum with array type - failure", params: []v1.ParamSpec{{ @@ -2525,7 +2538,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("enum can only be set with string type param: params[param1]"), + expectedErr: errors.New("enum can only be set with string type param: params[param1]"), }, { name: "param enum with object type - failure", params: []v1.ParamSpec{{ @@ -2536,7 +2549,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("enum can only be set with string type param: params[param1]"), + expectedErr: errors.New("enum can only be set with string type param: params[param1]"), }, { name: "param enum with duplicate values - failure", params: []v1.ParamSpec{{ @@ -2547,7 +2560,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("parameter enum value v1 appears more than once: params[param1]"), + expectedErr: errors.New("parameter enum value v1 appears more than once: params[param1]"), }, { name: "param enum with feature flag disabled - failure", params: []v1.ParamSpec{{ @@ -2558,7 +2571,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "false", }, - expectedErr: fmt.Errorf("feature flag `enable-param-enum` should be set to true to use Enum: params[param1]"), + expectedErr: errors.New("feature flag `enable-param-enum` should be set to true to use Enum: params[param1]"), }} for _, tc := range tcs { diff --git a/pkg/apis/pipeline/v1/taskref_validation.go b/pkg/apis/pipeline/v1/taskref_validation.go index 1a743e6dac6..4f4e0330350 100644 --- a/pkg/apis/pipeline/v1/taskref_validation.go +++ b/pkg/apis/pipeline/v1/taskref_validation.go @@ -29,7 +29,7 @@ import ( // correctly. No errors are returned for a nil TaskRef. func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { - return + return errs } switch { diff --git a/pkg/apis/pipeline/v1/taskrun_types.go b/pkg/apis/pipeline/v1/taskrun_types.go index 51bb5426a47..d2d017a0f95 100644 --- a/pkg/apis/pipeline/v1/taskrun_types.go +++ b/pkg/apis/pipeline/v1/taskrun_types.go @@ -15,7 +15,6 @@ package v1 import ( "context" - "fmt" "time" "github.com/tektoncd/pipeline/pkg/apis/config" @@ -408,7 +407,7 @@ func (tr *TaskRun) GetPipelineRunPVCName() string { } for _, ref := range tr.GetOwnerReferences() { if ref.Kind == pipeline.PipelineRunControllerName { - return fmt.Sprintf("%s-pvc", ref.Name) + return ref.Name + "-pvc" } } return "" diff --git a/pkg/apis/pipeline/v1/taskrun_validation.go b/pkg/apis/pipeline/v1/taskrun_validation.go index e9bf1c17f6e..8fbaa7309ab 100644 --- a/pkg/apis/pipeline/v1/taskrun_validation.go +++ b/pkg/apis/pipeline/v1/taskrun_validation.go @@ -32,8 +32,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*TaskRun)(nil) -var _ resourcesemantics.VerbLimited = (*TaskRun)(nil) +var ( + _ apis.Validatable = (*TaskRun)(nil) + _ resourcesemantics.VerbLimited = (*TaskRun)(nil) +) // SupportedVerbs returns the operations that validation should be called for func (tr *TaskRun) SupportedVerbs() []admissionregistrationv1.OperationType { @@ -100,7 +102,7 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { if ts.Timeout != nil { // timeout should be a valid duration of at least 0. if ts.Timeout.Duration < 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s should be >= 0", ts.Timeout.Duration.String()), "timeout")) + errs = errs.Also(apis.ErrInvalidValue(ts.Timeout.Duration.String()+" should be >= 0", "timeout")) } } @@ -189,14 +191,14 @@ func combineParamSpec(p ParamSpec, paramSpecForValidation map[string]ParamSpec) } // If Default values of object type are provided then Properties must also be fully declared. if p.Properties == nil { - return paramSpecForValidation, apis.ErrMissingField(fmt.Sprintf("%s.properties", p.Name)) + return paramSpecForValidation, apis.ErrMissingField(p.Name + ".properties") } } // Properties must be defined if paramSpec is of object Type if pSpec.Type == ParamTypeObject { if p.Properties == nil { - return paramSpecForValidation, apis.ErrMissingField(fmt.Sprintf("%s.properties", p.Name)) + return paramSpecForValidation, apis.ErrMissingField(p.Name + ".properties") } // Expect Properties to be complete pSpec.Properties = p.Properties @@ -217,7 +219,7 @@ func validateDebug(db *TaskRunDebug) (errs *apis.FieldError) { return errs } if db.Breakpoints.OnFailure != "" && db.Breakpoints.OnFailure != EnabledOnFailureBreakpoint { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s is not a valid onFailure breakpoint value, onFailure breakpoint is only allowed to be set as enabled", db.Breakpoints.OnFailure), "breakpoints.onFailure")) + errs = errs.Also(apis.ErrInvalidValue(db.Breakpoints.OnFailure+" is not a valid onFailure breakpoint value, onFailure breakpoint is only allowed to be set as enabled", "breakpoints.onFailure")) } return errs } diff --git a/pkg/apis/pipeline/v1/taskrun_validation_test.go b/pkg/apis/pipeline/v1/taskrun_validation_test.go index e418256c042..0006256b6ac 100644 --- a/pkg/apis/pipeline/v1/taskrun_validation_test.go +++ b/pkg/apis/pipeline/v1/taskrun_validation_test.go @@ -18,7 +18,6 @@ package v1_test import ( "context" - "fmt" "testing" "time" @@ -575,7 +574,7 @@ func TestTaskRunSpec_Invalidate(t *testing.T) { }, StatusMessage: v1.TaskRunSpecStatusMessage(invalidStatusMessage), }, - wantErr: apis.ErrInvalidValue(fmt.Sprintf("statusMessage should not be set if status is not set, but it is currently set to %s", invalidStatusMessage), "statusMessage"), + wantErr: apis.ErrInvalidValue("statusMessage should not be set if status is not set, but it is currently set to "+invalidStatusMessage, "statusMessage"), }, { name: "invalid taskspec", spec: v1.TaskRunSpec{ diff --git a/pkg/apis/pipeline/v1alpha1/run_validation_test.go b/pkg/apis/pipeline/v1alpha1/run_validation_test.go index 9bd3d932ed9..feb19e6ec21 100644 --- a/pkg/apis/pipeline/v1alpha1/run_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/run_validation_test.go @@ -18,7 +18,6 @@ package v1alpha1_test import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" @@ -159,7 +158,7 @@ func TestRun_Invalid(t *testing.T) { StatusMessage: v1alpha1.RunSpecStatusMessage(invalidStatusMessage), }, }, - want: apis.ErrInvalidValue(fmt.Sprintf("statusMessage should not be set if status is not set, but it is currently set to %s", invalidStatusMessage), "statusMessage"), + want: apis.ErrInvalidValue("statusMessage should not be set if status is not set, but it is currently set to "+invalidStatusMessage, "statusMessage"), }, { name: "non-unique params", run: &v1alpha1.Run{ diff --git a/pkg/apis/pipeline/v1alpha1/stepaction_types.go b/pkg/apis/pipeline/v1alpha1/stepaction_types.go index 2e90321b142..c685f4b5cd5 100644 --- a/pkg/apis/pipeline/v1alpha1/stepaction_types.go +++ b/pkg/apis/pipeline/v1alpha1/stepaction_types.go @@ -106,7 +106,7 @@ type StepActionSpec struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // Script is the contents of an executable file to execute. // // If Script is not empty, the Step cannot have an Command and the Args will be passed to the Script. @@ -139,7 +139,7 @@ type StepActionSpec struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` } // ToStep converts the StepActionSpec to a Step struct diff --git a/pkg/apis/pipeline/v1alpha1/stepaction_validation.go b/pkg/apis/pipeline/v1alpha1/stepaction_validation.go index a9c6ebed0e6..f61d137978a 100644 --- a/pkg/apis/pipeline/v1alpha1/stepaction_validation.go +++ b/pkg/apis/pipeline/v1alpha1/stepaction_validation.go @@ -15,7 +15,6 @@ package v1alpha1 import ( "context" - "fmt" "strings" "github.com/tektoncd/pipeline/pkg/apis/config" @@ -29,8 +28,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*StepAction)(nil) -var _ resourcesemantics.VerbLimited = (*StepAction)(nil) +var ( + _ apis.Validatable = (*StepAction)(nil) + _ resourcesemantics.VerbLimited = (*StepAction)(nil) +) // SupportedVerbs returns the operations that validation should be called for func (s *StepAction) SupportedVerbs() []admissionregistrationv1.OperationType { @@ -144,7 +145,7 @@ func validateObjectUsage(ctx context.Context, sas StepActionSpec, params v1.Para } // check if the object's key names are referenced correctly i.e. param.objectParam.key1 - errs = errs.Also(validateStepActionVariables(ctx, sas, fmt.Sprintf("params\\.%s", p.Name), objectKeys)) + errs = errs.Also(validateStepActionVariables(ctx, sas, "params\\."+p.Name, objectKeys)) } return errs.Also(validateStepActionObjectUsageAsWhole(sas, "params", objectParameterNames)) diff --git a/pkg/apis/pipeline/v1beta1/container_types.go b/pkg/apis/pipeline/v1beta1/container_types.go index 2b2cf7901aa..4494184d7aa 100644 --- a/pkg/apis/pipeline/v1beta1/container_types.go +++ b/pkg/apis/pipeline/v1beta1/container_types.go @@ -75,7 +75,7 @@ type Step struct { // +listType=map // +listMapKey=containerPort // +listMapKey=protocol - DeprecatedPorts []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + DeprecatedPorts []corev1.ContainerPort `json:"ports,omitempty" patchMergeKey:"containerPort" patchStrategy:"merge" protobuf:"bytes,6,rep,name=ports"` // List of sources to populate environment variables in the container. // The keys defined within a source must be a C_IDENTIFIER. All invalid keys // will be reported as an event when the container is starting. When a key exists in multiple @@ -91,7 +91,7 @@ type Step struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // Compute Resources required by this Step. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ @@ -103,13 +103,13 @@ type Step struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` // volumeDevices is the list of block devices to be used by the Step. // +patchMergeKey=devicePath // +patchStrategy=merge // +optional // +listType=atomic - VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchMergeKey:"devicePath" patchStrategy:"merge" protobuf:"bytes,21,rep,name=volumeDevices"` // Periodic probe of container liveness. // Step will be restarted if the probe fails. // Cannot be updated. @@ -389,7 +389,7 @@ type StepTemplate struct { // +listType=map // +listMapKey=containerPort // +listMapKey=protocol - DeprecatedPorts []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + DeprecatedPorts []corev1.ContainerPort `json:"ports,omitempty" patchMergeKey:"containerPort" patchStrategy:"merge" protobuf:"bytes,6,rep,name=ports"` // List of sources to populate environment variables in the Step. // The keys defined within a source must be a C_IDENTIFIER. All invalid keys // will be reported as an event when the container is starting. When a key exists in multiple @@ -405,7 +405,7 @@ type StepTemplate struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // Compute Resources required by this Step. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ @@ -417,13 +417,13 @@ type StepTemplate struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` // volumeDevices is the list of block devices to be used by the Step. // +patchMergeKey=devicePath // +patchStrategy=merge // +optional // +listType=atomic - VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchMergeKey:"devicePath" patchStrategy:"merge" protobuf:"bytes,21,rep,name=volumeDevices"` // Periodic probe of container liveness. // Container will be restarted if the probe fails. // Cannot be updated. @@ -616,7 +616,7 @@ type Sidecar struct { // +listType=map // +listMapKey=containerPort // +listMapKey=protocol - Ports []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + Ports []corev1.ContainerPort `json:"ports,omitempty" patchMergeKey:"containerPort" patchStrategy:"merge" protobuf:"bytes,6,rep,name=ports"` // List of sources to populate environment variables in the Sidecar. // The keys defined within a source must be a C_IDENTIFIER. All invalid keys // will be reported as an event when the Sidecar is starting. When a key exists in multiple @@ -632,7 +632,7 @@ type Sidecar struct { // +patchMergeKey=name // +patchStrategy=merge // +listType=atomic - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` // Compute Resources required by this Sidecar. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ @@ -644,13 +644,13 @@ type Sidecar struct { // +patchMergeKey=mountPath // +patchStrategy=merge // +listType=atomic - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` // volumeDevices is the list of block devices to be used by the Sidecar. // +patchMergeKey=devicePath // +patchStrategy=merge // +optional // +listType=atomic - VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchMergeKey:"devicePath" patchStrategy:"merge" protobuf:"bytes,21,rep,name=volumeDevices"` // Periodic probe of Sidecar liveness. // Container will be restarted if the probe fails. // Cannot be updated. diff --git a/pkg/apis/pipeline/v1beta1/container_validation.go b/pkg/apis/pipeline/v1beta1/container_validation.go index de7319da67b..bab6f8bc4d5 100644 --- a/pkg/apis/pipeline/v1beta1/container_validation.go +++ b/pkg/apis/pipeline/v1beta1/container_validation.go @@ -29,7 +29,7 @@ import ( // correctly. No errors are returned for a nil Ref. func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { - return + return errs } switch { diff --git a/pkg/apis/pipeline/v1beta1/customrun_validation_test.go b/pkg/apis/pipeline/v1beta1/customrun_validation_test.go index 169f99df1c5..30f1dc514dd 100644 --- a/pkg/apis/pipeline/v1beta1/customrun_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/customrun_validation_test.go @@ -18,7 +18,6 @@ package v1beta1_test import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" @@ -158,7 +157,7 @@ func TestCustomRun_Invalid(t *testing.T) { StatusMessage: v1beta1.CustomRunSpecStatusMessage(invalidStatusMessage), }, }, - want: apis.ErrInvalidValue(fmt.Sprintf("statusMessage should not be set if status is not set, but it is currently set to %s", invalidStatusMessage), "statusMessage"), + want: apis.ErrInvalidValue("statusMessage should not be set if status is not set, but it is currently set to "+invalidStatusMessage, "statusMessage"), }, { name: "non-unique params", customRun: &v1beta1.CustomRun{ diff --git a/pkg/apis/pipeline/v1beta1/merge.go b/pkg/apis/pipeline/v1beta1/merge.go index c34bb13e0ae..42d9ffa868c 100644 --- a/pkg/apis/pipeline/v1beta1/merge.go +++ b/pkg/apis/pipeline/v1beta1/merge.go @@ -77,6 +77,7 @@ func MergeStepsWithOverrides(steps []Step, overrides []TaskRunStepOverride) ([]S stepNameToOverride[o.Name] = o } for i, s := range steps { + s := s o, found := stepNameToOverride[s.Name] if !found { continue @@ -103,6 +104,7 @@ func MergeSidecarsWithOverrides(sidecars []Sidecar, overrides []TaskRunSidecarOv sidecarNameToOverride[o.Name] = o } for i, s := range sidecars { + s := s o, found := sidecarNameToOverride[s.Name] if !found { continue diff --git a/pkg/apis/pipeline/v1beta1/param_types_test.go b/pkg/apis/pipeline/v1beta1/param_types_test.go index d9985e8ddd0..8f15dae7545 100644 --- a/pkg/apis/pipeline/v1beta1/param_types_test.go +++ b/pkg/apis/pipeline/v1beta1/param_types_test.go @@ -307,6 +307,7 @@ type ParamValuesHolder struct { AOrS v1beta1.ParamValue `json:"val"` } +//nolint:musttag func TestParamValues_UnmarshalJSON(t *testing.T) { cases := []struct { input map[string]interface{} @@ -397,6 +398,7 @@ func TestParamValues_UnmarshalJSON_Directly(t *testing.T) { } } +//nolint:musttag func TestParamValues_UnmarshalJSON_Error(t *testing.T) { cases := []struct { desc string @@ -414,6 +416,7 @@ func TestParamValues_UnmarshalJSON_Error(t *testing.T) { } } +//nolint:musttag func TestParamValues_MarshalJSON(t *testing.T) { cases := []struct { input v1beta1.ParamValue @@ -501,7 +504,8 @@ func TestExtractNames(t *testing.T) { params: v1beta1.Params{{ Name: "IMAGE", Value: v1beta1.ParamValue{Type: v1beta1.ParamTypeString, StringVal: "image-1"}, }, { - Name: "DOCKERFILE", Value: v1beta1.ParamValue{Type: v1beta1.ParamTypeString, StringVal: "path/to/Dockerfile1"}}}, + Name: "DOCKERFILE", Value: v1beta1.ParamValue{Type: v1beta1.ParamTypeString, StringVal: "path/to/Dockerfile1"}, + }}, want: sets.NewString("IMAGE", "DOCKERFILE"), }, { name: "extract param names from ParamTypeArray", diff --git a/pkg/apis/pipeline/v1beta1/pipeline_validation.go b/pkg/apis/pipeline/v1beta1/pipeline_validation.go index 85d3312c596..ac5b5c5c797 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_validation.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_validation.go @@ -35,8 +35,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*Pipeline)(nil) -var _ resourcesemantics.VerbLimited = (*Pipeline)(nil) +var ( + _ apis.Validatable = (*Pipeline)(nil) + _ resourcesemantics.VerbLimited = (*Pipeline)(nil) +) const ( taskRef = "taskRef" @@ -539,8 +541,8 @@ func (pt *PipelineTask) validateExecutionStatusVariablesDisallowed() (errs *apis func validateContainsExecutionStatusVariablesDisallowed(expressions []string, path string) (errs *apis.FieldError) { if containsExecutionStatusReferences(expressions) { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("pipeline tasks can not refer to execution status"+ - " of any other pipeline task or aggregate status of tasks"), path)) + errs = errs.Also(apis.ErrInvalidValue("pipeline tasks can not refer to execution status"+ + " of any other pipeline task or aggregate status of tasks", path)) } return errs } @@ -796,7 +798,7 @@ func validateMatrixedPipelineTaskConsumed(expressions []string, taskMapping map[ taskConsumed := taskMapping[pipelineTask] if taskConsumed.IsMatrixed() { if !strings.HasSuffix(expression, "[*]") { - errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("A matrixed pipelineTask can only be consumed in aggregate using [*] notation, but is currently set to %s", expression))) + errs = errs.Also(apis.ErrGeneric("A matrixed pipelineTask can only be consumed in aggregate using [*] notation, but is currently set to " + expression)) } filteredExpressions = append(filteredExpressions, expression) } diff --git a/pkg/apis/pipeline/v1beta1/pipelineref_validation.go b/pkg/apis/pipeline/v1beta1/pipelineref_validation.go index 7131f6c62f5..a0b7e02f18b 100644 --- a/pkg/apis/pipeline/v1beta1/pipelineref_validation.go +++ b/pkg/apis/pipeline/v1beta1/pipelineref_validation.go @@ -29,7 +29,7 @@ import ( // correctly. No errors are returned for a nil PipelineRef. func (ref *PipelineRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { - return + return errs } if ref.Resolver != "" || ref.Params != nil { diff --git a/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go b/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go index 10799ed1732..f7c434eb7b4 100644 --- a/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go +++ b/pkg/apis/pipeline/v1beta1/pipelinerun_validation.go @@ -31,8 +31,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*PipelineRun)(nil) -var _ resourcesemantics.VerbLimited +var ( + _ apis.Validatable = (*PipelineRun)(nil) + _ resourcesemantics.VerbLimited +) // SupportedVerbs returns the operations that validation should be called for func (pr *PipelineRun) SupportedVerbs() []admissionregistrationv1.OperationType { @@ -85,7 +87,7 @@ func (ps *PipelineRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) if ps.Timeout != nil { // timeout should be a valid duration of at least 0. if ps.Timeout.Duration < 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s should be >= 0", ps.Timeout.Duration.String()), "timeout")) + errs = errs.Also(apis.ErrInvalidValue(ps.Timeout.Duration.String()+" should be >= 0", "timeout")) } } @@ -279,8 +281,8 @@ func validateSpecStatus(status PipelineRunSpecStatus) *apis.FieldError { func validateTimeoutDuration(field string, d *metav1.Duration) (errs *apis.FieldError) { if d != nil && d.Duration < 0 { - fieldPath := fmt.Sprintf("timeouts.%s", field) - return errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s should be >= 0", d.Duration.String()), fieldPath)) + fieldPath := "timeouts." + field + return errs.Also(apis.ErrInvalidValue(d.Duration.String()+" should be >= 0", fieldPath)) } return nil } diff --git a/pkg/apis/pipeline/v1beta1/result_validation.go b/pkg/apis/pipeline/v1beta1/result_validation.go index deadbd53497..2416276316f 100644 --- a/pkg/apis/pipeline/v1beta1/result_validation.go +++ b/pkg/apis/pipeline/v1beta1/result_validation.go @@ -47,7 +47,7 @@ func (tr TaskResult) Validate(ctx context.Context) (errs *apis.FieldError) { // for Properties values it will check if the type is string. func validateObjectResult(tr TaskResult) (errs *apis.FieldError) { if ParamType(tr.Type) == ParamTypeObject && tr.Properties == nil { - return apis.ErrMissingField(fmt.Sprintf("%s.properties", tr.Name)) + return apis.ErrMissingField(tr.Name + ".properties") } invalidKeys := []string{} @@ -60,7 +60,7 @@ func validateObjectResult(tr TaskResult) (errs *apis.FieldError) { if len(invalidKeys) != 0 { return &apis.FieldError{ Message: fmt.Sprintf("The value type specified for these keys %v is invalid, the type must be string", invalidKeys), - Paths: []string{fmt.Sprintf("%s.properties", tr.Name)}, + Paths: []string{tr.Name + ".properties"}, } } return nil @@ -81,7 +81,7 @@ func (tr TaskResult) validateValue(ctx context.Context) (errs *apis.FieldError) Message: fmt.Sprintf( "Invalid Type. Wanted string but got: \"%v\"", tr.Value.Type), Paths: []string{ - fmt.Sprintf("%s.type", tr.Name), + tr.Name + ".type", }, } } @@ -90,20 +90,20 @@ func (tr TaskResult) validateValue(ctx context.Context) (errs *apis.FieldError) if err != nil { return &apis.FieldError{ Message: err.Error(), - Paths: []string{fmt.Sprintf("%s.value", tr.Name)}, + Paths: []string{tr.Name + ".value"}, } } if e := validation.IsDNS1123Label(stepName); len(e) > 0 { errs = errs.Also(&apis.FieldError{ Message: fmt.Sprintf("invalid extracted step name %q", stepName), - Paths: []string{fmt.Sprintf("%s.value", tr.Name)}, + Paths: []string{tr.Name + ".value"}, Details: "stepName in $(steps..results.) must be a valid DNS Label, For more info refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", }) } if !resultNameFormatRegex.MatchString(resultName) { errs = errs.Also(&apis.FieldError{ Message: fmt.Sprintf("invalid extracted result name %q", resultName), - Paths: []string{fmt.Sprintf("%s.value", tr.Name)}, + Paths: []string{tr.Name + ".value"}, Details: fmt.Sprintf("resultName in $(steps..results.) must consist of alphanumeric characters, '-', '_', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my-name', or 'my_name', regex used for validation is '%s')", ResultNameFormat), }) } diff --git a/pkg/apis/pipeline/v1beta1/task_conversion.go b/pkg/apis/pipeline/v1beta1/task_conversion.go index 0c3df76ed3b..4c026e10b60 100644 --- a/pkg/apis/pipeline/v1beta1/task_conversion.go +++ b/pkg/apis/pipeline/v1beta1/task_conversion.go @@ -19,6 +19,7 @@ package v1beta1 import ( "context" "encoding/json" + "errors" "fmt" "github.com/tektoncd/pipeline/pkg/apis/version" @@ -208,7 +209,7 @@ func serializeTaskDeprecations(meta *metav1.ObjectMeta, spec *TaskSpec, taskName if spec.HasDeprecatedFields() { taskDeprecation = retrieveTaskDeprecation(spec) } - var existingDeprecations = taskDeprecations{} + existingDeprecations := taskDeprecations{} if str, ok := meta.Annotations[TaskDeprecationsAnnotationKey]; ok { if err := json.Unmarshal([]byte(str), &existingDeprecations); err != nil { return fmt.Errorf("error deserializing key %s from metadata: %w", TaskDeprecationsAnnotationKey, err) @@ -224,7 +225,7 @@ func serializeTaskDeprecations(meta *metav1.ObjectMeta, spec *TaskSpec, taskName // deserializeTaskDeprecations retrieves deprecation info of the Task from object annotation. // The object could be Task, TaskRun, Pipeline or PipelineRun. func deserializeTaskDeprecations(meta *metav1.ObjectMeta, spec *TaskSpec, taskName string) error { - var existingDeprecations = taskDeprecations{} + existingDeprecations := taskDeprecations{} if meta == nil || meta.Annotations == nil { return nil } @@ -235,7 +236,7 @@ func deserializeTaskDeprecations(meta *metav1.ObjectMeta, spec *TaskSpec, taskNa } if td, ok := existingDeprecations[taskName]; ok { if len(spec.Steps) != len(td.DeprecatedSteps) { - return fmt.Errorf("length of deserialized steps mismatch the length of target steps") + return errors.New("length of deserialized steps mismatch the length of target steps") } for i := 0; i < len(spec.Steps); i++ { spec.Steps[i].DeprecatedPorts = td.DeprecatedSteps[i].DeprecatedPorts diff --git a/pkg/apis/pipeline/v1beta1/task_validation.go b/pkg/apis/pipeline/v1beta1/task_validation.go index 3c26d5bf0fe..3b1fd1f7b31 100644 --- a/pkg/apis/pipeline/v1beta1/task_validation.go +++ b/pkg/apis/pipeline/v1beta1/task_validation.go @@ -50,16 +50,20 @@ const ( objectVariableNameFormat = "^[_a-zA-Z][_a-zA-Z0-9-]*$" ) -var _ apis.Validatable = (*Task)(nil) -var _ resourcesemantics.VerbLimited = (*Task)(nil) +var ( + _ apis.Validatable = (*Task)(nil) + _ resourcesemantics.VerbLimited = (*Task)(nil) +) // SupportedVerbs returns the operations that validation should be called for func (t *Task) SupportedVerbs() []admissionregistrationv1.OperationType { return []admissionregistrationv1.OperationType{admissionregistrationv1.Create, admissionregistrationv1.Update} } -var stringAndArrayVariableNameFormatRegex = regexp.MustCompile(stringAndArrayVariableNameFormat) -var objectVariableNameFormatRegex = regexp.MustCompile(objectVariableNameFormat) +var ( + stringAndArrayVariableNameFormatRegex = regexp.MustCompile(stringAndArrayVariableNameFormat) + objectVariableNameFormatRegex = regexp.MustCompile(objectVariableNameFormat) +) // Validate implements apis.Validatable func (t *Task) Validate(ctx context.Context) *apis.FieldError { @@ -117,7 +121,7 @@ func validateObjectParamsHaveProperties(ctx context.Context, params ParamSpecs) var errs *apis.FieldError for _, p := range params { if p.Type == ParamTypeObject && p.Properties == nil { - errs = errs.Also(apis.ErrMissingField(fmt.Sprintf("%s.properties", p.Name))) + errs = errs.Also(apis.ErrMissingField(p.Name + ".properties")) } } return errs @@ -482,7 +486,7 @@ func (p ParamSpec) ValidateType(ctx context.Context) *apis.FieldError { } } if !validType { - return apis.ErrInvalidValue(p.Type, fmt.Sprintf("%s.type", p.Name)) + return apis.ErrInvalidValue(p.Type, p.Name+".type") } // If a default value is provided, ensure its type matches param's declared type. @@ -491,8 +495,8 @@ func (p ParamSpec) ValidateType(ctx context.Context) *apis.FieldError { Message: fmt.Sprintf( "\"%v\" type does not match default value's type: \"%v\"", p.Type, p.Default.Type), Paths: []string{ - fmt.Sprintf("%s.type", p.Name), - fmt.Sprintf("%s.default.type", p.Name), + p.Name + ".type", + p.Name + ".default.type", }, } } @@ -515,7 +519,7 @@ func (p ParamSpec) ValidateObjectType(ctx context.Context) *apis.FieldError { if len(invalidKeys) != 0 { return &apis.FieldError{ Message: fmt.Sprintf("The value type specified for these keys %v is invalid", invalidKeys), - Paths: []string{fmt.Sprintf("%s.properties", p.Name)}, + Paths: []string{p.Name + ".properties"}, } } @@ -575,7 +579,7 @@ func validateObjectUsage(ctx context.Context, steps []Step, params []ParamSpec) } // check if the object's key names are referenced correctly i.e. param.objectParam.key1 - errs = errs.Also(validateVariables(ctx, steps, fmt.Sprintf("params\\.%s", p.Name), objectKeys)) + errs = errs.Also(validateVariables(ctx, steps, "params\\."+p.Name, objectKeys)) } return errs.Also(validateObjectUsageAsWhole(steps, "params", objectParameterNames)) diff --git a/pkg/apis/pipeline/v1beta1/task_validation_test.go b/pkg/apis/pipeline/v1beta1/task_validation_test.go index 6d5729617d5..02694dc5418 100644 --- a/pkg/apis/pipeline/v1beta1/task_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/task_validation_test.go @@ -18,6 +18,7 @@ package v1beta1_test import ( "context" + "errors" "fmt" "testing" "time" @@ -759,7 +760,8 @@ func TestTaskValidateError(t *testing.T) { Spec: v1beta1.TaskSpec{ Params: tt.fields.Params, Steps: tt.fields.Steps, - }} + }, + } ctx := cfgtesting.EnableAlphaAPIFields(context.Background()) task.SetDefaults(ctx) err := task.Validate(ctx) @@ -1079,7 +1081,8 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "mystep", Image: "my-image", WorkingDir: "/foo/bar/src/", - }}, + }, + }, }, expectedError: apis.FieldError{ Message: `variable type invalid in "$(params.baz[*])"`, @@ -1432,43 +1435,44 @@ func TestTaskSpecValidateErrorWithStepActionRef_CreateUpdateEvent(t *testing.T) isCreate bool isUpdate bool expectedError apis.FieldError - }{{ - name: "is create ctx", - Steps: []v1beta1.Step{{ - Ref: &v1beta1.Ref{ - Name: "stepAction", + }{ + { + name: "is create ctx", + Steps: []v1beta1.Step{{ + Ref: &v1beta1.Ref{ + Name: "stepAction", + }, + }}, + isCreate: true, + isUpdate: false, + expectedError: apis.FieldError{ + Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", + Paths: []string{"steps[0]"}, }, - }}, - isCreate: true, - isUpdate: false, - expectedError: apis.FieldError{ - Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", - Paths: []string{"steps[0]"}, - }, - }, { - name: "is update ctx", - Steps: []v1beta1.Step{{ - Ref: &v1beta1.Ref{ - Name: "stepAction", + }, { + name: "is update ctx", + Steps: []v1beta1.Step{{ + Ref: &v1beta1.Ref{ + Name: "stepAction", + }, + }}, + isCreate: false, + isUpdate: true, + expectedError: apis.FieldError{ + Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", + Paths: []string{"steps[0]"}, }, - }}, - isCreate: false, - isUpdate: true, - expectedError: apis.FieldError{ - Message: "feature flag enable-step-actions should be set to true to reference StepActions in Steps.", - Paths: []string{"steps[0]"}, + }, { + name: "ctx is not create or update", + Steps: []v1beta1.Step{{ + Ref: &v1beta1.Ref{ + Name: "stepAction", + }, + }}, + isCreate: false, + isUpdate: false, + expectedError: apis.FieldError{}, }, - }, { - name: "ctx is not create or update", - Steps: []v1beta1.Step{{ - Ref: &v1beta1.Ref{ - Name: "stepAction", - }, - }}, - isCreate: false, - isUpdate: false, - expectedError: apis.FieldError{}, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1644,85 +1648,86 @@ func TestTaskSpecValidateErrorWithStepResultRef(t *testing.T) { name string Steps []v1beta1.Step expectedError apis.FieldError - }{{ - name: "Cannot reference step results in image", - Steps: []v1beta1.Step{{ - Image: "$(steps.prevStep.results.resultName)", - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].image"}, - }, - }, { - name: "Cannot reference step results in script", - Steps: []v1beta1.Step{{ - Image: "my-img", - Script: "echo $(steps.prevStep.results.resultName)", - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].script"}, - }, - }, { - name: "Cannot reference step results in workingDir", - Steps: []v1beta1.Step{{ - Image: "my-img", - WorkingDir: "$(steps.prevStep.results.resultName)", - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].workingDir"}, - }, - }, { - name: "Cannot reference step results in envFrom", - Steps: []v1beta1.Step{{ - Image: "my-img", - EnvFrom: []corev1.EnvFromSource{{ - Prefix: "$(steps.prevStep.results.resultName)", - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(steps.prevStep.results.resultName)", + }{ + { + name: "Cannot reference step results in image", + Steps: []v1beta1.Step{{ + Image: "$(steps.prevStep.results.resultName)", + }}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].image"}, + }, + }, { + name: "Cannot reference step results in script", + Steps: []v1beta1.Step{{ + Image: "my-img", + Script: "echo $(steps.prevStep.results.resultName)", + }}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].script"}, + }, + }, { + name: "Cannot reference step results in workingDir", + Steps: []v1beta1.Step{{ + Image: "my-img", + WorkingDir: "$(steps.prevStep.results.resultName)", + }}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].workingDir"}, + }, + }, { + name: "Cannot reference step results in envFrom", + Steps: []v1beta1.Step{{ + Image: "my-img", + EnvFrom: []corev1.EnvFromSource{{ + Prefix: "$(steps.prevStep.results.resultName)", + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(steps.prevStep.results.resultName)", + }, }, - }, - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(steps.prevStep.results.resultName)", + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(steps.prevStep.results.resultName)", + }, }, - }, + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].envFrom.configMapRef", "steps[0].envFrom.prefix", "steps[0].envFrom.secretRef"}, - }, - }, { - name: "Cannot reference step results in VolumeMounts", - Steps: []v1beta1.Step{{ - Image: "my-img", - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(steps.prevStep.results.resultName)", - MountPath: "$(steps.prevStep.results.resultName)", - SubPath: "$(steps.prevStep.results.resultName)", + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].envFrom.configMapRef", "steps[0].envFrom.prefix", "steps[0].envFrom.secretRef"}, + }, + }, { + name: "Cannot reference step results in VolumeMounts", + Steps: []v1beta1.Step{{ + Image: "my-img", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(steps.prevStep.results.resultName)", + MountPath: "$(steps.prevStep.results.resultName)", + SubPath: "$(steps.prevStep.results.resultName)", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].volumeMounts.name", "steps[0].volumeMounts.mountPath", "steps[0].volumeMounts.subPath"}, - }, - }, { - name: "Cannot reference step results in VolumeDevices", - Steps: []v1beta1.Step{{ - Image: "my-img", - VolumeDevices: []corev1.VolumeDevice{{ - Name: "$(steps.prevStep.results.resultName)", - DevicePath: "$(steps.prevStep.results.resultName)", + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].volumeMounts.name", "steps[0].volumeMounts.mountPath", "steps[0].volumeMounts.subPath"}, + }, + }, { + name: "Cannot reference step results in VolumeDevices", + Steps: []v1beta1.Step{{ + Image: "my-img", + VolumeDevices: []corev1.VolumeDevice{{ + Name: "$(steps.prevStep.results.resultName)", + DevicePath: "$(steps.prevStep.results.resultName)", + }}, }}, - }}, - expectedError: apis.FieldError{ - Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", - Paths: []string{"steps[0].volumeDevices.name", "steps[0].volumeDevices.devicePath"}, + expectedError: apis.FieldError{ + Message: "stepResult substitutions are only allowed in env, command and args. Found usage in", + Paths: []string{"steps[0].volumeDevices.name", "steps[0].volumeDevices.devicePath"}, + }, }, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1976,70 +1981,72 @@ func TestIncompatibleAPIVersions(t *testing.T) { name string requiredVersion string spec v1beta1.TaskSpec - }{{ - name: "step workspace requires beta", - requiredVersion: "beta", - spec: v1beta1.TaskSpec{ - Workspaces: []v1beta1.WorkspaceDeclaration{{ - Name: "foo", - }}, - Steps: []v1beta1.Step{{ - Image: "foo", - Workspaces: []v1beta1.WorkspaceUsage{{ + }{ + { + name: "step workspace requires beta", + requiredVersion: "beta", + spec: v1beta1.TaskSpec{ + Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "foo", }}, - }}, - }, - }, { - name: "sidecar workspace requires beta", - requiredVersion: "beta", - spec: v1beta1.TaskSpec{ - Workspaces: []v1beta1.WorkspaceDeclaration{{ - Name: "foo", - }}, - Steps: []v1beta1.Step{{ - Image: "foo", - }}, - Sidecars: []v1beta1.Sidecar{{ - Image: "foo", - Workspaces: []v1beta1.WorkspaceUsage{{ + Steps: []v1beta1.Step{{ + Image: "foo", + Workspaces: []v1beta1.WorkspaceUsage{{ + Name: "foo", + }}, + }}, + }, + }, { + name: "sidecar workspace requires beta", + requiredVersion: "beta", + spec: v1beta1.TaskSpec{ + Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "foo", }}, - }}, - }, - }, { - name: "windows script support requires alpha", - requiredVersion: "alpha", - spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{ - Image: "my-image", - Script: ` + Steps: []v1beta1.Step{{ + Image: "foo", + }}, + Sidecars: []v1beta1.Sidecar{{ + Image: "foo", + Workspaces: []v1beta1.WorkspaceUsage{{ + Name: "foo", + }}, + }}, + }, + }, { + name: "windows script support requires alpha", + requiredVersion: "alpha", + spec: v1beta1.TaskSpec{ + Steps: []v1beta1.Step{{ + Image: "my-image", + Script: ` #!win powershell -File script-1`, - }}, - }, - }, { - name: "stdout stream support requires alpha", - requiredVersion: "alpha", - spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{ - Image: "foo", - StdoutConfig: &v1beta1.StepOutputConfig{ - Path: "/tmp/stdout.txt", - }, - }}, + }}, + }, + }, { + name: "stdout stream support requires alpha", + requiredVersion: "alpha", + spec: v1beta1.TaskSpec{ + Steps: []v1beta1.Step{{ + Image: "foo", + StdoutConfig: &v1beta1.StepOutputConfig{ + Path: "/tmp/stdout.txt", + }, + }}, + }, + }, { + name: "stderr stream support requires alpha", + requiredVersion: "alpha", + spec: v1beta1.TaskSpec{ + Steps: []v1beta1.Step{{ + Image: "foo", + StderrConfig: &v1beta1.StepOutputConfig{ + Path: "/tmp/stderr.txt", + }, + }}, + }, }, - }, { - name: "stderr stream support requires alpha", - requiredVersion: "alpha", - spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{ - Image: "foo", - StderrConfig: &v1beta1.StepOutputConfig{ - Path: "/tmp/stderr.txt", - }, - }}, - }}, } { for _, version := range versions { testName := fmt.Sprintf("(using %s) %s", version, tt.name) @@ -2077,161 +2084,165 @@ func TestGetArrayIndexParamRefs(t *testing.T) { name string taskspec *v1beta1.TaskSpec want sets.String - }{{ - name: "steps reference", - taskspec: &v1beta1.TaskSpec{ - Params: []v1beta1.ParamSpec{{ - Name: "array-params", - Default: v1beta1.NewStructuredValues("bar", "foo"), - }}, - Steps: []v1beta1.Step{{ - Name: "$(params.array-params[10])", - Image: "$(params.array-params[11])", - Command: []string{"$(params.array-params[12])"}, - Args: []string{"$(params.array-params[13])"}, - Script: "echo $(params.array-params[14])", - Env: []corev1.EnvVar{{ - Value: "$(params.array-params[15])", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - Key: "$(params.array-params[16])", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[17])", + }{ + { + name: "steps reference", + taskspec: &v1beta1.TaskSpec{ + Params: []v1beta1.ParamSpec{{ + Name: "array-params", + Default: v1beta1.NewStructuredValues("bar", "foo"), + }}, + Steps: []v1beta1.Step{{ + Name: "$(params.array-params[10])", + Image: "$(params.array-params[11])", + Command: []string{"$(params.array-params[12])"}, + Args: []string{"$(params.array-params[13])"}, + Script: "echo $(params.array-params[14])", + Env: []corev1.EnvVar{{ + Value: "$(params.array-params[15])", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "$(params.array-params[16])", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[17])", + }, + }, + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + Key: "$(params.array-params[18])", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[19])", + }, }, }, - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - Key: "$(params.array-params[18])", + }}, + EnvFrom: []corev1.EnvFromSource{{ + Prefix: "$(params.array-params[20])", + ConfigMapRef: &corev1.ConfigMapEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[19])", + Name: "$(params.array-params[21])", }, }, - }, - }}, - EnvFrom: []corev1.EnvFromSource{{ - Prefix: "$(params.array-params[20])", - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[21])", - }, - }, - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[22])", + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[22])", + }, }, - }, - }}, - WorkingDir: "$(params.array-params[23])", - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(params.array-params[24])", - MountPath: "$(params.array-params[25])", - SubPath: "$(params.array-params[26])", + }}, + WorkingDir: "$(params.array-params[23])", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.array-params[24])", + MountPath: "$(params.array-params[25])", + SubPath: "$(params.array-params[26])", + }}, }}, - }}, - StepTemplate: &v1beta1.StepTemplate{ - Image: "$(params.array-params[27])", + StepTemplate: &v1beta1.StepTemplate{ + Image: "$(params.array-params[27])", + }, }, - }, - want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", - "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", - "$(params.array-params[21])", "$(params.array-params[22])", "$(params.array-params[23])", "$(params.array-params[24])", "$(params.array-params[25])", "$(params.array-params[26])", "$(params.array-params[27])"), - }, { - name: "stepTemplate reference", - taskspec: &v1beta1.TaskSpec{ - Params: []v1beta1.ParamSpec{{ - Name: "array-params", - Default: v1beta1.NewStructuredValues("bar", "foo"), - }}, - StepTemplate: &v1beta1.StepTemplate{ - Image: "$(params.array-params[3])", + want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", + "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", + "$(params.array-params[21])", "$(params.array-params[22])", "$(params.array-params[23])", "$(params.array-params[24])", "$(params.array-params[25])", "$(params.array-params[26])", "$(params.array-params[27])"), + }, { + name: "stepTemplate reference", + taskspec: &v1beta1.TaskSpec{ + Params: []v1beta1.ParamSpec{{ + Name: "array-params", + Default: v1beta1.NewStructuredValues("bar", "foo"), + }}, + StepTemplate: &v1beta1.StepTemplate{ + Image: "$(params.array-params[3])", + }, }, - }, - want: sets.NewString("$(params.array-params[3])"), - }, { - name: "volumes references", - taskspec: &v1beta1.TaskSpec{ - Params: []v1beta1.ParamSpec{{ - Name: "array-params", - Default: v1beta1.NewStructuredValues("bar", "foo"), - }}, - Volumes: []corev1.Volume{{ - Name: "$(params.array-params[10])", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[11])", - }, - Items: []corev1.KeyToPath{{ - Key: "$(params.array-params[12])", - Path: "$(params.array-params[13])", - }, - }, - }, - Secret: &corev1.SecretVolumeSource{ - SecretName: "$(params.array-params[14])", - Items: []corev1.KeyToPath{{ - Key: "$(params.array-params[15])", - Path: "$(params.array-params[16])", - }}, - }, - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: "$(params.array-params[17])", - }, - Projected: &corev1.ProjectedVolumeSource{ - Sources: []corev1.VolumeProjection{{ - ConfigMap: &corev1.ConfigMapProjection{ + want: sets.NewString("$(params.array-params[3])"), + }, { + name: "volumes references", + taskspec: &v1beta1.TaskSpec{ + Params: []v1beta1.ParamSpec{{ + Name: "array-params", + Default: v1beta1.NewStructuredValues("bar", "foo"), + }}, + Volumes: []corev1.Volume{ + { + Name: "$(params.array-params[10])", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[18])", + Name: "$(params.array-params[11])", }, - }, - Secret: &corev1.SecretProjection{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(params.array-params[19])", + Items: []corev1.KeyToPath{ + { + Key: "$(params.array-params[12])", + Path: "$(params.array-params[13])", + }, }, }, - ServiceAccountToken: &corev1.ServiceAccountTokenProjection{ - Audience: "$(params.array-params[20])", + Secret: &corev1.SecretVolumeSource{ + SecretName: "$(params.array-params[14])", + Items: []corev1.KeyToPath{{ + Key: "$(params.array-params[15])", + Path: "$(params.array-params[16])", + }}, + }, + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: "$(params.array-params[17])", + }, + Projected: &corev1.ProjectedVolumeSource{ + Sources: []corev1.VolumeProjection{{ + ConfigMap: &corev1.ConfigMapProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[18])", + }, + }, + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(params.array-params[19])", + }, + }, + ServiceAccountToken: &corev1.ServiceAccountTokenProjection{ + Audience: "$(params.array-params[20])", + }, + }}, + }, + CSI: &corev1.CSIVolumeSource{ + NodePublishSecretRef: &corev1.LocalObjectReference{ + Name: "$(params.array-params[21])", + }, + VolumeAttributes: map[string]string{"key": "$(params.array-params[22])"}, }, - }}, - }, - CSI: &corev1.CSIVolumeSource{ - NodePublishSecretRef: &corev1.LocalObjectReference{ - Name: "$(params.array-params[21])", }, - VolumeAttributes: map[string]string{"key": "$(params.array-params[22])"}, }, }, }, + want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", + "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", + "$(params.array-params[21])", "$(params.array-params[22])"), + }, { + name: "workspaces references", + taskspec: &v1beta1.TaskSpec{ + Params: []v1beta1.ParamSpec{{ + Name: "array-params", + Default: v1beta1.NewStructuredValues("bar", "foo"), + }}, + Workspaces: []v1beta1.WorkspaceDeclaration{{ + MountPath: "$(params.array-params[3])", + }}, }, - }, - want: sets.NewString("$(params.array-params[10])", "$(params.array-params[11])", "$(params.array-params[12])", "$(params.array-params[13])", "$(params.array-params[14])", - "$(params.array-params[15])", "$(params.array-params[16])", "$(params.array-params[17])", "$(params.array-params[18])", "$(params.array-params[19])", "$(params.array-params[20])", - "$(params.array-params[21])", "$(params.array-params[22])"), - }, { - name: "workspaces references", - taskspec: &v1beta1.TaskSpec{ - Params: []v1beta1.ParamSpec{{ - Name: "array-params", - Default: v1beta1.NewStructuredValues("bar", "foo"), - }}, - Workspaces: []v1beta1.WorkspaceDeclaration{{ - MountPath: "$(params.array-params[3])", - }}, - }, - want: sets.NewString("$(params.array-params[3])"), - }, { - name: "sidecar references", - taskspec: &v1beta1.TaskSpec{ - Params: []v1beta1.ParamSpec{{ - Name: "array-params", - Default: v1beta1.NewStructuredValues("bar", "foo"), - }}, - Sidecars: []v1beta1.Sidecar{{ - Script: "$(params.array-params[3])", - }, + want: sets.NewString("$(params.array-params[3])"), + }, { + name: "sidecar references", + taskspec: &v1beta1.TaskSpec{ + Params: []v1beta1.ParamSpec{{ + Name: "array-params", + Default: v1beta1.NewStructuredValues("bar", "foo"), + }}, + Sidecars: []v1beta1.Sidecar{ + { + Script: "$(params.array-params[3])", + }, + }, }, + want: sets.NewString("$(params.array-params[3])"), }, - want: sets.NewString("$(params.array-params[3])"), - }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { @@ -2301,7 +2312,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("param default value v4 not in the enum list: params[param1]"), + expectedErr: errors.New("param default value v4 not in the enum list: params[param1]"), }, { name: "param enum with array type - failure", params: []v1beta1.ParamSpec{{ @@ -2312,7 +2323,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("enum can only be set with string type param: params[param1]"), + expectedErr: errors.New("enum can only be set with string type param: params[param1]"), }, { name: "param enum with object type - failure", params: []v1beta1.ParamSpec{{ @@ -2323,7 +2334,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("enum can only be set with string type param: params[param1]"), + expectedErr: errors.New("enum can only be set with string type param: params[param1]"), }, { name: "param enum with duplicate values - failure", params: []v1beta1.ParamSpec{{ @@ -2334,7 +2345,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "true", }, - expectedErr: fmt.Errorf("parameter enum value v1 appears more than once: params[param1]"), + expectedErr: errors.New("parameter enum value v1 appears more than once: params[param1]"), }, { name: "param enum with feature flag disabled - failure", params: []v1beta1.ParamSpec{{ @@ -2345,7 +2356,7 @@ func TestParamEnum_Failure(t *testing.T) { configMap: map[string]string{ "enable-param-enum": "false", }, - expectedErr: fmt.Errorf("feature flag `enable-param-enum` should be set to true to use Enum: params[param1]"), + expectedErr: errors.New("feature flag `enable-param-enum` should be set to true to use Enum: params[param1]"), }} for _, tc := range tcs { diff --git a/pkg/apis/pipeline/v1beta1/taskref_validation.go b/pkg/apis/pipeline/v1beta1/taskref_validation.go index a8bbe480ae8..a3e2bb036c3 100644 --- a/pkg/apis/pipeline/v1beta1/taskref_validation.go +++ b/pkg/apis/pipeline/v1beta1/taskref_validation.go @@ -30,7 +30,7 @@ import ( // correctly. No errors are returned for a nil TaskRef. func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { - return + return errs } switch { diff --git a/pkg/apis/pipeline/v1beta1/taskrun_types.go b/pkg/apis/pipeline/v1beta1/taskrun_types.go index c4b1e7f8249..4d6e13ee544 100644 --- a/pkg/apis/pipeline/v1beta1/taskrun_types.go +++ b/pkg/apis/pipeline/v1beta1/taskrun_types.go @@ -18,7 +18,6 @@ package v1beta1 import ( "context" - "fmt" "time" "github.com/tektoncd/pipeline/pkg/apis/config" @@ -456,7 +455,7 @@ func (tr *TaskRun) GetPipelineRunPVCName() string { } for _, ref := range tr.GetOwnerReferences() { if ref.Kind == pipeline.PipelineRunControllerName { - return fmt.Sprintf("%s-pvc", ref.Name) + return ref.Name + "-pvc" } } return "" diff --git a/pkg/apis/pipeline/v1beta1/taskrun_validation.go b/pkg/apis/pipeline/v1beta1/taskrun_validation.go index e5108a6464c..8dd96f0ef99 100644 --- a/pkg/apis/pipeline/v1beta1/taskrun_validation.go +++ b/pkg/apis/pipeline/v1beta1/taskrun_validation.go @@ -32,8 +32,10 @@ import ( "knative.dev/pkg/webhook/resourcesemantics" ) -var _ apis.Validatable = (*TaskRun)(nil) -var _ resourcesemantics.VerbLimited = (*TaskRun)(nil) +var ( + _ apis.Validatable = (*TaskRun)(nil) + _ resourcesemantics.VerbLimited = (*TaskRun)(nil) +) // SupportedVerbs returns the operations that validation should be called for func (tr *TaskRun) SupportedVerbs() []admissionregistrationv1.OperationType { @@ -100,7 +102,7 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) (errs *apis.FieldError) { if ts.Timeout != nil { // timeout should be a valid duration of at least 0. if ts.Timeout.Duration < 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s should be >= 0", ts.Timeout.Duration.String()), "timeout")) + errs = errs.Also(apis.ErrInvalidValue(ts.Timeout.Duration.String()+" should be >= 0", "timeout")) } } if ts.PodTemplate != nil { @@ -191,14 +193,14 @@ func combineParamSpec(p ParamSpec, paramSpecForValidation map[string]ParamSpec) } // If Default values of object type are provided then Properties must also be fully declared. if p.Properties == nil { - return paramSpecForValidation, apis.ErrMissingField(fmt.Sprintf("%s.properties", p.Name)) + return paramSpecForValidation, apis.ErrMissingField(p.Name + ".properties") } } // Properties must be defined if paramSpec is of object Type if pSpec.Type == ParamTypeObject { if p.Properties == nil { - return paramSpecForValidation, apis.ErrMissingField(fmt.Sprintf("%s.properties", p.Name)) + return paramSpecForValidation, apis.ErrMissingField(p.Name + ".properties") } // Expect Properties to be complete pSpec.Properties = p.Properties @@ -219,7 +221,7 @@ func validateDebug(db *TaskRunDebug) (errs *apis.FieldError) { return errs } if db.Breakpoints.OnFailure != "" && db.Breakpoints.OnFailure != EnabledOnFailureBreakpoint { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s is not a valid onFailure breakpoint value, onFailure breakpoint is only allowed to be set as enabled", db.Breakpoints.OnFailure), "breakpoints.onFailure")) + errs = errs.Also(apis.ErrInvalidValue(db.Breakpoints.OnFailure+" is not a valid onFailure breakpoint value, onFailure breakpoint is only allowed to be set as enabled", "breakpoints.onFailure")) } return errs } diff --git a/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go b/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go index 6e604fb6e36..3005c14c357 100644 --- a/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go @@ -18,7 +18,6 @@ package v1beta1_test import ( "context" - "fmt" "testing" "time" @@ -68,7 +67,8 @@ func TestTaskRun_Invalidate(t *testing.T) { Value: "false", }}, }, - }}, + }, + }, wc: EnableForbiddenEnv, want: apis.ErrInvalidValue("PodTemplate cannot update a forbidden env: TEST_ENV", "spec.PodTemplate.Env"), }, { @@ -564,7 +564,7 @@ func TestTaskRunSpec_Invalidate(t *testing.T) { }, StatusMessage: v1beta1.TaskRunSpecStatusMessage(invalidStatusMessage), }, - wantErr: apis.ErrInvalidValue(fmt.Sprintf("statusMessage should not be set if status is not set, but it is currently set to %s", invalidStatusMessage), "statusMessage"), + wantErr: apis.ErrInvalidValue("statusMessage should not be set if status is not set, but it is currently set to "+invalidStatusMessage, "statusMessage"), }, { name: "invalid taskspec", spec: v1beta1.TaskRunSpec{ diff --git a/pkg/credentials/dockercreds/creds.go b/pkg/credentials/dockercreds/creds.go index d6a4dd4c31b..3dc805ba7bc 100644 --- a/pkg/credentials/dockercreds/creds.go +++ b/pkg/credentials/dockercreds/creds.go @@ -31,9 +31,11 @@ import ( const annotationPrefix = "tekton.dev/docker-" -var config basicDocker -var dockerConfig arrayArg -var dockerCfg arrayArg +var ( + config basicDocker + dockerConfig arrayArg + dockerCfg arrayArg +) // AddFlags adds CLI flags that dockercreds supports to a given flag.FlagSet. func AddFlags(flagSet *flag.FlagSet) { @@ -154,9 +156,9 @@ func (*basicDockerBuilder) MatchingAnnotations(secret *corev1.Secret) []string { flags = append(flags, fmt.Sprintf("-basic-docker=%s=%s", secret.Name, v)) } case corev1.SecretTypeDockerConfigJson: - flags = append(flags, fmt.Sprintf("-docker-config=%s", secret.Name)) + flags = append(flags, "-docker-config="+secret.Name) case corev1.SecretTypeDockercfg: - flags = append(flags, fmt.Sprintf("-docker-cfg=%s", secret.Name)) + flags = append(flags, "-docker-cfg="+secret.Name) case corev1.SecretTypeOpaque, corev1.SecretTypeServiceAccountToken, corev1.SecretTypeSSHAuth, corev1.SecretTypeTLS, corev1.SecretTypeBootstrapToken: return flags @@ -212,7 +214,7 @@ func (*basicDockerBuilder) Write(directory string) error { if err != nil { return err } - return os.WriteFile(basicDocker, content, 0600) + return os.WriteFile(basicDocker, content, 0o600) } func authsFromDockerCfg(secret string) (map[string]entry, error) { diff --git a/pkg/credentials/dockercreds/creds_test.go b/pkg/credentials/dockercreds/creds_test.go index 2e45d5c8701..e6f9d7d7144 100644 --- a/pkg/credentials/dockercreds/creds_test.go +++ b/pkg/credentials/dockercreds/creds_test.go @@ -18,7 +18,6 @@ package dockercreds import ( "flag" - "fmt" "os" "path/filepath" "testing" @@ -35,10 +34,10 @@ func TestFlagHandling(t *testing.T) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", dir, err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -74,20 +73,20 @@ func TestFlagHandlingTwice(t *testing.T) { if err := os.MkdirAll(fooDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthUsernameKey), []byte("asdf"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthUsernameKey), []byte("asdf"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("blah"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("blah"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } barDir := credentials.VolumeName("bar") if err := os.MkdirAll(barDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", barDir, err) } - if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthUsernameKey), []byte("bleh"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthUsernameKey), []byte("bleh"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthPasswordKey), []byte("belch"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthPasswordKey), []byte("belch"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -138,10 +137,10 @@ func TestFlagHandlingURLCollision(t *testing.T) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", dir, err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -178,7 +177,7 @@ func TestMatchingAnnotations(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "git", Annotations: map[string]string{ - fmt.Sprintf("%s.testkeys", annotationPrefix): "basickeys", + annotationPrefix + ".testkeys": "basickeys", }, }, }, @@ -189,7 +188,7 @@ func TestMatchingAnnotations(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ssh", Annotations: map[string]string{ - fmt.Sprintf("%s.testkeys", annotationPrefix): "keys", + annotationPrefix + ".testkeys": "keys", }, }, }, @@ -200,13 +199,14 @@ func TestMatchingAnnotations(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ssh", Annotations: map[string]string{ - fmt.Sprintf("%s.testkeys1", annotationPrefix): "keys1", - fmt.Sprintf("%s.testkeys2", annotationPrefix): "keys2", - fmt.Sprintf("%s.testkeys3", annotationPrefix): "keys3", + annotationPrefix + ".testkeys1": "keys1", + annotationPrefix + ".testkeys2": "keys2", + annotationPrefix + ".testkeys3": "keys3", }, }, }, - wantFlag: []string{"-basic-docker=ssh=keys1", + wantFlag: []string{ + "-basic-docker=ssh=keys1", "-basic-docker=ssh=keys2", "-basic-docker=ssh=keys3", }, @@ -249,10 +249,10 @@ func TestMultipleFlagHandling(t *testing.T) { if err := os.MkdirAll(fooDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthUsernameKey), []byte("bar"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthUsernameKey), []byte("bar"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("baz"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("baz"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -260,7 +260,7 @@ func TestMultipleFlagHandling(t *testing.T) { if err := os.MkdirAll(barDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", barDir, err) } - if err := os.WriteFile(filepath.Join(barDir, corev1.DockerConfigJsonKey), []byte(`{"auths":{"https://index.docker.io/v1":{"auth":"fooisbar"}}}`), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, corev1.DockerConfigJsonKey), []byte(`{"auths":{"https://index.docker.io/v1":{"auth":"fooisbar"}}}`), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } @@ -268,7 +268,7 @@ func TestMultipleFlagHandling(t *testing.T) { if err := os.MkdirAll(blubbDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", blubbDir, err) } - if err := os.WriteFile(filepath.Join(blubbDir, corev1.DockerConfigJsonKey), []byte(`{"auths":{"us.icr.io":{"auth":"fooisblubb"}}}`), 0777); err != nil { + if err := os.WriteFile(filepath.Join(blubbDir, corev1.DockerConfigJsonKey), []byte(`{"auths":{"us.icr.io":{"auth":"fooisblubb"}}}`), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } @@ -276,7 +276,7 @@ func TestMultipleFlagHandling(t *testing.T) { if err := os.MkdirAll(bazDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", bazDir, err) } - if err := os.WriteFile(filepath.Join(bazDir, corev1.DockerConfigKey), []byte(`{"https://my.registry/v1":{"auth":"fooisbaz"}}`), 0777); err != nil { + if err := os.WriteFile(filepath.Join(bazDir, corev1.DockerConfigKey), []byte(`{"https://my.registry/v1":{"auth":"fooisbaz"}}`), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } @@ -284,7 +284,7 @@ func TestMultipleFlagHandling(t *testing.T) { if err := os.MkdirAll(blaDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", blaDir, err) } - if err := os.WriteFile(filepath.Join(blaDir, corev1.DockerConfigKey), []byte(`{"de.icr.io":{"auth":"fooisbla"}}`), 0777); err != nil { + if err := os.WriteFile(filepath.Join(blaDir, corev1.DockerConfigKey), []byte(`{"de.icr.io":{"auth":"fooisbla"}}`), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } diff --git a/pkg/credentials/gitcreds/creds_test.go b/pkg/credentials/gitcreds/creds_test.go index ef2f6228290..ec5956d3fc3 100644 --- a/pkg/credentials/gitcreds/creds_test.go +++ b/pkg/credentials/gitcreds/creds_test.go @@ -36,10 +36,10 @@ func TestBasicFlagHandling(t *testing.T) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", dir, err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -89,20 +89,20 @@ func TestBasicFlagHandlingTwice(t *testing.T) { if err := os.MkdirAll(fooDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthUsernameKey), []byte("asdf"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthUsernameKey), []byte("asdf"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("blah"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("blah"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } barDir := credentials.VolumeName("bar") if err := os.MkdirAll(barDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", barDir, err) } - if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthUsernameKey), []byte("bleh"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthUsernameKey), []byte("bleh"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthPasswordKey), []byte("belch"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, corev1.BasicAuthPasswordKey), []byte("belch"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -170,10 +170,10 @@ func TestBasicFlagHandlingURLCollision(t *testing.T) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", dir, err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte("bar"), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } @@ -192,10 +192,10 @@ func TestSSHFlagHandling(t *testing.T) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", dir, err) } - if err := os.WriteFile(filepath.Join(dir, corev1.SSHAuthPrivateKey), []byte("bar"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.SSHAuthPrivateKey), []byte("bar"), 0o777); err != nil { t.Fatalf("os.WriteFile(ssh-privatekey) = %v", err) } - if err := os.WriteFile(filepath.Join(dir, "known_hosts"), []byte("ssh-rsa blah"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, "known_hosts"), []byte("ssh-rsa blah"), 0o777); err != nil { t.Fatalf("os.WriteFile(known_hosts) = %v", err) } @@ -253,30 +253,30 @@ func TestSSHFlagHandlingThrice(t *testing.T) { if err := os.MkdirAll(fooDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err) } - if err := os.WriteFile(filepath.Join(fooDir, corev1.SSHAuthPrivateKey), []byte("asdf"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, corev1.SSHAuthPrivateKey), []byte("asdf"), 0o777); err != nil { t.Fatalf("os.WriteFile(ssh-privatekey) = %v", err) } - if err := os.WriteFile(filepath.Join(fooDir, "known_hosts"), []byte("ssh-rsa aaaa"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(fooDir, "known_hosts"), []byte("ssh-rsa aaaa"), 0o777); err != nil { t.Fatalf("os.WriteFile(known_hosts) = %v", err) } barDir := credentials.VolumeName("bar") if err := os.MkdirAll(barDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", barDir, err) } - if err := os.WriteFile(filepath.Join(barDir, corev1.SSHAuthPrivateKey), []byte("bleh"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, corev1.SSHAuthPrivateKey), []byte("bleh"), 0o777); err != nil { t.Fatalf("os.WriteFile(ssh-privatekey) = %v", err) } - if err := os.WriteFile(filepath.Join(barDir, "known_hosts"), []byte("ssh-rsa bbbb"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(barDir, "known_hosts"), []byte("ssh-rsa bbbb"), 0o777); err != nil { t.Fatalf("os.WriteFile(known_hosts) = %v", err) } bazDir := credentials.VolumeName("baz") if err := os.MkdirAll(bazDir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", bazDir, err) } - if err := os.WriteFile(filepath.Join(bazDir, corev1.SSHAuthPrivateKey), []byte("derp"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(bazDir, corev1.SSHAuthPrivateKey), []byte("derp"), 0o777); err != nil { t.Fatalf("os.WriteFile(ssh-privatekey) = %v", err) } - if err := os.WriteFile(filepath.Join(bazDir, "known_hosts"), []byte("ssh-rsa cccc"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(bazDir, "known_hosts"), []byte("ssh-rsa cccc"), 0o777); err != nil { t.Fatalf("os.WriteFile(known_hosts) = %v", err) } @@ -409,7 +409,7 @@ func TestMatchingAnnotations(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "git", Annotations: map[string]string{ - fmt.Sprintf("%s.testkeys", annotationPrefix): "basickeys", + annotationPrefix + ".testkeys": "basickeys", }, }, }, @@ -420,7 +420,7 @@ func TestMatchingAnnotations(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ssh", Annotations: map[string]string{ - fmt.Sprintf("%s.testkeys", annotationPrefix): "keys", + annotationPrefix + ".testkeys": "keys", }, }, }, @@ -431,9 +431,9 @@ func TestMatchingAnnotations(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ssh", Annotations: map[string]string{ - fmt.Sprintf("%s.testkeys1", annotationPrefix): "keys1", - fmt.Sprintf("%s.testkeys2", annotationPrefix): "keys2", - fmt.Sprintf("%s.testkeys3", annotationPrefix): "keys3", + annotationPrefix + ".testkeys1": "keys1", + annotationPrefix + ".testkeys2": "keys2", + annotationPrefix + ".testkeys3": "keys3", }, }, }, @@ -469,10 +469,10 @@ func TestBasicBackslashInUsername(t *testing.T) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { t.Fatalf("os.MkdirAll(%s) = %v", dir, err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte(`foo\bar\banana`), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthUsernameKey), []byte(`foo\bar\banana`), 0o777); err != nil { t.Fatalf("os.WriteFile(username) = %v", err) } - if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0777); err != nil { + if err := os.WriteFile(filepath.Join(dir, corev1.BasicAuthPasswordKey), []byte("baz"), 0o777); err != nil { t.Fatalf("os.WriteFile(password) = %v", err) } diff --git a/pkg/credentials/initialize.go b/pkg/credentials/initialize.go index 4a98d2072ca..4fb839319ec 100644 --- a/pkg/credentials/initialize.go +++ b/pkg/credentials/initialize.go @@ -33,11 +33,11 @@ import ( const ( // credsDirPermissions are the persmission bits assigned to the directories // copied out of the /tekton/creds and into a Step's HOME. - credsDirPermissions = 0700 + credsDirPermissions = 0o700 // credsFilePermissions are the persmission bits assigned to the files // copied out of /tekton/creds and into a Step's HOME. - credsFilePermissions = 0600 + credsFilePermissions = 0o600 ) // CredsInitCredentials is the complete list of credentials that the legacy credentials @@ -53,10 +53,10 @@ type Builder interface { // MatchingAnnotations extracts flags for the credential // helper from the supplied secret and returns a slice (of // length 0 or greater) of applicable domains. - MatchingAnnotations(*corev1.Secret) []string + MatchingAnnotations(secret *corev1.Secret) []string // Write writes the credentials to the provided directory. - Write(string) error + Write(folder string) error } // VolumeName returns the full path to the secret, inside the VolumePath. diff --git a/pkg/credentials/initialize_test.go b/pkg/credentials/initialize_test.go index 1e89b184ab8..f2a1f4ef61a 100644 --- a/pkg/credentials/initialize_test.go +++ b/pkg/credentials/initialize_test.go @@ -28,7 +28,7 @@ func TestTryCopyCredDir(t *testing.T) { dir := t.TempDir() fakeCredDir := filepath.Join(dir, ".docker") - err := os.Mkdir(fakeCredDir, 0700) + err := os.Mkdir(fakeCredDir, 0o700) if err != nil { t.Fatalf("unexpected error creating fake credential directory: %v", err) } @@ -93,11 +93,11 @@ func writeFakeCred(t *testing.T, dir, name, contents string) string { t.Helper() flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC path := filepath.Join(dir, name) - cred, err := os.OpenFile(path, flags, 0600) + cred, err := os.OpenFile(path, flags, 0o600) if err != nil { t.Fatalf("unexpected error writing fake credential: %v", err) } - _, _ = cred.Write([]byte(credContents)) + _, _ = cred.WriteString(contents) _ = cred.Close() return path } diff --git a/pkg/entrypoint/entrypointer.go b/pkg/entrypoint/entrypointer.go index a1d4893c8ee..0be35256b77 100644 --- a/pkg/entrypoint/entrypointer.go +++ b/pkg/entrypoint/entrypointer.go @@ -192,7 +192,7 @@ func (e Entrypointer) Go() error { var err error if e.Timeout != nil && *e.Timeout < time.Duration(0) { - err = fmt.Errorf("negative timeout specified") + err = errors.New("negative timeout specified") } ctx := context.Background() var cancel context.CancelFunc @@ -325,7 +325,7 @@ func (e Entrypointer) BreakpointExitCode(breakpointExitPostFile string) (int, er // WritePostFile write the postfile func (e Entrypointer) WritePostFile(postFile string, err error) { if err != nil && postFile != "" { - postFile = fmt.Sprintf("%s.err", postFile) + postFile += ".err" } if postFile != "" { e.PostWriter.Write(postFile, "") diff --git a/pkg/entrypoint/entrypointer_test.go b/pkg/entrypoint/entrypointer_test.go index 29d3563ef0c..36eb014e8d5 100644 --- a/pkg/entrypoint/entrypointer_test.go +++ b/pkg/entrypoint/entrypointer_test.go @@ -20,13 +20,13 @@ import ( "context" "encoding/json" "errors" - "fmt" "log" "os" "os/exec" "path" "path/filepath" "reflect" + "strconv" "sync" "testing" "time" @@ -237,7 +237,7 @@ func TestEntrypointer(t *testing.T) { if err == nil { var entries []result.RunResult if err := json.Unmarshal(fileContents, &entries); err == nil { - var found = false + found := false for _, result := range entries { if result.Key == "StartedAt" { found = true @@ -265,61 +265,82 @@ func TestReadResultsFromDisk(t *testing.T) { resultContent []v1beta1.ResultValue resultType result.ResultType want []result.RunResult - }{{ - desc: "read string result file", - results: []string{"results"}, - resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello world")}, - resultType: result.TaskRunResultType, - want: []result.RunResult{ - {Value: `"hello world"`, - ResultType: 1}}, - }, { - desc: "read array result file", - results: []string{"results"}, - resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world")}, - resultType: result.TaskRunResultType, - want: []result.RunResult{ - {Value: `["hello","world"]`, - ResultType: 1}}, - }, { - desc: "read string and array result files", - results: []string{"resultsArray", "resultsString"}, - resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world"), *v1beta1.NewStructuredValues("hello world")}, - resultType: result.TaskRunResultType, - want: []result.RunResult{ - {Value: `["hello","world"]`, - ResultType: 1}, - {Value: `"hello world"`, - ResultType: 1}, - }, - }, { - desc: "read string step result file", - results: []string{"results"}, - resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello world")}, - resultType: result.StepResultType, - want: []result.RunResult{ - {Value: `"hello world"`, - ResultType: 4}}, - }, { - desc: "read array step result file", - results: []string{"results"}, - resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world")}, - resultType: result.StepResultType, - want: []result.RunResult{ - {Value: `["hello","world"]`, - ResultType: 4}}, - }, { - desc: "read string and array step result files", - results: []string{"resultsArray", "resultsString"}, - resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world"), *v1beta1.NewStructuredValues("hello world")}, - resultType: result.StepResultType, - want: []result.RunResult{ - {Value: `["hello","world"]`, - ResultType: 4}, - {Value: `"hello world"`, - ResultType: 4}, + }{ + { + desc: "read string result file", + results: []string{"results"}, + resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello world")}, + resultType: result.TaskRunResultType, + want: []result.RunResult{ + { + Value: `"hello world"`, + ResultType: 1, + }, + }, + }, { + desc: "read array result file", + results: []string{"results"}, + resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world")}, + resultType: result.TaskRunResultType, + want: []result.RunResult{ + { + Value: `["hello","world"]`, + ResultType: 1, + }, + }, + }, { + desc: "read string and array result files", + results: []string{"resultsArray", "resultsString"}, + resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world"), *v1beta1.NewStructuredValues("hello world")}, + resultType: result.TaskRunResultType, + want: []result.RunResult{ + { + Value: `["hello","world"]`, + ResultType: 1, + }, + { + Value: `"hello world"`, + ResultType: 1, + }, + }, + }, { + desc: "read string step result file", + results: []string{"results"}, + resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello world")}, + resultType: result.StepResultType, + want: []result.RunResult{ + { + Value: `"hello world"`, + ResultType: 4, + }, + }, + }, { + desc: "read array step result file", + results: []string{"results"}, + resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world")}, + resultType: result.StepResultType, + want: []result.RunResult{ + { + Value: `["hello","world"]`, + ResultType: 4, + }, + }, + }, { + desc: "read string and array step result files", + results: []string{"resultsArray", "resultsString"}, + resultContent: []v1beta1.ResultValue{*v1beta1.NewStructuredValues("hello", "world"), *v1beta1.NewStructuredValues("hello world")}, + resultType: result.StepResultType, + want: []result.RunResult{ + { + Value: `["hello","world"]`, + ResultType: 4, + }, + { + Value: `"hello world"`, + ResultType: 4, + }, + }, }, - }, } { t.Run(c.desc, func(t *testing.T) { ctx := context.Background() @@ -342,7 +363,7 @@ func TestReadResultsFromDisk(t *testing.T) { if err != nil { t.Fatal(err) } - if err := os.WriteFile(resultName, d, 0777); err != nil { + if err := os.WriteFile(resultName, d, 0o777); err != nil { t.Fatal(err) } defer os.Remove(resultName) @@ -383,7 +404,7 @@ func TestEntrypointer_ReadBreakpointExitCodeFromDisk(t *testing.T) { t.Errorf("error while creating temp file for testing exit code written by breakpoint") } // write exit code to file - if err = os.WriteFile(tmp.Name(), []byte(fmt.Sprintf("%d", expectedExitCode)), 0700); err != nil { + if err = os.WriteFile(tmp.Name(), []byte(strconv.Itoa(expectedExitCode)), 0o700); err != nil { t.Errorf("error while writing to temp file create temp file for testing exit code written by breakpoint") } e := Entrypointer{} @@ -772,12 +793,12 @@ func TestApplyStepResultSubstitutions_Env(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { resultPath := filepath.Join(stepDir, pod.GetContainerName(tc.stepName), "results") - err := os.MkdirAll(resultPath, 0750) + err := os.MkdirAll(resultPath, 0o750) if err != nil { log.Fatal(err) } resultFile := filepath.Join(resultPath, tc.resultName) - err = os.WriteFile(resultFile, []byte(tc.result), 0666) + err = os.WriteFile(resultFile, []byte(tc.result), 0o666) if err != nil { log.Fatal(err) } @@ -853,12 +874,12 @@ func TestApplyStepResultSubstitutions_Command(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { resultPath := filepath.Join(stepDir, pod.GetContainerName(tc.stepName), "results") - err := os.MkdirAll(resultPath, 0750) + err := os.MkdirAll(resultPath, 0o750) if err != nil { log.Fatal(err) } resultFile := filepath.Join(resultPath, tc.resultName) - err = os.WriteFile(resultFile, []byte(tc.result), 0666) + err = os.WriteFile(resultFile, []byte(tc.result), 0o666) if err != nil { log.Fatal(err) } @@ -1187,7 +1208,7 @@ type fakeResultsWriter struct { func (f *fakeResultsWriter) Run(ctx context.Context, args ...string) error { f.args = &args for k, v := range f.resultsToWrite { - err := os.WriteFile(k, []byte(v), 0666) + err := os.WriteFile(k, []byte(v), 0o666) if err != nil { return err } diff --git a/pkg/internal/resultref/resultref_test.go b/pkg/internal/resultref/resultref_test.go index 2d8ab653949..624e244b5fd 100644 --- a/pkg/internal/resultref/resultref_test.go +++ b/pkg/internal/resultref/resultref_test.go @@ -17,6 +17,7 @@ limitations under the License. package resultref_test import ( + "errors" "fmt" "testing" @@ -90,7 +91,7 @@ func TestParseStepExpression(t *testing.T) { Value: *v1.NewStructuredValues("$(steps.sumSteps.results.sumResult.foo.bar)"), }, wantParsedResult: resultref.ParsedResult{}, - wantError: fmt.Errorf("must be one of the form 1). \"tasks..results.\"; 2). \"tasks..results..\"; 3). \"steps..results.\"; 4). \"steps..results..\""), + wantError: errors.New("must be one of the form 1). \"tasks..results.\"; 2). \"tasks..results..\"; 3). \"steps..results.\"; 4). \"steps..results..\""), }, { name: "not a step result ref", param: v1.Param{ @@ -98,7 +99,7 @@ func TestParseStepExpression(t *testing.T) { Value: *v1.NewStructuredValues("$(tasks.sumSteps.results.sumResult.foo.bar)"), }, wantParsedResult: resultref.ParsedResult{}, - wantError: fmt.Errorf("must be one of the form 1). \"steps..results.\"; 2). \"steps..results..\""), + wantError: errors.New("must be one of the form 1). \"steps..results.\"; 2). \"steps..results..\""), }} { t.Run(tt.name, func(t *testing.T) { expressions, _ := tt.param.GetVarSubstitutionExpressions() @@ -183,7 +184,7 @@ func TestParseTaskExpression(t *testing.T) { Value: *v1.NewStructuredValues("$(tasks.sumTasks.results.sumResult.foo.bar)"), }, wantParsedResult: resultref.ParsedResult{}, - wantError: fmt.Errorf("must be one of the form 1). \"tasks..results.\"; 2). \"tasks..results..\"; 3). \"steps..results.\"; 4). \"steps..results..\""), + wantError: errors.New("must be one of the form 1). \"tasks..results.\"; 2). \"tasks..results..\"; 3). \"steps..results.\"; 4). \"steps..results..\""), }, { name: "not a task result ref", param: v1.Param{ @@ -191,7 +192,7 @@ func TestParseTaskExpression(t *testing.T) { Value: *v1.NewStructuredValues("$(nottasks.sumTasks.results.sumResult.foo.bar)"), }, wantParsedResult: resultref.ParsedResult{}, - wantError: fmt.Errorf("must be one of the form 1). \"tasks..results.\"; 2). \"tasks..results..\""), + wantError: errors.New("must be one of the form 1). \"tasks..results.\"; 2). \"tasks..results..\""), }} { t.Run(tt.name, func(t *testing.T) { expressions, _ := tt.param.GetVarSubstitutionExpressions() @@ -217,11 +218,12 @@ func TestParseResultName(t *testing.T) { name string input string want []string - }{{ - name: "array indexing", - input: "anArrayResult[1]", - want: []string{"anArrayResult", "1"}, - }, + }{ + { + name: "array indexing", + input: "anArrayResult[1]", + want: []string{"anArrayResult", "1"}, + }, { name: "array star reference", input: "anArrayResult[*]", diff --git a/pkg/pod/creds_init.go b/pkg/pod/creds_init.go index 1556f95395f..6890b73602c 100644 --- a/pkg/pod/creds_init.go +++ b/pkg/pod/creds_init.go @@ -18,6 +18,7 @@ package pod import ( "context" + "errors" "fmt" "regexp" @@ -106,7 +107,7 @@ func credsInit(ctx context.Context, serviceAccountName, namespace string, kubecl // While secret names can use RFC1123 DNS subdomain name rules, the volume mount // name required the stricter DNS label standard, for example no dots anymore. sanitizedName := dnsLabel1123Forbidden.ReplaceAllString(secret.Name, "-") - name := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("tekton-internal-secret-volume-%s", sanitizedName)) + name := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("tekton-internal-secret-volume-" + sanitizedName) volumeMounts = append(volumeMounts, corev1.VolumeMount{ Name: name, MountPath: credentials.VolumeName(secret.Name), @@ -159,7 +160,7 @@ func checkGitSSHSecret(ctx context.Context, secret *corev1.Secret) error { if secret.Type == corev1.SecretTypeSSHAuth && cfg.FeatureFlags.RequireGitSSHSecretKnownHosts { if _, ok := secret.Data[sshKnownHosts]; !ok { - return fmt.Errorf("TaskRun validation failed. Git SSH Secret must have \"known_hosts\" included " + + return errors.New("TaskRun validation failed. Git SSH Secret must have \"known_hosts\" included " + "when feature flag \"require-git-ssh-secret-known-hosts\" is set to true") } } diff --git a/pkg/pod/pod.go b/pkg/pod/pod.go index d63111db427..5beefb8fa35 100644 --- a/pkg/pod/pod.go +++ b/pkg/pod/pod.go @@ -559,7 +559,7 @@ func updateResourceRequirements(resourceRequirementsMap map[string]corev1.Resour // get actual container name, remove "prefix-" string and append "-" at the end // append '-' in the container prefix containerPrefix = strings.Replace(containerPrefix, "prefix-", "", 1) - containerPrefix = fmt.Sprintf("%s-", containerPrefix) + containerPrefix += "-" // update init containers for index := range pod.Spec.InitContainers { diff --git a/pkg/pod/pod_test.go b/pkg/pod/pod_test.go index 31f0b867a44..0ff4e0f0154 100644 --- a/pkg/pod/pod_test.go +++ b/pkg/pod/pod_test.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "path/filepath" + "strconv" "testing" "time" @@ -97,923 +98,939 @@ func TestPodBuild(t *testing.T) { want *corev1.PodSpec wantAnnotations map[string]string wantPodName string - }{{ - desc: "simple", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "name", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-name", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }, runMount(0, false), binROMount}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }, runVolume(0)), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "simple with breakpoint onFailure enabled, alpha api fields disabled", - trs: v1.TaskRunSpec{ - Debug: &v1.TaskRunDebug{ - Breakpoints: &v1.TaskBreakpoints{ - OnFailure: "enabled", - }, + }{ + { + desc: "simple", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "name", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, }, - }, - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "name", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-name", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "simple with running-in-environment-with-injected-sidecar set to false", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "name", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - }, - featureFlags: map[string]string{ - featureInjectedSidecar: "false", - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-name", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - wantAnnotations: map[string]string{ - readyAnnotation: readyAnnotationValue, - }, - }, { - desc: "with service account", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "name", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - }, - trs: v1.TaskRunSpec{ - ServiceAccountName: "service-account", - }, - want: &corev1.PodSpec{ - ServiceAccountName: "service-account", - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-name", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-basic-docker=multi-creds=https://docker.io", - "-basic-docker=multi-creds=https://us.gcr.io", - "-basic-git=multi-creds=github.com", - "-basic-git=multi-creds=gitlab.com", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, append(append([]corev1.VolumeMount{}, implicitVolumeMounts...), corev1.VolumeMount{ - Name: "tekton-internal-secret-volume-multi-creds-9l9zj", - MountPath: "/tekton/creds-secrets/multi-creds", - })...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, secretsVolume, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "with-pod-template", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "name", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - }, - trs: v1.TaskRunSpec{ - PodTemplate: &pod.Template{ - SecurityContext: &corev1.PodSecurityContext{ - Sysctls: []corev1.Sysctl{ - {Name: "net.ipv4.tcp_syncookies", Value: "1"}, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-name", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", }, - }, - RuntimeClassName: &runtimeClassName, - AutomountServiceAccountToken: &automountServiceAccountToken, - DNSPolicy: &dnsPolicy, - DNSConfig: &corev1.PodDNSConfig{ - Nameservers: []string{"8.8.8.8"}, - Searches: []string{"tekton.local"}, - }, - EnableServiceLinks: &enableServiceLinks, - PriorityClassName: &priorityClassName, + VolumeMounts: append([]corev1.VolumeMount{downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }, runMount(0, false), binROMount}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, runVolume(0)), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-name", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{ - binROMount, runMount(0, false), - downwardMount, - {Name: "tekton-creds-init-home-0", MountPath: "/tekton/creds"}, - }, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - SecurityContext: &corev1.PodSecurityContext{ - Sysctls: []corev1.Sysctl{ - {Name: "net.ipv4.tcp_syncookies", Value: "1"}, + { + desc: "simple with breakpoint onFailure enabled, alpha api fields disabled", + trs: v1.TaskRunSpec{ + Debug: &v1.TaskRunDebug{ + Breakpoints: &v1.TaskBreakpoints{ + OnFailure: "enabled", + }, }, }, - RuntimeClassName: &runtimeClassName, - AutomountServiceAccountToken: &automountServiceAccountToken, - DNSPolicy: dnsPolicy, - DNSConfig: &corev1.PodDNSConfig{ - Nameservers: []string{"8.8.8.8"}, - Searches: []string{"tekton.local"}, + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "name", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-name", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - EnableServiceLinks: &enableServiceLinks, - PriorityClassName: priorityClassName, - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "very long step name", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-a-very-very-long-character-step-name-to-trigger-max-len", // step name trimmed. - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "step name ends with non alphanumeric", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "ends-with-invalid-%%__$$", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "ends-with-invalid-%%__$$"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-ends-with-invalid", // invalid suffix removed. - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + { + desc: "simple with running-in-environment-with-injected-sidecar set to false", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "name", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + }, + featureFlags: map[string]string{ + featureInjectedSidecar: "false", + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-name", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, + wantAnnotations: map[string]string{ + readyAnnotation: readyAnnotationValue, + }, }, - }, { - desc: "workingDir in workspace", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "name", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - WorkingDir: filepath.Join(pipeline.WorkspaceDir, "test"), - }}, + { + desc: "with service account", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "name", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + }, + trs: v1.TaskRunSpec{ + ServiceAccountName: "service-account", + }, + want: &corev1.PodSpec{ + ServiceAccountName: "service-account", + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-name", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-basic-docker=multi-creds=https://docker.io", + "-basic-docker=multi-creds=https://us.gcr.io", + "-basic-git=multi-creds=github.com", + "-basic-git=multi-creds=gitlab.com", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, append(append([]corev1.VolumeMount{}, implicitVolumeMounts...), corev1.VolumeMount{ + Name: "tekton-internal-secret-volume-multi-creds-9l9zj", + MountPath: "/tekton/creds-secrets/multi-creds", + })...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, secretsVolume, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{ - entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */), - { - Name: "working-dir-initializer", - Image: images.WorkingDirInitImage, - Command: []string{"/ko-app/workingdirinit"}, - Args: []string{filepath.Join(pipeline.WorkspaceDir, "test")}, - WorkingDir: pipeline.WorkspaceDir, - VolumeMounts: implicitVolumeMounts, + { + desc: "with-pod-template", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "name", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + }, + trs: v1.TaskRunSpec{ + PodTemplate: &pod.Template{ + SecurityContext: &corev1.PodSecurityContext{ + Sysctls: []corev1.Sysctl{ + {Name: "net.ipv4.tcp_syncookies", Value: "1"}, + }, + }, + RuntimeClassName: &runtimeClassName, + AutomountServiceAccountToken: &automountServiceAccountToken, + DNSPolicy: &dnsPolicy, + DNSConfig: &corev1.PodDNSConfig{ + Nameservers: []string{"8.8.8.8"}, + Searches: []string{"tekton.local"}, + }, + EnableServiceLinks: &enableServiceLinks, + PriorityClassName: &priorityClassName, }, }, - Containers: []corev1.Container{{ - Name: "step-name", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-name", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{ + binROMount, runMount(0, false), + downwardMount, + {Name: "tekton-creds-init-home-0", MountPath: "/tekton/creds"}, + }, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + SecurityContext: &corev1.PodSecurityContext{ + Sysctls: []corev1.Sysctl{ + {Name: "net.ipv4.tcp_syncookies", Value: "1"}, + }, }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - WorkingDir: filepath.Join(pipeline.WorkspaceDir, "test"), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + RuntimeClassName: &runtimeClassName, + AutomountServiceAccountToken: &automountServiceAccountToken, + DNSPolicy: dnsPolicy, + DNSConfig: &corev1.PodDNSConfig{ + Nameservers: []string{"8.8.8.8"}, + Searches: []string{"tekton.local"}, + }, + EnableServiceLinks: &enableServiceLinks, + PriorityClassName: priorityClassName, + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - }, { - desc: "sidecar container", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "primary-name", - Image: "primary-image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - Sidecars: []v1.Sidecar{{ - Name: "sc-name", - Image: "sidecar-image", - }}, + { + desc: "very long step name", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-a-very-very-long-character-step-name-to-trigger-max-len", // step name trimmed. + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - wantAnnotations: map[string]string{}, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-primary-name", - Image: "primary-image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }, { - Name: "sidecar-sc-name", - Image: "sidecar-image", - Resources: corev1.ResourceRequirements{ - Requests: nil, + { + desc: "step name ends with non alphanumeric", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "ends-with-invalid-%%__$$", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "ends-with-invalid-%%__$$"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-ends-with-invalid", // invalid suffix removed. + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, + }, + { + desc: "workingDir in workspace", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "name", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + WorkingDir: filepath.Join(pipeline.WorkspaceDir, "test"), + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{ + entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "name"}}, false /* setSecurityContext */, false /* windows */), + { + Name: "working-dir-initializer", + Image: images.WorkingDirInitImage, + Command: []string{"/ko-app/workingdirinit"}, + Args: []string{filepath.Join(pipeline.WorkspaceDir, "test")}, + WorkingDir: pipeline.WorkspaceDir, + VolumeMounts: implicitVolumeMounts, + }, }, - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + Containers: []corev1.Container{{ + Name: "step-name", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + WorkingDir: filepath.Join(pipeline.WorkspaceDir, "test"), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - }, { - desc: "sidecar container with script", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "primary-name", - Image: "primary-image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - Sidecars: []v1.Sidecar{{ - Name: "sc-name", - Image: "sidecar-image", - Script: "#!/bin/sh\necho hello from sidecar", - }}, + { + desc: "sidecar container", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "primary-name", + Image: "primary-image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + Sidecars: []v1.Sidecar{{ + Name: "sc-name", + Image: "sidecar-image", + }}, + }, + wantAnnotations: map[string]string{}, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-primary-name", + Image: "primary-image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "sidecar-sc-name", + Image: "sidecar-image", + Resources: corev1.ResourceRequirements{ + Requests: nil, + }, + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - wantAnnotations: map[string]string{}, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{ - entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */), - { - Name: "place-scripts", - Image: "busybox", - Command: []string{"sh"}, - VolumeMounts: []corev1.VolumeMount{writeScriptsVolumeMount, binMount}, - Args: []string{"-c", `scriptfile="/tekton/scripts/sidecar-script-0-9l9zj" + { + desc: "sidecar container with script", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "primary-name", + Image: "primary-image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + Sidecars: []v1.Sidecar{{ + Name: "sc-name", + Image: "sidecar-image", + Script: "#!/bin/sh\necho hello from sidecar", + }}, + }, + wantAnnotations: map[string]string{}, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{ + entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */), + { + Name: "place-scripts", + Image: "busybox", + Command: []string{"sh"}, + VolumeMounts: []corev1.VolumeMount{writeScriptsVolumeMount, binMount}, + Args: []string{"-c", `scriptfile="/tekton/scripts/sidecar-script-0-9l9zj" touch ${scriptfile} && chmod +x ${scriptfile} cat > ${scriptfile} << '_EOF_' IyEvYmluL3NoCmVjaG8gaGVsbG8gZnJvbSBzaWRlY2Fy _EOF_ /tekton/bin/entrypoint decode-script "${scriptfile}" `}, + }, }, + Containers: []corev1.Container{{ + Name: "step-primary-name", + Image: "primary-image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "sidecar-sc-name", + Image: "sidecar-image", + Command: []string{"/tekton/scripts/sidecar-script-0-9l9zj"}, + VolumeMounts: []corev1.VolumeMount{scriptsVolumeMount}, + }}, + Volumes: append(implicitVolumes, scriptsVolume, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - Containers: []corev1.Container{{ - Name: "step-primary-name", - Image: "primary-image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }, { - Name: "sidecar-sc-name", - Image: "sidecar-image", - Command: []string{"/tekton/scripts/sidecar-script-0-9l9zj"}, - VolumeMounts: []corev1.VolumeMount{scriptsVolumeMount}, - }}, - Volumes: append(implicitVolumes, scriptsVolume, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "sidecar container with enable-ready-annotation-on-pod-create", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "primary-name", - Image: "primary-image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - Sidecars: []v1.Sidecar{{ - Name: "sc-name", - Image: "sidecar-image", - }}, }, - featureFlags: map[string]string{ - featureFlagSetReadyAnnotationOnPodCreate: "true", - }, - wantAnnotations: map[string]string{}, // no ready annotations on pod create since sidecars are present - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-primary-name", - Image: "primary-image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }, { - Name: "sidecar-sc-name", - Image: "sidecar-image", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + { + desc: "sidecar container with enable-ready-annotation-on-pod-create", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "primary-name", + Image: "primary-image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + Sidecars: []v1.Sidecar{{ + Name: "sc-name", + Image: "sidecar-image", + }}, + }, + featureFlags: map[string]string{ + featureFlagSetReadyAnnotationOnPodCreate: "true", + }, + wantAnnotations: map[string]string{}, // no ready annotations on pod create since sidecars are present + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-primary-name", + Image: "primary-image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "sidecar-sc-name", + Image: "sidecar-image", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - }, { - desc: "resource request", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("8"), - corev1.ResourceMemory: resource.MustParse("10Gi"), + { + desc: "resource request", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("8"), + corev1.ResourceMemory: resource.MustParse("10Gi"), + }, }, - }, - }, { - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse("100Gi"), + }, { + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("100Gi"), + }, }, - }, - }}, - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{ - {Name: "unnamed-0"}, - {Name: "unnamed-1"}, - }, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-unnamed-0", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), runMount(1, true), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("8"), - corev1.ResourceMemory: resource.MustParse("10Gi"), + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{ + {Name: "unnamed-0"}, + {Name: "unnamed-1"}, + }, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-unnamed-0", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", }, - }, - TerminationMessagePath: "/tekton/termination", - }, { - Name: "step-unnamed-1", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/run/0/out", - "-post_file", - "/tekton/run/1/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/1/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, true), runMount(1, false), { - Name: "tekton-creds-init-home-1", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse("100Gi"), + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), runMount(1, true), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("8"), + corev1.ResourceMemory: resource.MustParse("10Gi"), + }, }, - }, - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), runVolume(1), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }, corev1.Volume{ - Name: "tekton-creds-init-home-1", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "with stepOverrides", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "image", - Command: []string{"cmd"}, - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("8"), - corev1.ResourceMemory: resource.MustParse("10Gi"), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "step-unnamed-1", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/run/0/out", + "-post_file", + "/tekton/run/1/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/1/status", + "-entrypoint", + "cmd", + "--", }, - }, - }}, - }, - trs: v1.TaskRunSpec{ - StepSpecs: []v1.TaskRunStepSpec{{ - Name: "step1", - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("6"), - corev1.ResourceMemory: resource.MustParse("5Gi"), + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, true), runMount(1, false), { + Name: "tekton-creds-init-home-1", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("100Gi"), + }, }, - }, - }}, + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), runVolume(1), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-1", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{ - {Name: "step1"}, - }, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-step1", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("6"), - corev1.ResourceMemory: resource.MustParse("5Gi"), + { + desc: "with stepOverrides", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "image", + Command: []string{"cmd"}, + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("8"), + corev1.ResourceMemory: resource.MustParse("10Gi"), + }, }, - }, - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "with stepOverrides and stepTemplate", - ts: v1.TaskSpec{ - StepTemplate: &v1.StepTemplate{ - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("8"), - corev1.ResourceMemory: resource.MustParse("10Gi"), + }}, + }, + trs: v1.TaskRunSpec{ + StepSpecs: []v1.TaskRunStepSpec{{ + Name: "step1", + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("6"), + corev1.ResourceMemory: resource.MustParse("5Gi"), + }, }, - }, + }}, }, - Steps: []v1.Step{{ - Name: "step1", - Image: "image", - Command: []string{"cmd"}, - }}, - }, - trs: v1.TaskRunSpec{ - StepSpecs: []v1.TaskRunStepSpec{{ - Name: "step1", - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("6"), - corev1.ResourceMemory: resource.MustParse("5Gi"), + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{ + {Name: "step1"}, + }, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-step1", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", }, - }, - }}, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("6"), + corev1.ResourceMemory: resource.MustParse("5Gi"), + }, + }, + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{ - {Name: "step1"}, - }, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-step1", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("6"), - corev1.ResourceMemory: resource.MustParse("5Gi"), + { + desc: "with stepOverrides and stepTemplate", + ts: v1.TaskSpec{ + StepTemplate: &v1.StepTemplate{ + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("8"), + corev1.ResourceMemory: resource.MustParse("10Gi"), + }, }, }, - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + Steps: []v1.Step{{ + Name: "step1", + Image: "image", + Command: []string{"cmd"}, + }}, + }, + trs: v1.TaskRunSpec{ + StepSpecs: []v1.TaskRunStepSpec{{ + Name: "step1", + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("6"), + corev1.ResourceMemory: resource.MustParse("5Gi"), + }, + }, + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{ + {Name: "step1"}, + }, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-step1", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("6"), + corev1.ResourceMemory: resource.MustParse("5Gi"), + }, + }, + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - }, { - desc: "with sidecarOverrides", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "primary-name", - Image: "primary-image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }}, - Sidecars: []v1.Sidecar{{ - Name: "sc-name", - Image: "sidecar-image", - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("8"), - corev1.ResourceMemory: resource.MustParse("10Gi"), + { + desc: "with sidecarOverrides", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "primary-name", + Image: "primary-image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }}, + Sidecars: []v1.Sidecar{{ + Name: "sc-name", + Image: "sidecar-image", + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("8"), + corev1.ResourceMemory: resource.MustParse("10Gi"), + }, + }, + }}, + }, + trs: v1.TaskRunSpec{ + SidecarSpecs: []v1.TaskRunSidecarSpec{{ + Name: "sc-name", + ComputeResources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("6"), + corev1.ResourceMemory: resource.MustParse("5Gi"), + }, + }, + }}, + }, + wantAnnotations: map[string]string{}, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */)}, + Containers: []corev1.Container{{ + Name: "step-primary-name", + Image: "primary-image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", }, - }, - }}, - }, - trs: v1.TaskRunSpec{ - SidecarSpecs: []v1.TaskRunSidecarSpec{{ - Name: "sc-name", - ComputeResources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("6"), - corev1.ResourceMemory: resource.MustParse("5Gi"), + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "sidecar-sc-name", + Image: "sidecar-image", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("6"), + corev1.ResourceMemory: resource.MustParse("5Gi"), + }, }, - }, - }}, + }}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - wantAnnotations: map[string]string{}, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "primary-name"}}, false /* setSecurityContext */, false /* windows */)}, - Containers: []corev1.Container{{ - Name: "step-primary-name", - Image: "primary-image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }, { - Name: "sidecar-sc-name", - Image: "sidecar-image", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("6"), - corev1.ResourceMemory: resource.MustParse("5Gi"), - }, + { + desc: "step with script and stepTemplate", + ts: v1.TaskSpec{ + StepTemplate: &v1.StepTemplate{ + Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, + Args: []string{"template", "args"}, }, - }}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "step with script and stepTemplate", - ts: v1.TaskSpec{ - StepTemplate: &v1.StepTemplate{ - Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, - Args: []string{"template", "args"}, - }, - Steps: []v1.Step{{ - Name: "one", - Image: "image", - Script: "#!/bin/sh\necho hello from step one", - }, { - Name: "two", - Image: "image", - VolumeMounts: []corev1.VolumeMount{{Name: "i-have-a-volume-mount"}}, - Script: `#!/usr/bin/env python + Steps: []v1.Step{{ + Name: "one", + Image: "image", + Script: "#!/bin/sh\necho hello from step one", + }, { + Name: "two", + Image: "image", + VolumeMounts: []corev1.VolumeMount{{Name: "i-have-a-volume-mount"}}, + Script: `#!/usr/bin/env python print("Hello from Python")`, - }, { - Name: "regular-step", - Image: "image", - Command: []string{"regular", "command"}, - }}, - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{ - entrypointInitContainer(images.EntrypointImage, []v1.Step{ - {Name: "one"}, - {Name: "two"}, - {Name: "regular-step"}, - }, false /* setSecurityContext */, false /* windows */), - { - Name: "place-scripts", - Image: images.ShellImage, - Command: []string{"sh"}, - Args: []string{"-c", `scriptfile="/tekton/scripts/script-0-9l9zj" + }, { + Name: "regular-step", + Image: "image", + Command: []string{"regular", "command"}, + }}, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{ + entrypointInitContainer(images.EntrypointImage, []v1.Step{ + {Name: "one"}, + {Name: "two"}, + {Name: "regular-step"}, + }, false /* setSecurityContext */, false /* windows */), + { + Name: "place-scripts", + Image: images.ShellImage, + Command: []string{"sh"}, + Args: []string{"-c", `scriptfile="/tekton/scripts/script-0-9l9zj" touch ${scriptfile} && chmod +x ${scriptfile} cat > ${scriptfile} << '_EOF_' IyEvYmluL3NoCmVjaG8gaGVsbG8gZnJvbSBzdGVwIG9uZQ== @@ -1026,256 +1043,261 @@ IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCnByaW50KCJIZWxsbyBmcm9tIFB5dGhvbiIp _EOF_ /tekton/bin/entrypoint decode-script "${scriptfile}" `}, - VolumeMounts: []corev1.VolumeMount{writeScriptsVolumeMount, binMount}, + VolumeMounts: []corev1.VolumeMount{writeScriptsVolumeMount, binMount}, + }, }, + Containers: []corev1.Container{{ + Name: "step-one", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "/tekton/scripts/script-0-9l9zj", + "--", + "template", + "args", + }, + Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, + VolumeMounts: append([]corev1.VolumeMount{scriptsVolumeMount, binROMount, runMount(0, false), runMount(1, true), runMount(2, true), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "step-two", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/run/0/out", + "-post_file", + "/tekton/run/1/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/1/status", + "-entrypoint", + "/tekton/scripts/script-1-mz4c7", + "--", + "template", + "args", + }, + Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, + VolumeMounts: append([]corev1.VolumeMount{{Name: "i-have-a-volume-mount"}, scriptsVolumeMount, binROMount, runMount(0, true), runMount(1, false), runMount(2, true), { + Name: "tekton-creds-init-home-1", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }, { + Name: "step-regular-step", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/run/1/out", + "-post_file", + "/tekton/run/2/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/2/status", + "-entrypoint", + "regular", + "--", + "command", + "template", + "args", + }, + Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, true), runMount(1, true), runMount(2, false), { + Name: "tekton-creds-init-home-2", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, scriptsVolume, binVolume, runVolume(0), runVolume(1), runVolume(2), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-1", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }, corev1.Volume{ + Name: "tekton-creds-init-home-2", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - Containers: []corev1.Container{{ - Name: "step-one", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "/tekton/scripts/script-0-9l9zj", - "--", - "template", - "args", - }, - Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, - VolumeMounts: append([]corev1.VolumeMount{scriptsVolumeMount, binROMount, runMount(0, false), runMount(1, true), runMount(2, true), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }, { - Name: "step-two", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/run/0/out", - "-post_file", - "/tekton/run/1/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/1/status", - "-entrypoint", - "/tekton/scripts/script-1-mz4c7", - "--", - "template", - "args", - }, - Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, - VolumeMounts: append([]corev1.VolumeMount{{Name: "i-have-a-volume-mount"}, scriptsVolumeMount, binROMount, runMount(0, true), runMount(1, false), runMount(2, true), { - Name: "tekton-creds-init-home-1", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }, { - Name: "step-regular-step", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/run/1/out", - "-post_file", - "/tekton/run/2/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/2/status", - "-entrypoint", - "regular", - "--", - "command", - "template", - "args", - }, - Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, true), runMount(1, true), runMount(2, false), { - Name: "tekton-creds-init-home-2", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, scriptsVolume, binVolume, runVolume(0), runVolume(1), runVolume(2), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }, corev1.Volume{ - Name: "tekton-creds-init-home-1", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }, corev1.Volume{ - Name: "tekton-creds-init-home-2", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "step with script that uses two dollar signs", - ts: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "one", - Image: "image", - Script: "#!/bin/sh\n$$", - }}, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "one"}}, false /* setSecurityContext */, false /* windows */), - { - Name: "place-scripts", - Image: images.ShellImage, - Command: []string{"sh"}, - Args: []string{"-c", `scriptfile="/tekton/scripts/script-0-9l9zj" -touch ${scriptfile} && chmod +x ${scriptfile} -cat > ${scriptfile} << '_EOF_' -IyEvYmluL3NoCiQk -_EOF_ -/tekton/bin/entrypoint decode-script "${scriptfile}" -`}, - VolumeMounts: []corev1.VolumeMount{writeScriptsVolumeMount, binMount}, - }, + { + desc: "step with script that uses two dollar signs", + ts: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "one", + Image: "image", + Script: "#!/bin/sh\n$$", + }}, }, - Containers: []corev1.Container{{ - Name: "step-one", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "/tekton/scripts/script-0-9l9zj", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{scriptsVolumeMount, binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - Volumes: append(implicitVolumes, scriptsVolume, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }, - }, { - desc: "using another scheduler", - ts: v1.TaskSpec{ - Steps: []v1.Step{ - { - Name: "schedule-me", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{ + entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "one"}}, false /* setSecurityContext */, false /* windows */), + { + Name: "place-scripts", + Image: images.ShellImage, + Command: []string{"sh"}, + Args: []string{"-c", `scriptfile="/tekton/scripts/script-0-9l9zj" +touch ${scriptfile} && chmod +x ${scriptfile} +cat > ${scriptfile} << '_EOF_' +IyEvYmluL3NoCiQk +_EOF_ +/tekton/bin/entrypoint decode-script "${scriptfile}" +`}, + VolumeMounts: []corev1.VolumeMount{writeScriptsVolumeMount, binMount}, + }, }, + Containers: []corev1.Container{{ + Name: "step-one", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "/tekton/scripts/script-0-9l9zj", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{scriptsVolumeMount, binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + Volumes: append(implicitVolumes, scriptsVolume, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, }, - trs: v1.TaskRunSpec{ - PodTemplate: &pod.Template{ - SchedulerName: "there-scheduler", + { + desc: "using another scheduler", + ts: v1.TaskSpec{ + Steps: []v1.Step{ + { + Name: "schedule-me", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }, + }, }, - }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "schedule-me"}}, false /* setSecurityContext */, false /* windows */)}, - SchedulerName: "there-scheduler", - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - Containers: []corev1.Container{{ - Name: "step-schedule-me", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", + trs: v1.TaskRunSpec{ + PodTemplate: &pod.Template{ + SchedulerName: "there-scheduler", }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "schedule-me"}}, false /* setSecurityContext */, false /* windows */)}, + SchedulerName: "there-scheduler", + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + Containers: []corev1.Container{{ + Name: "step-schedule-me", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + TerminationMessagePath: "/tekton/termination", + }}, + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, + }, }, - }, { - desc: "setting image pull secret", - ts: v1.TaskSpec{ - Steps: []v1.Step{ - { - Name: "image-pull", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. + { + desc: "setting image pull secret", + ts: v1.TaskSpec{ + Steps: []v1.Step{ + { + Name: "image-pull", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. + }, }, }, - }, - trs: v1.TaskRunSpec{ - PodTemplate: &pod.Template{ - ImagePullSecrets: []corev1.LocalObjectReference{{Name: "imageSecret"}}, + trs: v1.TaskRunSpec{ + PodTemplate: &pod.Template{ + ImagePullSecrets: []corev1.LocalObjectReference{{Name: "imageSecret"}}, + }, + }, + want: &corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "image-pull"}}, false /* setSecurityContext */, false /* windows */)}, + Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ + Name: "tekton-creds-init-home-0", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, + }), + Containers: []corev1.Container{{ + Name: "step-image-pull", + Image: "image", + Command: []string{"/tekton/bin/entrypoint"}, + Args: []string{ + "-wait_file", + "/tekton/downward/ready", + "-wait_file_content", + "-post_file", + "/tekton/run/0/out", + "-termination_path", + "/tekton/termination", + "-step_metadata_dir", + "/tekton/run/0/status", + "-entrypoint", + "cmd", + "--", + }, + VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { + Name: "tekton-creds-init-home-0", + MountPath: "/tekton/creds", + }}, implicitVolumeMounts...), + TerminationMessagePath: "/tekton/termination", + }}, + ImagePullSecrets: []corev1.LocalObjectReference{{Name: "imageSecret"}}, + ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, }, - want: &corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{entrypointInitContainer(images.EntrypointImage, []v1.Step{{Name: "image-pull"}}, false /* setSecurityContext */, false /* windows */)}, - Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ - Name: "tekton-creds-init-home-0", - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, - }), - Containers: []corev1.Container{{ - Name: "step-image-pull", - Image: "image", - Command: []string{"/tekton/bin/entrypoint"}, - Args: []string{ - "-wait_file", - "/tekton/downward/ready", - "-wait_file_content", - "-post_file", - "/tekton/run/0/out", - "-termination_path", - "/tekton/termination", - "-step_metadata_dir", - "/tekton/run/0/status", - "-entrypoint", - "cmd", - "--", - }, - VolumeMounts: append([]corev1.VolumeMount{binROMount, runMount(0, false), downwardMount, { - Name: "tekton-creds-init-home-0", - MountPath: "/tekton/creds", - }}, implicitVolumeMounts...), - TerminationMessagePath: "/tekton/termination", - }}, - ImagePullSecrets: []corev1.LocalObjectReference{{Name: "imageSecret"}}, - ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }}, { desc: "setting host aliases", ts: v1.TaskSpec{ @@ -1325,7 +1347,9 @@ _EOF_ }}, HostAliases: []corev1.HostAlias{{IP: "127.0.0.1", Hostnames: []string{"foo.bar"}}}, ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, - }}, { + }, + }, + { desc: "using hostNetwork", ts: v1.TaskSpec{ Steps: []v1.Step{ @@ -1375,7 +1399,8 @@ _EOF_ }}, ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "step-with-timeout", ts: v1.TaskSpec{ Steps: []v1.Step{{ @@ -1420,7 +1445,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "step-with-no-timeout-equivalent-to-0-second-timeout", ts: v1.TaskSpec{ Steps: []v1.Step{{ @@ -1468,7 +1494,8 @@ _EOF_ }), ActiveDeadlineSeconds: &MaxActiveDeadlineSeconds, }, - }, { + }, + { desc: "task-with-creds-init-disabled", featureFlags: map[string]string{ "disable-creds-init": "true", @@ -1507,22 +1534,27 @@ _EOF_ Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "default-forbidden-env - disallowed via podTemplate.", ts: v1.TaskSpec{ Steps: []v1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - Env: []corev1.EnvVar{{Name: "SOME_ENV", Value: "some_val"}, - {Name: "FORBIDDEN_ENV", Value: "some_val"}}, + Env: []corev1.EnvVar{ + {Name: "SOME_ENV", Value: "some_val"}, + {Name: "FORBIDDEN_ENV", Value: "some_val"}, + }, }}, }, configDefaults: map[string]string{"default-forbidden-env": "FORBIDDEN_ENV, TEST_ENV"}, trs: v1.TaskRunSpec{ PodTemplate: &pod.Template{ - Env: []corev1.EnvVar{{Name: "FORBIDDEN_ENV", Value: "overridden_val"}, - {Name: "TEST_ENV", Value: "new_val"}}, + Env: []corev1.EnvVar{ + {Name: "FORBIDDEN_ENV", Value: "overridden_val"}, + {Name: "TEST_ENV", Value: "new_val"}, + }, }, }, want: &corev1.PodSpec{ @@ -1562,7 +1594,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "override env var using podTemplate", ts: v1.TaskSpec{ Steps: []v1.Step{{ @@ -1574,8 +1607,10 @@ _EOF_ }, trs: v1.TaskRunSpec{ PodTemplate: &pod.Template{ - Env: []corev1.EnvVar{{Name: "SOME_ENV", Value: "overridden_val"}, - {Name: "SOME_ENV2", Value: "new_val"}}, + Env: []corev1.EnvVar{ + {Name: "SOME_ENV", Value: "overridden_val"}, + {Name: "SOME_ENV2", Value: "new_val"}, + }, }, }, want: &corev1.PodSpec{ @@ -1616,7 +1651,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "hermetic env var", featureFlags: map[string]string{"enable-api-fields": "alpha"}, ts: v1.TaskSpec{ @@ -1665,7 +1701,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "override hermetic env var", featureFlags: map[string]string{"enable-api-fields": "alpha"}, ts: v1.TaskSpec{ @@ -1717,7 +1754,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "pod for a taskRun with retries", ts: v1.TaskSpec{ Steps: []v1.Step{{ @@ -1778,8 +1816,9 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - wantPodName: fmt.Sprintf("%s-pod-retry2", taskRunName), - }, { + wantPodName: taskRunName + "-pod-retry2", + }, + { desc: "long-taskrun-name", ts: v1.TaskSpec{ Steps: []v1.Step{{ @@ -1823,7 +1862,8 @@ _EOF_ }, runVolume(0)), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "using TopologySpreadConstraints", ts: v1.TaskSpec{ Steps: []v1.Step{ @@ -1895,7 +1935,8 @@ _EOF_ }}, ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "sidecar logs enabled", featureFlags: map[string]string{"results-from": "sidecar-logs"}, ts: v1.TaskSpec{ @@ -1967,7 +2008,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "sidecar logs enabled with step results", featureFlags: map[string]string{"results-from": "sidecar-logs"}, ts: v1.TaskSpec{ @@ -2045,7 +2087,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "sidecar logs enabled with security context", featureFlags: map[string]string{"results-from": "sidecar-logs", "set-security-context": "true"}, ts: v1.TaskSpec{ @@ -2118,7 +2161,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "simple with security context", ts: v1.TaskSpec{ Steps: []v1.Step{{ @@ -2161,7 +2205,8 @@ _EOF_ }, runVolume(0)), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "keep pod on cancel enabled", featureFlags: map[string]string{"keep-pod-on-cancel": "true", "enable-api-fields": "alpha"}, ts: v1.TaskSpec{ @@ -2218,7 +2263,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }, { + }, + { desc: "keep pod on cancel enabled but not alpha", featureFlags: map[string]string{"keep-pod-on-cancel": "true"}, ts: v1.TaskSpec{ @@ -2275,7 +2321,8 @@ _EOF_ }), ActiveDeadlineSeconds: &defaultActiveDeadlineSeconds, }, - }} { + }, + } { t.Run(c.desc, func(t *testing.T) { names.TestingSeed() store := config.NewStore(logtesting.TestLogger(t)) @@ -2293,7 +2340,8 @@ _EOF_ ) kubeclient := fakek8s.NewSimpleClientset( &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}}, - &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "service-account", Namespace: "default"}, + &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{Name: "service-account", Namespace: "default"}, Secrets: []corev1.ObjectReference{{ Name: "multi-creds", }}, @@ -2307,7 +2355,8 @@ _EOF_ "tekton.dev/docker-1": "https://docker.io", "tekton.dev/git-0": "github.com", "tekton.dev/git-1": "gitlab.com", - }}, + }, + }, Type: "kubernetes.io/basic-auth", Data: map[string][]byte{ "username": []byte("foo"), @@ -2350,7 +2399,7 @@ _EOF_ if err != nil { t.Fatalf("builder.Build: %v", err) } - expectedName := fmt.Sprintf("%s-pod", testTaskRunName) + expectedName := testTaskRunName + "-pod" if c.wantPodName != "" { expectedName = c.wantPodName } @@ -2431,7 +2480,7 @@ debug-fail-continue-heredoc-randomly-generated-mz4c7 containersVolumeMounts = append(containersVolumeMounts, debugScriptsVolumeMount) containersVolumeMounts = append(containersVolumeMounts, corev1.VolumeMount{ Name: debugInfoVolumeName, - MountPath: filepath.Join(debugInfoDir, fmt.Sprintf("%d", 0)), + MountPath: filepath.Join(debugInfoDir, strconv.Itoa(0)), }) for _, c := range []struct { @@ -2503,7 +2552,8 @@ debug-fail-continue-heredoc-randomly-generated-mz4c7 ) kubeclient := fakek8s.NewSimpleClientset( &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}}, - &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "service-account", Namespace: "default"}, + &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{Name: "service-account", Namespace: "default"}, Secrets: []corev1.ObjectReference{{ Name: "multi-creds", }}, @@ -2517,7 +2567,8 @@ debug-fail-continue-heredoc-randomly-generated-mz4c7 "tekton.dev/docker-1": "https://docker.io", "tekton.dev/git-0": "github.com", "tekton.dev/git-1": "gitlab.com", - }}, + }, + }, Type: "kubernetes.io/basic-auth", Data: map[string][]byte{ "username": []byte("foo"), @@ -2859,7 +2910,8 @@ func TestPodBuildwithSpireEnabled(t *testing.T) { ) kubeclient := fakek8s.NewSimpleClientset( &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}}, - &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "service-account", Namespace: "default"}, + &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{Name: "service-account", Namespace: "default"}, Secrets: []corev1.ObjectReference{{ Name: "multi-creds", }}, @@ -2873,7 +2925,8 @@ func TestPodBuildwithSpireEnabled(t *testing.T) { "tekton.dev/docker-1": "https://docker.io", "tekton.dev/git-0": "github.com", "tekton.dev/git-1": "gitlab.com", - }}, + }, + }, Type: "kubernetes.io/basic-auth", Data: map[string][]byte{ "username": []byte("foo"), @@ -3227,7 +3280,6 @@ func TestUpdateResourceRequirements(t *testing.T) { resourceRequirements map[string]corev1.ResourceRequirements getExpectedPod func() *corev1.Pod }{ - // verifies with no resource requirements data from a config map { name: "test-with-no-data", diff --git a/pkg/pod/script.go b/pkg/pod/script.go index 32ee47ae2e6..e2f3ca5d24d 100644 --- a/pkg/pod/script.go +++ b/pkg/pod/script.go @@ -20,6 +20,7 @@ import ( "encoding/base64" "fmt" "path/filepath" + "strconv" "strings" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" @@ -217,7 +218,7 @@ func placeDebugScriptInContainers(containers []corev1.Container, initContainer * for i := 0; i < len(containers); i++ { debugInfoVolumeMount := corev1.VolumeMount{ Name: debugInfoVolumeName, - MountPath: filepath.Join(debugInfoDir, fmt.Sprintf("%d", i)), + MountPath: filepath.Join(debugInfoDir, strconv.Itoa(i)), } (&containers[i]).VolumeMounts = append((&containers[i]).VolumeMounts, debugScriptsVolumeMount, debugInfoVolumeMount) } diff --git a/pkg/pod/status.go b/pkg/pod/status.go index f3ad845c3f6..40674df6542 100644 --- a/pkg/pod/status.go +++ b/pkg/pod/status.go @@ -602,7 +602,7 @@ func getFailureMessage(logger *zap.SugaredLogger, pod *corev1.Pod) string { // First, try to surface an error about the actual init container that failed. for _, status := range pod.Status.InitContainerStatuses { if msg := extractContainerFailureMessage(logger, status, pod.ObjectMeta); len(msg) > 0 { - return fmt.Sprintf("init container failed, %s", msg) + return "init container failed, " + msg } } diff --git a/pkg/reconciler/events/cloudevent/cloudeventsfakeclient.go b/pkg/reconciler/events/cloudevent/cloudeventsfakeclient.go index a3b6ae86163..92692943918 100644 --- a/pkg/reconciler/events/cloudevent/cloudeventsfakeclient.go +++ b/pkg/reconciler/events/cloudevent/cloudeventsfakeclient.go @@ -71,7 +71,7 @@ func (c FakeClient) Send(ctx context.Context, event cloudevents.Event) protocol. func (c FakeClient) Request(ctx context.Context, event cloudevents.Event) (*cloudevents.Event, protocol.Result) { if c.behaviour.SendSuccessfully { if len(c.events) < cap(c.events) { - c.events <- fmt.Sprintf("%v", event.String()) + c.events <- event.String() return &event, nil } return nil, fmt.Errorf("channel is full of size:%v, but extra event wants to be sent:%v", cap(c.events), event) diff --git a/pkg/reconciler/pipelinerun/affinity_assistant.go b/pkg/reconciler/pipelinerun/affinity_assistant.go index 0d3d0c2009e..87ff43fe3b8 100644 --- a/pkg/reconciler/pipelinerun/affinity_assistant.go +++ b/pkg/reconciler/pipelinerun/affinity_assistant.go @@ -19,6 +19,7 @@ package pipelinerun import ( "context" "crypto/sha256" + "encoding/hex" "errors" "fmt" @@ -257,7 +258,7 @@ func getAffinityAssistantAnnotationVal(aaBehavior affinityassistant.AffinityAssi // GetAffinityAssistantName returns the Affinity Assistant name based on pipelineWorkspaceName and pipelineRunName func GetAffinityAssistantName(pipelineWorkspaceName string, pipelineRunName string) string { hashBytes := sha256.Sum256([]byte(pipelineWorkspaceName + pipelineRunName)) - hashString := fmt.Sprintf("%x", hashBytes) + hashString := hex.EncodeToString(hashBytes[:]) return fmt.Sprintf("%s-%s", workspace.ComponentNameAffinityAssistant, hashString[:10]) } @@ -391,18 +392,16 @@ func getAssistantAffinityMergedWithPodTemplateAffinity(pr *v1.PipelineRun, aaBeh if aaBehavior == aa.AffinityAssistantPerPipelineRunWithIsolation { // use RequiredDuringSchedulingIgnoredDuringExecution term to enforce only one pipelinerun can run in a node at a time - affinityAssistantsAffinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution = - append(affinityAssistantsAffinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, - repelOtherAffinityAssistantsPodAffinityTerm) + affinityAssistantsAffinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution = append(affinityAssistantsAffinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, + repelOtherAffinityAssistantsPodAffinityTerm) } else { preferredRepelOtherAffinityAssistantsPodAffinityTerm := corev1.WeightedPodAffinityTerm{ Weight: 100, PodAffinityTerm: repelOtherAffinityAssistantsPodAffinityTerm, } // use RequiredDuringSchedulingIgnoredDuringExecution term to schedule pipelineruns to different nodes when possible - affinityAssistantsAffinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution = - append(affinityAssistantsAffinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, - preferredRepelOtherAffinityAssistantsPodAffinityTerm) + affinityAssistantsAffinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append(affinityAssistantsAffinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, + preferredRepelOtherAffinityAssistantsPodAffinityTerm) } return affinityAssistantsAffinity diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index 71d1e776f1c..de293772183 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -332,7 +332,8 @@ spec: type: string - name: contextRetriesParam type: string -`)} +`), + } clusterTasks := []*v1beta1.ClusterTask{ parse.MustParseClusterTask(t, ` metadata: @@ -347,7 +348,8 @@ spec: type: string - name: contextPipelineParam type: string -`)} +`), + } d := test.Data{ PipelineRuns: prs, @@ -713,7 +715,8 @@ spec: `, v1.ParamTypeObject)), } - ps := []*v1.Pipeline{parse.MustParseV1Pipeline(t, ` + ps := []*v1.Pipeline{ + parse.MustParseV1Pipeline(t, ` metadata: name: pipeline-missing-tasks namespace: foo @@ -1192,8 +1195,7 @@ status: value: 123 `)} - expectedPipelineRun := - parse.MustParseV1PipelineRun(t, ` + expectedPipelineRun := parse.MustParseV1PipelineRun(t, ` metadata: name: test-pipeline-missing-results namespace: foo @@ -2199,14 +2201,15 @@ status: "hello-world", corev1.ConditionTrue, )}, - initialChildReferences: []v1.ChildStatusReference{{ - TypeMeta: runtime.TypeMeta{ - APIVersion: v1.SchemeGroupVersion.String(), - Kind: "TaskRun", + initialChildReferences: []v1.ChildStatusReference{ + { + TypeMeta: runtime.TypeMeta{ + APIVersion: v1.SchemeGroupVersion.String(), + Kind: "TaskRun", + }, + Name: "test-pipeline-run-stopped-run-finally-hello-world", + PipelineTaskName: "hello-world-1", }, - Name: "test-pipeline-run-stopped-run-finally-hello-world", - PipelineTaskName: "hello-world-1", - }, }, expectedEvents: []string{"Warning Failed PipelineRun \"test-pipeline-run-stopped-run-finally\" was cancelled"}, hasNilCompletionTime: false, @@ -2876,7 +2879,8 @@ spec: taskRef: name: hello-world kind: Task -`)} +`), + } oneStartedTRs := []*v1.TaskRun{ getTaskRun( t, @@ -3159,7 +3163,8 @@ spec: taskRef: name: hello-world kind: Task -`)}, +`), + }, ps: []*v1.Pipeline{pipelineFinalTask}, pr: parse.MustParseV1PipelineRun(t, fmt.Sprintf(` metadata: @@ -3438,7 +3443,7 @@ spec: // Make the patch call fail, i.e. make it so that the controller fails to cancel the TaskRun clients.Pipeline.PrependReactor("patch", "taskruns", func(action ktesting.Action) (bool, runtime.Object, error) { - return failingReactorActivated, nil, fmt.Errorf("i'm sorry Dave, i'm afraid i can't do that") + return failingReactorActivated, nil, errors.New("i'm sorry Dave, i'm afraid i can't do that") }) err := c.Reconciler.Reconcile(testAssets.Ctx, "foo/test-pipeline-fails-to-cancel") @@ -3556,7 +3561,7 @@ spec: // Make the patch call fail, i.e. make it so that the controller fails to cancel the TaskRun clients.Pipeline.PrependReactor("patch", "taskruns", func(action ktesting.Action) (bool, runtime.Object, error) { - return failingReactorActivated, nil, fmt.Errorf("i'm sorry Dave, i'm afraid i can't do that") + return failingReactorActivated, nil, errors.New("i'm sorry Dave, i'm afraid i can't do that") }) err := c.Reconciler.Reconcile(testAssets.Ctx, "foo/test-pipeline-fails-to-timeout") @@ -4102,7 +4107,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -4293,7 +4297,6 @@ spec: LabelSelector: fmt.Sprintf("tekton.dev/pipelineTask=%s,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs", taskName), Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRuns %s", err) } @@ -4451,7 +4454,6 @@ status: LabelSelector: "tekton.dev/pipelineTask=c-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRuns %s", err) } @@ -4596,7 +4598,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -4762,7 +4763,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=f-c-task,tekton.dev/pipelineRun=test-pipeline-run-different-final-task-when", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -5820,7 +5820,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-different-service-accs", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -6178,7 +6177,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=b-task,tekton.dev/pipelineRun=test-pipeline-run-variable-substitution", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -6777,7 +6775,7 @@ metadata: resolvedObjectMeta *resolutionutil.ResolvedObjectMeta } - var tests = []struct { + tests := []struct { name string reconcile1Args *args reconcile2Args *args @@ -7631,7 +7629,8 @@ func TestReconcilePipeline_FinalTasks(t *testing.T) { // checkTaskRunStatusFromChildRefs checks the status of taskruns from ChildReferences to be expected. func checkTaskRunStatusFromChildRefs(ctx context.Context, t *testing.T, namespace string, clients test.Clients, - childRefs []v1.ChildStatusReference, expectedTaskRuns map[string]*v1.PipelineRunTaskRunStatus) { + childRefs []v1.ChildStatusReference, expectedTaskRuns map[string]*v1.PipelineRunTaskRunStatus, +) { t.Helper() taskrunsToCheck := len(expectedTaskRuns) if taskrunsToCheck == 0 { @@ -7960,7 +7959,8 @@ spec: params: - name: pipelineRun-tasks-task1 type: string -`)} +`), + } trs := []*v1.TaskRun{mustParseTaskRunWithObjectMeta(t, taskRunObjectMeta(pipelineRunName+"-task1-xxyy", "foo", pipelineRunName, pipelineName, "task1", false), @@ -8006,7 +8006,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=finaltask,tekton.dev/pipelineRun=" + pipelineRunName, Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -8212,7 +8211,6 @@ spec: LabelSelector: "tekton.dev/pipelineTask=final-task-1,tekton.dev/pipelineRun=test-pipeline-run-final-task-results", Limit: 1, }) - if err != nil { t.Fatalf("Failure to list TaskRun's %s", err) } @@ -8781,7 +8779,7 @@ spec: } // Mock a successful resolution - var pipelineBytes = []byte(` + pipelineBytes := []byte(` kind: Pipeline apiVersion: tekton.dev/v1 metadata: @@ -9138,6 +9136,7 @@ spec: status: startTime: %s`, prName, specStatus, now.Format(time.RFC3339))) } + func verifyTaskRunStatusesCount(t *testing.T, prStatus v1.PipelineRunStatus, taskCount int) { t.Helper() @@ -9145,6 +9144,7 @@ func verifyTaskRunStatusesCount(t *testing.T, prStatus v1.PipelineRunStatus, tas t.Errorf("Expected PipelineRun status ChildReferences to have %d tasks, but was %d", taskCount, len(filterChildRefsForKind(prStatus.ChildReferences, taskRun))) } } + func verifyTaskRunStatusesNames(t *testing.T, prStatus v1.PipelineRunStatus, taskNames ...string) { t.Helper() @@ -9258,9 +9258,10 @@ func TestGetTaskrunWorkspaces_Failure(t *testing.T) { name string pr *v1.PipelineRun expectedError string - }{{ - name: "failure declaring workspace with different name", - pr: parse.MustParseV1PipelineRun(t, ` + }{ + { + name: "failure declaring workspace with different name", + pr: parse.MustParseV1PipelineRun(t, ` metadata: name: pipeline spec: @@ -9274,8 +9275,8 @@ spec: workspaces: - name: not-source `), - expectedError: `expected workspace "not-source" to be provided by pipelinerun for pipeline task "resolved-pipelinetask"`, - }, + expectedError: `expected workspace "not-source" to be provided by pipelinerun for pipeline task "resolved-pipelinetask"`, + }, { name: "failure mapping workspace with different name", pr: parse.MustParseV1PipelineRun(t, ` @@ -9367,24 +9368,25 @@ func TestGetTaskrunWorkspaces_Success(t *testing.T) { name string pr *v1.PipelineRun rprt *resources.ResolvedPipelineTask - }{{ - name: "valid declaration of workspace names", - pr: parse.MustParseV1PipelineRun(t, ` + }{ + { + name: "valid declaration of workspace names", + pr: parse.MustParseV1PipelineRun(t, ` metadata: name: pipeline spec: workspaces: - name: source`), - rprt: &resources.ResolvedPipelineTask{ - PipelineTask: &v1.PipelineTask{ - Name: "resolved-pipelinetask", - Workspaces: []v1.WorkspacePipelineTaskBinding{{ - Name: "my-task-workspace", - Workspace: "source", - }}, + rprt: &resources.ResolvedPipelineTask{ + PipelineTask: &v1.PipelineTask{ + Name: "resolved-pipelinetask", + Workspaces: []v1.WorkspacePipelineTaskBinding{{ + Name: "my-task-workspace", + Workspace: "source", + }}, + }, }, }, - }, { name: "valid mapping with same workspace names", pr: parse.MustParseV1PipelineRun(t, ` @@ -9460,7 +9462,6 @@ spec: KubeClientSet: fakek8s.NewSimpleClientset(), } _, _, err := c.getTaskrunWorkspaces(context.Background(), tt.pr, tt.rprt) - if err != nil { t.Errorf("Pipeline.getTaskrunWorkspaces() returned error for valid pipeline: %v", err) } @@ -10470,6 +10471,7 @@ labels: }) } } + func TestReconciler_PipelineTaskIncludeParams(t *testing.T) { names.TestingSeed() @@ -11102,10 +11104,11 @@ spec: p *v1.Pipeline tr *v1.TaskRun expectedPipelineRun *v1.PipelineRun - }{{ - name: "p-dag", - memberOf: "tasks", - p: parse.MustParseV1Pipeline(t, fmt.Sprintf(` + }{ + { + name: "p-dag", + memberOf: "tasks", + p: parse.MustParseV1Pipeline(t, fmt.Sprintf(` metadata: name: %s namespace: foo @@ -11135,7 +11138,7 @@ spec: - name: DOCKERFILE value: path/to/Dockerfile3 `, "p-dag")), - expectedPipelineRun: parse.MustParseV1PipelineRun(t, ` + expectedPipelineRun: parse.MustParseV1PipelineRun(t, ` metadata: name: pr namespace: foo @@ -11196,7 +11199,7 @@ status: displayName: build-3 pipelineTaskName: matrix-include `), - }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -13666,12 +13669,11 @@ spec: if tt.tr != nil { d.TaskRuns = []*v1.TaskRun{tt.tr} } - wantEvents := - []string{ - "Normal Started", - "Warning Failed [User error] PipelineRun foo/pr can't be Run; couldn't resolve all references: array Result Index 3 for Task pt-with-result Result platforms is out of bound of size 3", - "Warning InternalError 1 error occurred:", - } + wantEvents := []string{ + "Normal Started", + "Warning Failed [User error] PipelineRun foo/pr can't be Run; couldn't resolve all references: array Result Index 3 for Task pt-with-result Result platforms is out of bound of size 3", + "Warning InternalError 1 error occurred:", + } prt := newPipelineRunTest(t, d) defer prt.Cancel() pipelineRun, clients := prt.reconcileRun(pr.Namespace, pr.Name, wantEvents /* wantEvents*/, true /* permanentError*/) @@ -14723,7 +14725,7 @@ spec: defer prt.Cancel() _, clients := prt.reconcileRun("foo", "pr", []string{}, false) taskRuns, err := clients.Pipeline.TektonV1().TaskRuns("foo").List(prt.TestAssets.Ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=pr,tekton.dev/pipeline=%s", tt.name), + LabelSelector: "tekton.dev/pipelineRun=pr,tekton.dev/pipeline=" + tt.name, Limit: 1, }) if err != nil { @@ -15200,7 +15202,7 @@ spec: defer prt.Cancel() _, clients := prt.reconcileRun("foo", "pr", []string{}, false) taskRuns, err := clients.Pipeline.TektonV1().TaskRuns("foo").List(prt.TestAssets.Ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=pr,tekton.dev/pipeline=%s", tt.name), + LabelSelector: "tekton.dev/pipelineRun=pr,tekton.dev/pipeline=" + tt.name, Limit: 1, }) if err != nil { @@ -15526,6 +15528,7 @@ spec: }) } } + func TestReconcile_SetDefaults(t *testing.T) { names.TestingSeed() @@ -15757,7 +15760,8 @@ spec: expectedComputeResources: []corev1.ResourceRequirements{{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse("1Gi")}, + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, Limits: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("2")}, }}, }} @@ -15848,6 +15852,7 @@ spec: t.Fatalf("Should have filtered chains.tekton.dev/* and results.tekton.dev/* annotations and only have one annotations, got %v", tr.ObjectMeta.Annotations) } } + func TestReconcile_CancelUnscheduled(t *testing.T) { pipelineRunName := "cancel-test-run" prs := []*v1.PipelineRun{parse.MustParseV1PipelineRun(t, `metadata: @@ -15969,7 +15974,8 @@ spec: }, Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: "no-match"}}, - }}} + }, + }} // warnPolicy doesn't contain keys so it will fail verification but doesn't fail the run warnPolicy := []*v1alpha1.VerificationPolicy{{ ObjectMeta: metav1.ObjectMeta{ @@ -15979,7 +15985,8 @@ spec: Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: ".*"}}, Mode: v1alpha1.ModeWarn, - }}} + }, + }} prs := parse.MustParseV1PipelineRun(t, fmt.Sprintf(` metadata: @@ -16010,27 +16017,28 @@ spec: noMatchPolicy string verificationPolicies []*v1alpha1.VerificationPolicy wantTrustedResourcesCondition *apis.Condition - }{{ - name: "ignore no match policy", - noMatchPolicy: config.IgnoreNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: nil, - }, { - name: "warn no match policy", - noMatchPolicy: config.WarnNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: failNoMatchCondition, - }, { - name: "pass enforce policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: vps, - wantTrustedResourcesCondition: passCondition, - }, { - name: "only fail warn policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: warnPolicy, - wantTrustedResourcesCondition: failNoKeysCondition, - }, + }{ + { + name: "ignore no match policy", + noMatchPolicy: config.IgnoreNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: nil, + }, { + name: "warn no match policy", + noMatchPolicy: config.WarnNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: failNoMatchCondition, + }, { + name: "pass enforce policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: vps, + wantTrustedResourcesCondition: passCondition, + }, { + name: "only fail warn policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: warnPolicy, + wantTrustedResourcesCondition: failNoKeysCondition, + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -16303,7 +16311,8 @@ spec: }, Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: "no-match"}}, - }}} + }, + }} // warnPolicy doesn't contain keys so it will fail verification but doesn't fail the run warnPolicy := []*v1alpha1.VerificationPolicy{{ ObjectMeta: metav1.ObjectMeta{ @@ -16313,7 +16322,8 @@ spec: Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: ".*"}}, Mode: v1alpha1.ModeWarn, - }}} + }, + }} prs := parse.MustParseV1PipelineRun(t, fmt.Sprintf(` metadata: @@ -16344,27 +16354,28 @@ spec: noMatchPolicy string verificationPolicies []*v1alpha1.VerificationPolicy wantTrustedResourcesCondition *apis.Condition - }{{ - name: "ignore no match policy", - noMatchPolicy: config.IgnoreNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: nil, - }, { - name: "warn no match policy", - noMatchPolicy: config.WarnNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: failNoMatchCondition, - }, { - name: "pass enforce policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: vps, - wantTrustedResourcesCondition: passCondition, - }, { - name: "only fail warn policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: warnPolicy, - wantTrustedResourcesCondition: failNoKeysCondition, - }, + }{ + { + name: "ignore no match policy", + noMatchPolicy: config.IgnoreNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: nil, + }, { + name: "warn no match policy", + noMatchPolicy: config.WarnNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: failNoMatchCondition, + }, { + name: "pass enforce policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: vps, + wantTrustedResourcesCondition: passCondition, + }, { + name: "only fail warn policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: warnPolicy, + wantTrustedResourcesCondition: failNoKeysCondition, + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -16638,7 +16649,8 @@ spec: echo "hello world" workspaces: - name: source -`)} +`), + } trs := []*v1.TaskRun{} @@ -16773,7 +16785,7 @@ spec: creationErr error }{{ name: "invalid", - creationErr: apierrors.NewInvalid(taskRunGK, fmt.Sprintf("%s-hello-world", prName), field.ErrorList{}), + creationErr: apierrors.NewInvalid(taskRunGK, prName+"-hello-world", field.ErrorList{}), }, { name: "bad request", creationErr: apierrors.NewBadRequest("bad request"), @@ -16837,7 +16849,7 @@ spec: creationErr error }{{ name: "invalid", - creationErr: apierrors.NewInvalid(customRunGK, fmt.Sprintf("%s-hello-world", prName), field.ErrorList{}), + creationErr: apierrors.NewInvalid(customRunGK, prName+"-hello-world", field.ErrorList{}), }, { name: "bad request", creationErr: apierrors.NewBadRequest("bad request"), @@ -17075,7 +17087,8 @@ status: type: string value: bar-value startTime: "2023-10-03T10:55:12Z" -`)} +`), + } d := test.Data{ PipelineRuns: prs, @@ -17726,7 +17739,7 @@ func getSignedV1Task(unsigned *pipelinev1.Task, signer signature.Signer, name st func signInterface(signer signature.Signer, i interface{}) ([]byte, error) { if signer == nil { - return nil, fmt.Errorf("signer is nil") + return nil, errors.New("signer is nil") } b, err := json.Marshal(i) if err != nil { diff --git a/pkg/reconciler/pipelinerun/pipelinerun_updatestatus_test.go b/pkg/reconciler/pipelinerun/pipelinerun_updatestatus_test.go index b1fc9084ae9..1e60850d594 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_updatestatus_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_updatestatus_test.go @@ -18,7 +18,6 @@ package pipelinerun import ( "context" - "fmt" "regexp" "strings" "testing" @@ -451,7 +450,7 @@ pipelineTaskName: task var fixedChildRefs []v1.ChildStatusReference re := regexp.MustCompile(`^[a-z\-]*?-(task|run)-[0-9]`) for _, cr := range actualChildRefs { - cr.Name = fmt.Sprintf("%s-xxyyy", re.FindString(cr.Name)) + cr.Name = re.FindString(cr.Name) + "-xxyyy" fixedChildRefs = append(fixedChildRefs, cr) } actualPrStatus.ChildReferences = fixedChildRefs @@ -586,7 +585,7 @@ metadata: var fixedChildRefs []v1.ChildStatusReference re := regexp.MustCompile(`^[a-z\-]*?-(task|run)-[0-9]`) for _, cr := range actualChildRefs { - cr.Name = fmt.Sprintf("%s-xxyyy", re.FindString(cr.Name)) + cr.Name = re.FindString(cr.Name) + "-xxyyy" fixedChildRefs = append(fixedChildRefs, cr) } actualPrStatus.ChildReferences = fixedChildRefs diff --git a/pkg/reconciler/pipelinerun/resources/apply_test.go b/pkg/reconciler/pipelinerun/resources/apply_test.go index dc69a90bda8..e7d40c95d2e 100644 --- a/pkg/reconciler/pipelinerun/resources/apply_test.go +++ b/pkg/reconciler/pipelinerun/resources/apply_test.go @@ -18,7 +18,7 @@ package resources_test import ( "context" - "fmt" + "errors" "testing" "github.com/google/go-cmp/cmp" @@ -42,1436 +42,1469 @@ func TestApplyParameters(t *testing.T) { params []v1.Param expected v1.PipelineSpec wc func(context.Context) context.Context - }{{ - name: "single parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, - }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }{ + { + name: "single parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - }, { - name: "parameter propagation string no task or task default winner pipeline", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, - }}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello param!")}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "hello param!"`, - }}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation string into finally task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, - }}, + { + name: "parameter propagation string no task or task default winner pipeline", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello param!")}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "hello param!"`, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello param!")}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "hello param!"`, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation array no task or task default winner pipeline", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO[*])"}, - }}, + { + name: "parameter propagation string into finally task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello", "param", "!!!")}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "hello", "param", "!!!"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello param!")}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "hello param!"`, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation array finally task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO[*])"}, - }}, + { + name: "parameter propagation array no task or task default winner pipeline", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO[*])"}, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello", "param", "!!!")}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "hello", "param", "!!!"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello", "param", "!!!")}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "hello", "param", "!!!"}, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation object no task or task default winner pipeline", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myObject.key1) $(params.myObject.key2)"}, - }}, + { + name: "parameter propagation array finally task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO[*])"}, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "myObject", Value: *v1.NewObject(map[string]string{"key1": "hello", "key2": "world!"})}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "hello world!"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("hello", "param", "!!!")}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "hello", "param", "!!!"}, + }}, + }, }, - }, - }}, + }}, + }, }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "parameter propagation object finally task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myObject.key1) $(params.myObject.key2)"}, - }}, + { + name: "parameter propagation object no task or task default winner pipeline", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myObject.key1) $(params.myObject.key2)"}, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "myObject", Value: *v1.NewObject(map[string]string{"key1": "hello", "key2": "world!"})}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "hello world!"}, - }}, + }}, + }, + params: v1.Params{{Name: "myObject", Value: *v1.NewObject(map[string]string{"key1": "hello", "key2": "world!"})}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "hello world!"}, + }}, + }, }, - }, - }}, + }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "parameter propagation with task default but no task winner pipeline", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, - }}, + { + name: "parameter propagation object finally task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myObject.key1) $(params.myObject.key2)"}, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "pipeline param!"`, - }}, + }}, + }, + params: v1.Params{{Name: "myObject", Value: *v1.NewObject(map[string]string{"key1": "hello", "key2": "world!"})}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "hello world!"}, + }}, + }, }, - }, - }}, + }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, }, - }, { - name: "parameter propagation with task scoping Finally task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, - }}, + { + name: "parameter propagation with task default but no task winner pipeline", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "pipeline param!"`, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "pipeline param!"`, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation array with task default but no task winner pipeline", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, - }}, + { + name: "parameter propagation with task scoping Finally task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline", "param!"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "pipeline param!"`, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation array with task scoping Finally task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, - }}, + { + name: "parameter propagation array with task default but no task winner pipeline", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline", "param!"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline", "param!"}, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "parameter propagation array with task default and task winner task", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, - }}, + { + name: "parameter propagation array with task scoping Finally task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, + }}, + }, }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "task", "param!"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline", "param!"}, + }}, + }, }, - }, - }}, + }}, + }, }, - }, { - name: "Finally task parameter propagation array with task default and task winner task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, - }}, - }, - }, - }}, - }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default", "param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "task", "param!"}, - }}, + { + name: "parameter propagation array with task default and task winner task", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, + }}, + }, }, - }, - }}, - }, - }, { - name: "parameter propagation with task default and task winner task", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "task", "param!"}, + }}, + }, }, - }, - }}, + }}, + }, }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "task param!"`, - }}, + { + name: "Finally task parameter propagation array with task default and task winner task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.HELLO)"}, + }}, + }, }, - }, - }}, - }, - }, { - name: "Finally task parameter propagation with task default and task winner task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline", "param!")}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task", "param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default", "param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "task", "param!"}, + }}, + }, }, - }, - }}, + }}, + }, }, - params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "HELLO", - Default: v1.NewStructuredValues("default param!"), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Script: `#!/usr/bin/env bash\necho "task param!"`, - }}, + { + name: "parameter propagation with task default and task winner task", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, + }}, + }, }, - }, - }}, - }, - }, { - name: "parameter propagation object with task default but no task winner pipeline", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "task param!"`, + }}, + }, }, - }, - }}, + }}, + }, }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "pipeline", - "key2": "param!!", - })}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline param!!"}, - }}, + { + name: "Finally task parameter propagation with task default and task winner task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "$(params.HELLO)"`, + }}, + }, }, - }, - }}, - }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "Finally task parameter propagation object with task default but no task winner pipeline", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, - }}, + }}, + }, + params: v1.Params{{Name: "HELLO", Value: *v1.NewStructuredValues("pipeline param!")}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "HELLO", Value: *v1.NewStructuredValues("task param!")}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "HELLO", + Default: v1.NewStructuredValues("default param!"), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Script: `#!/usr/bin/env bash\necho "task param!"`, + }}, + }, }, - }, - }}, + }}, + }, }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "pipeline", - "key2": "param!!", - })}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline param!!"}, - }}, + { + name: "parameter propagation object with task default but no task winner pipeline", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, + }}, + }, }, - }, - }}, - }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "parameter propagation object with task default and task winner task", - original: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "task", - "key2": "param!", - })}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, - }}, + }}, + }, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "pipeline", + "key2": "param!!", + })}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline param!!"}, + }}, + }, }, - }, - }}, + }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{"key1": "pipeline", "key2": "param!!!"})}}, - expected: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "task", - "key2": "param!", - })}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "task param!"}, - }}, + { + name: "Finally task parameter propagation object with task default but no task winner pipeline", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, + }}, + }, }, - }, - }}, - }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "Finally task parameter propagation object with task default and task winner task", - original: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "task", - "key2": "param!", - })}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, - }}, + }}, + }, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "pipeline", + "key2": "param!!", + })}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "pipeline param!!"}, + }}, + }, }, - }, - }}, + }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{"key1": "pipeline", "key2": "param!!!"})}}, - expected: v1.PipelineSpec{ - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "task", - "key2": "param!", - })}, - }, - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "myobject", - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "default", - "key2": "param!!", - }), - }}, - Steps: []v1.Step{{ - Name: "step1", - Image: "ubuntu", - Args: []string{"#!/usr/bin/env bash\n", "echo", "task param!"}, - }}, + { + name: "parameter propagation object with task default and task winner task", + original: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "task", + "key2": "param!", + })}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, + }}, + }, }, - }, - }}, - }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "single parameter with when expression", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "$(params.first-param)", - Operator: selection.In, - Values: []string{"$(params.second-param)"}, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "default-value", - Operator: selection.In, - Values: []string{"second-value"}, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{"key1": "pipeline", "key2": "param!!!"})}}, + expected: v1.PipelineSpec{ + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "task", + "key2": "param!", + })}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "task param!"}, + }}, + }, + }, }}, - }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, }, - }, { - name: "object parameter with when expression", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - "key3": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - "key3": "val3", - }), - }, + { + name: "Finally task parameter propagation object with task default and task winner task", + original: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "task", + "key2": "param!", + })}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "$(params.myobject.key1) $(params.myobject.key2)"}, + }}, + }, + }, + }}, }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "$(params.myobject.key1)", - Operator: selection.In, - Values: []string{"$(params.myobject.key2)", "$(params.myobject.key3)"}, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{"key1": "pipeline", "key2": "param!!!"})}}, + expected: v1.PipelineSpec{ + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "task", + "key2": "param!", + })}, + }, + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "myobject", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + "key2": "param!!", + }), + }}, + Steps: []v1.Step{{ + Name: "step1", + Image: "ubuntu", + Args: []string{"#!/usr/bin/env bash\n", "echo", "task param!"}, + }}, + }, + }, }}, - }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - "key3": "val1", - })}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - "key3": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - "key3": "val3", - }), + { + name: "single parameter with when expression", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "val1", - Operator: selection.In, - Values: []string{"val2", "val1"}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "$(params.first-param)", + Operator: selection.In, + Values: []string{"$(params.second-param)"}, + }}, }}, - }}, - }, - }, { - name: "string pipeline parameter nested inside task parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param))")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param))")}, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: nil, // no parameter values. - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "default-value", + Operator: selection.In, + Values: []string{"second-value"}, + }}, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value)")}, - }, - }}, }, - }, { - name: "array pipeline parameter nested inside task parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param)")}, - }, - }}, - }, - params: v1.Params{ - {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "default", "array", "value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "second-value", "array")}, - }, - }}, - }, - }, { - name: "object pipeline parameter nested inside task parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, + { + name: "object parameter with when expression", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + "key3": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val3", + }), }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), }, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "$(params.myobject.key1)", + Operator: selection.In, + Values: []string{"$(params.myobject.key2)", "$(params.myobject.key3)"}, + }}, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.myobject.key1))")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.myobject.key2))")}, - }, - }}, - }, - params: nil, // no parameter values. - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val1", + })}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + "key3": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val3", + }), }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.val1)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.val2)")}, }, - }}, - }, - }, { - name: "parameter evaluation with final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, - }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param)", - Operator: selection.In, - Values: []string{"$(params.second-param)"}, - }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value")}, - }, - When: v1.WhenExpressions{{ - Input: "default-value", - Operator: selection.In, - Values: []string{"second-value"}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "val1", + Operator: selection.In, + Values: []string{"val2", "val1"}, + }}, }}, - }}, - }, - }, { - name: "parameter evaluation with both tasks and final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, - }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, - }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param)", - Operator: selection.In, - Values: []string{"$(params.second-param)"}, - }}, - }}, }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value")}, - }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value")}, + { + name: "string pipeline parameter nested inside task parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, }, - When: v1.WhenExpressions{{ - Input: "default-value", - Operator: selection.In, - Values: []string{"second-value"}, - }}, - }}, - }, - }, { - name: "object parameter evaluation with both tasks and final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param))")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param))")}, }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.myobject.key1)")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.myobject.key2)")}, - }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.myobject.key1)")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.myobject.key2)")}, - }, - When: v1.WhenExpressions{{ - Input: "$(params.myobject.key1)", - Operator: selection.In, - Values: []string{"$(params.myobject.key2)"}, }}, - }}, - }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "foo", - "key2": "bar", - })}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("foo")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("bar")}, - }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("foo")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("bar")}, + params: nil, // no parameter values. + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, }, - When: v1.WhenExpressions{{ - Input: "foo", - Operator: selection.In, - Values: []string{"bar"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value)")}, + }, }}, - }}, - }, - }, { - name: "parameter references with bracket notation and special characters", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second/param", Type: v1.ParamTypeString}, - {Name: "third.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "fourth/param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"])`)}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"])`)}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'])`)}, - {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'])`)}, - {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, - }, - }}, - }, - params: v1.Params{ - {Name: "second/param", Value: *v1.NewStructuredValues("second-value")}, - {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value")}, + }, }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second/param", Type: v1.ParamTypeString}, - {Name: "third.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "fourth/param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues("fourth-value")}, - {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + { + name: "array pipeline parameter nested inside task parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - }, - }, { - name: "single parameter in workspace subpath", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "$(params.second-param)", + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param)")}, }, + }}, + }, + params: v1.Params{ + {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, + }, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "default", "array", "value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "second-value", "array")}, + }, + }}, + }, }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + name: "object pipeline parameter nested inside task parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "second-value", + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), }, }, - }}, - }, - }, { - name: "object parameter in workspace subpath", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.myobject.key1))")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.myobject.key2))")}, }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.myobject.key1)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ + params: nil, // no parameter values. + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "$(params.myobject.key2)", + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), }, }, - }}, - }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "foo", - "key2": "bar", - })}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.val1)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.val2)")}, }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("foo")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + { + name: "parameter evaluation with final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "bar", + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, }, - }, - }}, - }, - }, { - name: "single parameter with resolver", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, + When: v1.WhenExpressions{{ + Input: "$(params.first-param)", + Operator: selection.In, + Values: []string{"$(params.second-param)"}, + }}, + }}, }, - Tasks: []v1.PipelineTask{{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "first-resolver-param", - Value: *v1.NewStructuredValues("$(params.first-param)"), - }, { - Name: "second-resolver-param", - Value: *v1.NewStructuredValues("$(params.second-param)"), - }}, - }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "first-resolver-param", - Value: *v1.NewStructuredValues("default-value"), - }, { - Name: "second-resolver-param", - Value: *v1.NewStructuredValues("second-value"), - }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value")}, }, - }, - }}, - }, - }, { - name: "object parameter with resolver", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - "key3": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - "key3": "val3", - }), - }, + When: v1.WhenExpressions{{ + Input: "default-value", + Operator: selection.In, + Values: []string{"second-value"}, + }}, + }}, }, - Tasks: []v1.PipelineTask{{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "first-resolver-param", - Value: *v1.NewStructuredValues("$(params.myobject.key1)"), - }, { - Name: "second-resolver-param", - Value: *v1.NewStructuredValues("$(params.myobject.key2)"), - }, { - Name: "third-resolver-param", - Value: *v1.NewStructuredValues("$(params.myobject.key3)"), - }}, - }, - }, - }}, }, - params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - "key3": "val1", - })}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - { - Name: "myobject", - Type: v1.ParamTypeObject, - Properties: map[string]v1.PropertySpec{ - "key1": {Type: "string"}, - "key2": {Type: "string"}, - "key3": {Type: "string"}, - }, - Default: v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - "key3": "val3", - }), + { + name: "parameter evaluation with both tasks and final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }, - Tasks: []v1.PipelineTask{{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "first-resolver-param", - Value: *v1.NewStructuredValues("val1"), - }, { - Name: "second-resolver-param", - Value: *v1.NewStructuredValues("val2"), - }, { - Name: "third-resolver-param", - Value: *v1.NewStructuredValues("val1"), - }}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, }, - }, - }}, - }, - wc: cfgtesting.EnableAlphaAPIFields, - }, { - name: "single parameter in finally workspace subpath", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "$(params.second-param)", + }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param)")}, }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param)", + Operator: selection.In, + Values: []string{"$(params.second-param)"}, + }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "second-value", + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value")}, }, - }, - }}, + }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value")}, + }, + When: v1.WhenExpressions{{ + Input: "default-value", + Operator: selection.In, + Values: []string{"second-value"}, + }}, + }}, + }, }, - }, { - name: "tasks with the same parameter name but referencing different values", + name: "object parameter evaluation with both tasks and final tasks", original: v1.PipelineSpec{ Params: []v1.ParamSpec{ { - Name: "param1", - Default: &v1.ParamValue{ - Type: v1.ParamTypeString, - StringVal: "a", + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, }, - Type: v1.ParamTypeString, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), }, }, - Tasks: []v1.PipelineTask{ - { - Name: "previous-task-with-result", + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.myobject.key1)")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.myobject.key2)")}, + }, + }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.myobject.key1)")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.myobject.key2)")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.myobject.key1)", + Operator: selection.In, + Values: []string{"$(params.myobject.key2)"}, + }}, + }}, + }, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "foo", + "key2": "bar", + })}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), + }, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("foo")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("bar")}, + }, + }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("foo")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("bar")}, + }, + When: v1.WhenExpressions{{ + Input: "foo", + Operator: selection.In, + Values: []string{"bar"}, + }}, + }}, + }, + }, + { + name: "parameter references with bracket notation and special characters", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second/param", Type: v1.ParamTypeString}, + {Name: "third.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "fourth/param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"])`)}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"])`)}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'])`)}, + {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'])`)}, + {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + }, + }}, + }, + params: v1.Params{ + {Name: "second/param", Value: *v1.NewStructuredValues("second-value")}, + {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value")}, + }, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second/param", Type: v1.ParamTypeString}, + {Name: "third.param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "fourth/param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues("fourth-value")}, + {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + }, + }}, + }, + }, + { + name: "single parameter in workspace subpath", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "$(params.second-param)", + }, + }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "second-value", + }, + }, + }}, + }, + }, + { + name: "object parameter in workspace subpath", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), + }, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.myobject.key1)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "$(params.myobject.key2)", + }, + }, + }}, + }, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "foo", + "key2": "bar", + })}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), + }, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("foo")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "bar", + }, + }, + }}, + }, + }, + { + name: "single parameter with resolver", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "first-resolver-param", + Value: *v1.NewStructuredValues("$(params.first-param)"), + }, { + Name: "second-resolver-param", + Value: *v1.NewStructuredValues("$(params.second-param)"), + }}, + }, + }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "first-resolver-param", + Value: *v1.NewStructuredValues("default-value"), + }, { + Name: "second-resolver-param", + Value: *v1.NewStructuredValues("second-value"), + }}, + }, + }, + }}, + }, + }, + { + name: "object parameter with resolver", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + "key3": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val3", + }), + }, + }, + Tasks: []v1.PipelineTask{{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "first-resolver-param", + Value: *v1.NewStructuredValues("$(params.myobject.key1)"), + }, { + Name: "second-resolver-param", + Value: *v1.NewStructuredValues("$(params.myobject.key2)"), + }, { + Name: "third-resolver-param", + Value: *v1.NewStructuredValues("$(params.myobject.key3)"), + }}, + }, + }, + }}, + }, + params: v1.Params{{Name: "myobject", Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val1", + })}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "myobject", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "string"}, + "key2": {Type: "string"}, + "key3": {Type: "string"}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val3", + }), + }, + }, + Tasks: []v1.PipelineTask{{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "first-resolver-param", + Value: *v1.NewStructuredValues("val1"), + }, { + Name: "second-resolver-param", + Value: *v1.NewStructuredValues("val2"), + }, { + Name: "third-resolver-param", + Value: *v1.NewStructuredValues("val1"), + }}, + }, + }, + }}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, + { + name: "single parameter in finally workspace subpath", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "$(params.second-param)", + }, + }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeString, Default: v1.NewStructuredValues("default-value")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "second-value", + }, + }, + }}, + }, + }, + { + name: "tasks with the same parameter name but referencing different values", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + { + Name: "param1", + Default: &v1.ParamValue{ + Type: v1.ParamTypeString, + StringVal: "a", + }, + Type: v1.ParamTypeString, + }, + }, + Tasks: []v1.PipelineTask{ + { + Name: "previous-task-with-result", }, { Name: "print-msg", @@ -1709,7 +1742,8 @@ func TestApplyParameters(t *testing.T) { }, }, }, - }, { + }, + { name: "parameter/s in tasks and finally display name", params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value")}}, original: v1.PipelineSpec{ @@ -1764,288 +1798,289 @@ func TestApplyParameters_ArrayIndexing(t *testing.T) { original v1.PipelineSpec params []v1.Param expected v1.PipelineSpec - }{{ - name: "single parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[1])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[0])")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, - }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value-again")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }{ + { + name: "single parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - }, { - name: "single parameter with when expression", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "$(params.first-param[1])", - Operator: selection.In, - Values: []string{"$(params.second-param[0])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[1])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[0])")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "default-value-again", - Operator: selection.In, - Values: []string{"second-value"}, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value-again")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }, }}, - }}, - }, - }, { - name: "pipeline parameter nested inside task parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param[0]))")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param[1]))")}, + }, { + name: "single parameter with when expression", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: nil, // no parameter values. - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "$(params.first-param[1])", + Operator: selection.In, + Values: []string{"$(params.second-param[0])"}, + }}, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value-again)")}, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - }, { - name: "array parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "default-value-again", + Operator: selection.In, + Values: []string{"second-value"}, + }}, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param[0])")}, + }, { + name: "pipeline parameter nested inside task parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, }, - }}, - }, - params: v1.Params{ - {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param[0]))")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param[1]))")}, + }, + }}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "default", "array", "value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "second-value")}, + params: nil, // no parameter values. + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, }, - }}, - }, - }, { - name: "parameter evaluation with final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, - }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param[0])", - Operator: selection.In, - Values: []string{"$(params.second-param[1])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.default-value-again)")}, + }, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value-again")}, - }, - When: v1.WhenExpressions{{ - Input: "default-value", - Operator: selection.In, - Values: []string{"second-value-again"}, + }, + }, { + name: "array parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param[0])")}, + }, }}, - }}, - }, - }, { - name: "parameter evaluation with both tasks and final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + params: v1.Params{ + {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, + }, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "default", "array", "value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "second-value")}, + }, + }}, + }, + }, { + name: "parameter evaluation with final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param[0])", - Operator: selection.In, - Values: []string{"$(params.second-param[1])"}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param[0])", + Operator: selection.In, + Values: []string{"$(params.second-param[1])"}, + }}, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value-again")}, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value-again")}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value-again")}, + }, + When: v1.WhenExpressions{{ + Input: "default-value", + Operator: selection.In, + Values: []string{"second-value-again"}, + }}, + }}, + }, + }, { + name: "parameter evaluation with both tasks and final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - When: v1.WhenExpressions{{ - Input: "default-value", - Operator: selection.In, - Values: []string{"second-value-again"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, }}, - }}, - }, - }, { - name: "parameter references with bracket notation and special characters", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second/param", Type: v1.ParamTypeArray}, - {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "fourth/param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"][0])`)}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"][0])`)}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'][1])`)}, - {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'][1])`)}, - {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param[0])", + Operator: selection.In, + Values: []string{"$(params.second-param[1])"}, + }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - }, - params: v1.Params{ - {Name: "second/param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}, - {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value", "fourth-value-again")}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second/param", Type: v1.ParamTypeArray}, - {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "fourth/param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("default-value-again")}, - {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues("fourth-value-again")}, - {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value-again")}, + }, + }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("second-value-again")}, + }, + When: v1.WhenExpressions{{ + Input: "default-value", + Operator: selection.In, + Values: []string{"second-value-again"}, + }}, + }}, + }, + }, { + name: "parameter references with bracket notation and special characters", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second/param", Type: v1.ParamTypeArray}, + {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "fourth/param", Type: v1.ParamTypeArray}, }, - }}, - }, - }, { - name: "single parameter in workspace subpath", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "$(params.second-param[1])", + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"][0])`)}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"][0])`)}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'][1])`)}, + {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'][1])`)}, + {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, }, + }}, + }, + params: v1.Params{ + {Name: "second/param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}, + {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value", "fourth-value-again")}, + }, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second/param", Type: v1.ParamTypeArray}, + {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "fourth/param", Type: v1.ParamTypeArray}, }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "second-value-again", + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("second-value")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("default-value-again")}, + {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues("fourth-value-again")}, + {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + }, + }}, + }, + }, { + name: "single parameter in workspace subpath", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "$(params.second-param[1])", + }, + }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("default-value")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "second-value-again", + }, + }, + }}, + }, }, - }, } { tt := tt // capture range variable t.Run(tt.name, func(t *testing.T) { @@ -2069,588 +2104,266 @@ func TestApplyReplacementsMatrix(t *testing.T) { original v1.PipelineSpec params []v1.Param expected v1.PipelineSpec - }{{ - name: "matrix params replacements", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Tasks: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Params: v1.Params{{ - // string replacements from string param, array param and object param - Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)", "$(params.bar[0])", "$(params.rad.key1)"), - }, { - // array replacement from array param - Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar)"), - }}, - }, - }}, - }, - params: v1.Params{ - {Name: "foo", Value: *v1.NewStructuredValues("foo")}, - {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, - {Name: "rad", Value: *v1.NewObject(map[string]string{ - "key1": "r", - "key2": "a", - "key3": "d", - })}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Tasks: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Params: v1.Params{{ - // string replacements from string param, array param and object param - Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), - }, { - // array replacement from array param - Name: "second-param", Value: *v1.NewStructuredValues("b", "a", "r"), - }}, - }, - }}, - }, - }, { - name: "matrix include params replacement", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Tasks: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", - Params: v1.Params{{ - // string replacements from string param - Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)"), - }, { - // string replacements from array param - Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar[0])"), - }, { - // string replacements from object param - Name: "third-param", Value: *v1.NewStructuredValues("$(params.rad.key1)"), - }}, - }}, - }, - }}, - }, - params: v1.Params{ - {Name: "foo", Value: *v1.NewStructuredValues("foo")}, - {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, - {Name: "rad", Value: *v1.NewObject(map[string]string{ - "key1": "r", - "key2": "a", - "key3": "d", - })}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Tasks: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", - Params: v1.Params{{ - // string replacements from string param - Name: "first-param", Value: *v1.NewStructuredValues("foo"), - }, { - // string replacements from array param - Name: "second-param", Value: *v1.NewStructuredValues("b"), - }, { - // string replacements from object param - Name: "third-param", Value: *v1.NewStructuredValues("r"), - }}, - }}, - }, - }}, - }, - }, { - name: "matrix params with final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Finally: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Params: v1.Params{{ - // string replacements from string param, array param and object param - Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)", "$(params.bar[0])", "$(params.rad.key1)"), - }, { - // array replacement from array param - Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar)"), - }}, - }, - }}, - }, - params: v1.Params{ - {Name: "foo", Value: *v1.NewStructuredValues("foo")}, - {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, - {Name: "rad", Value: *v1.NewObject(map[string]string{ - "key1": "r", - "key2": "a", - "key3": "d", - })}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Finally: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Params: v1.Params{{ - // string replacements from string param, array param and object param - Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), - }, { - // array replacement from array param - Name: "second-param", Value: *v1.NewStructuredValues("b", "a", "r"), - }}, - }, - }}, - }, - }, { - name: "matrix include params with final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Finally: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", - Params: v1.Params{{ - // string replacements from string param - Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)"), - }, { - // string replacements from array param - Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar[0])"), - }, { - // string replacements from object param - Name: "third-param", Value: *v1.NewStructuredValues("$(params.rad.key1)"), - }}, - }}, - }, - }}, - }, - params: v1.Params{ - {Name: "foo", Value: *v1.NewStructuredValues("foo")}, - {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, - {Name: "rad", Value: *v1.NewObject(map[string]string{ - "key1": "r", - "key2": "a", - "key3": "d", - })}, - }, - expected: v1.PipelineSpec{ - Params: []v1.ParamSpec{{ - Name: "foo", Type: v1.ParamTypeString, - }, { - Name: "bar", Type: v1.ParamTypeArray, - }, { - Name: "rad", Type: v1.ParamTypeObject, - }}, - Finally: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", + }{ + { + name: "matrix params replacements", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Tasks: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ Params: v1.Params{{ - // string replacements from string param - Name: "first-param", Value: *v1.NewStructuredValues("foo"), + // string replacements from string param, array param and object param + Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)", "$(params.bar[0])", "$(params.rad.key1)"), }, { - // string replacements from array param - Name: "second-param", Value: *v1.NewStructuredValues("b"), - }, { - // string replacements from object param - Name: "third-param", Value: *v1.NewStructuredValues("r"), + // array replacement from array param + Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar)"), }}, - }}, - }, - }}, - }, - }, - } { - tt := tt // capture range variable - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - run := &v1.PipelineRun{ - Spec: v1.PipelineRunSpec{ - Params: tt.params, - }, - } - got := resources.ApplyParameters(context.Background(), &tt.original, run) - if d := cmp.Diff(&tt.expected, got); d != "" { - t.Errorf("ApplyParameters() got diff %s", diff.PrintWantGot(d)) - } - }) - } -} - -func TestApplyTaskResults_MinimalExpression(t *testing.T) { - for _, tt := range []struct { - name string - targets resources.PipelineRunState - resolvedResultRefs resources.ResolvedResultRefs - want resources.PipelineRunState - }{{ - name: "Test result substitution on minimal variable substitution expression - params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"])`), - }}, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("aResultValue"), - }}, - }, - }}, - }, { - name: "Test array indexing result substitution on minimal variable substitution expression - params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][1])`), - }}, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("arrayResultValueTwo"), - }}, - }, - }}, - }, { - name: "Test array indexing result substitution out of bound - params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), - }}, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - // index validation is done in ResolveResultRefs() before ApplyTaskResults() - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), - }}, - }, - }}, - }, { - name: "Test array result substitution on minimal variable substitution expression - params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: v1.ParamValue{Type: v1.ParamTypeArray, - ArrayVal: []string{`$(tasks.aTask.results["a.Result"][*])`}, }, }}, }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - }}, + params: v1.Params{ + {Name: "foo", Value: *v1.NewStructuredValues("foo")}, + {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, + {Name: "rad", Value: *v1.NewObject(map[string]string{ + "key1": "r", + "key2": "a", + "key3": "d", + })}, }, - }}, - }, { - name: "Test object result as a whole substitution - params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "resultName", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results.resultName[*])`), - }}, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - // index validation is done in ResolveResultRefs() before ApplyTaskResults() - Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }}, - }, - }}, - }, { - name: "Test object result element substitution - params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "resultName", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results.resultName.key1)`), + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, }}, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Params: v1.Params{{ - Name: "bParam", - // index validation is done in ResolveResultRefs() before ApplyTaskResults() - Value: *v1.NewStructuredValues("val1"), + Tasks: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Params: v1.Params{{ + // string replacements from string param, array param and object param + Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), + }, { + // array replacement from array param + Name: "second-param", Value: *v1.NewStructuredValues("b", "a", "r"), + }}, + }, }}, }, - }}, - }, { - name: "Test result substitution on minimal variable substitution expression - matrix", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"])`), - }}}, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("aResultValue"), - }}}, - }, - }}, - }, { - name: "Test array indexing result substitution on minimal variable substitution expression - matrix", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][1])`), - }}}, + }, { + name: "matrix include params replacement", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Tasks: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + // string replacements from string param + Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)"), + }, { + // string replacements from array param + Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar[0])"), + }, { + // string replacements from object param + Name: "third-param", Value: *v1.NewStructuredValues("$(params.rad.key1)"), + }}, + }}, + }, + }}, }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("arrayResultValueTwo"), - }}}, + params: v1.Params{ + {Name: "foo", Value: *v1.NewStructuredValues("foo")}, + {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, + {Name: "rad", Value: *v1.NewObject(map[string]string{ + "key1": "r", + "key2": "a", + "key3": "d", + })}, }, - }}, - }, { - name: "Test array indexing result substitution out of bound - matrix", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "a.Result", + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Tasks: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + // string replacements from string param + Name: "first-param", Value: *v1.NewStructuredValues("foo"), + }, { + // string replacements from array param + Name: "second-param", Value: *v1.NewStructuredValues("b"), + }, { + // string replacements from object param + Name: "third-param", Value: *v1.NewStructuredValues("r"), + }}, + }}, + }, + }}, }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), - }}}, + }, { + name: "matrix params with final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Finally: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Params: v1.Params{{ + // string replacements from string param, array param and object param + Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)", "$(params.bar[0])", "$(params.rad.key1)"), + }, { + // array replacement from array param + Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar)"), + }}, + }, + }}, }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), - }}}, + params: v1.Params{ + {Name: "foo", Value: *v1.NewStructuredValues("foo")}, + {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, + {Name: "rad", Value: *v1.NewObject(map[string]string{ + "key1": "r", + "key2": "a", + "key3": "d", + })}, }, - }}, - }, { - name: "Test array result substitution on minimal variable substitution expression - when expressions", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "aResult", + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Finally: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Params: v1.Params{{ + // string replacements from string param, array param and object param + Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), + }, { + // array replacement from array param + Name: "second-param", Value: *v1.NewStructuredValues("b", "a", "r"), + }}, + }, + }}, }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - // Note that Input doesn't support array replacement. - Input: "anInput", - Operator: selection.In, - Values: []string{"$(tasks.aTask.results.aResult[*])"}, + }, { + name: "matrix include params with final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Finally: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + // string replacements from string param + Name: "first-param", Value: *v1.NewStructuredValues("$(params.foo)"), + }, { + // string replacements from array param + Name: "second-param", Value: *v1.NewStructuredValues("$(params.bar[0])"), + }, { + // string replacements from object param + Name: "third-param", Value: *v1.NewStructuredValues("$(params.rad.key1)"), + }}, + }}, + }, }}, }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - Input: "anInput", - Operator: selection.In, - Values: []string{"arrayResultValueOne", "arrayResultValueTwo"}, + params: v1.Params{ + {Name: "foo", Value: *v1.NewStructuredValues("foo")}, + {Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r")}, + {Name: "rad", Value: *v1.NewObject(map[string]string{ + "key1": "r", + "key2": "a", + "key3": "d", + })}, + }, + expected: v1.PipelineSpec{ + Params: []v1.ParamSpec{{ + Name: "foo", Type: v1.ParamTypeString, + }, { + Name: "bar", Type: v1.ParamTypeArray, + }, { + Name: "rad", Type: v1.ParamTypeObject, + }}, + Finally: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + // string replacements from string param + Name: "first-param", Value: *v1.NewStructuredValues("foo"), + }, { + // string replacements from array param + Name: "second-param", Value: *v1.NewStructuredValues("b"), + }, { + // string replacements from object param + Name: "third-param", Value: *v1.NewStructuredValues("r"), + }}, + }}, + }, }}, }, - }}, - }, { - name: "Test result substitution on minimal variable substitution expression - when expressions", + }, + } { + tt := tt // capture range variable + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + run := &v1.PipelineRun{ + Spec: v1.PipelineRunSpec{ + Params: tt.params, + }, + } + got := resources.ApplyParameters(context.Background(), &tt.original, run) + if d := cmp.Diff(&tt.expected, got); d != "" { + t.Errorf("ApplyParameters() got diff %s", diff.PrintWantGot(d)) + } + }) + } +} + +func TestApplyTaskResults_MinimalExpression(t *testing.T) { + for _, tt := range []struct { + name string + targets resources.PipelineRunState + resolvedResultRefs resources.ResolvedResultRefs + want resources.PipelineRunState + }{{ + name: "Test result substitution on minimal variable substitution expression - params", resolvedResultRefs: resources.ResolvedResultRefs{{ Value: *v1.NewStructuredValues("aResultValue"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", + Result: "a.Result", }, FromTaskRun: "aTaskRun", }}, @@ -2658,10 +2371,9 @@ func TestApplyTaskResults_MinimalExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - Input: "$(tasks.aTask.results.aResult)", - Operator: selection.In, - Values: []string{"$(tasks.aTask.results.aResult)"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"])`), }}, }, }}, @@ -2669,20 +2381,19 @@ func TestApplyTaskResults_MinimalExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - Input: "aResultValue", - Operator: selection.In, - Values: []string{"aResultValue"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("aResultValue"), }}, }, }}, }, { - name: "Test array indexing result substitution on minimal variable substitution expression - when expressions", + name: "Test array indexing result substitution on minimal variable substitution expression - params", resolvedResultRefs: resources.ResolvedResultRefs{{ Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", + Result: "a.Result", }, FromTaskRun: "aTaskRun", }}, @@ -2690,10 +2401,9 @@ func TestApplyTaskResults_MinimalExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - Input: "$(tasks.aTask.results.aResult[1])", - Operator: selection.In, - Values: []string{"$(tasks.aTask.results.aResult[0])"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][1])`), }}, }, }}, @@ -2701,148 +2411,86 @@ func TestApplyTaskResults_MinimalExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - Input: "arrayResultValueTwo", - Operator: selection.In, - Values: []string{"arrayResultValueOne"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("arrayResultValueTwo"), }}, }, }}, }, { - name: "Test array result substitution on minimal variable substitution expression - resolver params", + name: "Test array indexing result substitution out of bound - params", resolvedResultRefs: resources.ResolvedResultRefs{{ Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: v1.ParamValue{Type: v1.ParamTypeArray, - ArrayVal: []string{`$(tasks.aTask.results["aResult"][*])`}, - }, - }}, - }, - }, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: v1.ParamValue{Type: v1.ParamTypeArray, - ArrayVal: []string{"arrayResultValueOne", "arrayResultValueTwo"}, - }, - }}, - }, - }, - }, - }}, - }, { - name: "Test result substitution on minimal variable substitution expression - resolver params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "aResult", + Result: "a.Result", }, FromTaskRun: "aTaskRun", }}, targets: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("$(tasks.aTask.results.aResult)"), - }}, - }, - }, + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), + }}, }, }}, want: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("aResultValue"), - }}, - }, - }, + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + // index validation is done in ResolveResultRefs() before ApplyTaskResults() + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), + }}, }, }}, }, { - name: "Test array indexing result substitution on minimal variable substitution expression - resolver params", + name: "Test array result substitution on minimal variable substitution expression - params", resolvedResultRefs: resources.ResolvedResultRefs{{ Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", + Result: "a.Result", }, FromTaskRun: "aTaskRun", }}, targets: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("$(tasks.aTask.results.aResult[0])"), - }, { - Name: "cParam", - Value: *v1.NewStructuredValues("$(tasks.aTask.results.aResult[1])"), - }}, + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: v1.ParamValue{ + Type: v1.ParamTypeArray, + ArrayVal: []string{`$(tasks.aTask.results["a.Result"][*])`}, }, - }, + }}, }, }}, want: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("arrayResultValueOne"), - }, { - Name: "cParam", - Value: *v1.NewStructuredValues("arrayResultValueTwo"), - }}, - }, - }, + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), + }}, }, }}, - }} { - t.Run(tt.name, func(t *testing.T) { - resources.ApplyTaskResults(tt.targets, tt.resolvedResultRefs) - if d := cmp.Diff(tt.want, tt.targets); d != "" { - t.Fatalf("ApplyTaskResults() %s", diff.PrintWantGot(d)) - } - }) - } -} - -func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { - for _, tt := range []struct { - name string - targets resources.PipelineRunState - resolvedResultRefs resources.ResolvedResultRefs - want resources.PipelineRunState - }{{ - name: "Test result substitution on embedded variable substitution expression - params", + }, { + name: "Test object result as a whole substitution - params", resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), + Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", + Result: "resultName", }, FromTaskRun: "aTaskRun", }}, @@ -2852,7 +2500,7 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { TaskRef: &v1.TaskRef{Name: "bTask"}, Params: v1.Params{{ Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult)"), + Value: *v1.NewStructuredValues(`$(tasks.aTask.results.resultName[*])`), }}, }, }}, @@ -2861,18 +2509,25 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> aResultValue"), + Name: "bParam", + // index validation is done in ResolveResultRefs() before ApplyTaskResults() + Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), }}, }, }}, }, { - name: "Test array indexing result substitution on embedded variable substitution expression - params", + name: "Test object result element substitution - params", resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), + Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", + Result: "resultName", }, FromTaskRun: "aTaskRun", }}, @@ -2882,7 +2537,7 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { TaskRef: &v1.TaskRef{Name: "bTask"}, Params: v1.Params{{ Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult[0])"), + Value: *v1.NewStructuredValues(`$(tasks.aTask.results.resultName.key1)`), }}, }, }}, @@ -2891,18 +2546,19 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> arrayResultValueOne"), + Name: "bParam", + // index validation is done in ResolveResultRefs() before ApplyTaskResults() + Value: *v1.NewStructuredValues("val1"), }}, }, }}, }, { - name: "Test result substitution on embedded variable substitution expression - matrix", + name: "Test result substitution on minimal variable substitution expression - matrix", resolvedResultRefs: resources.ResolvedResultRefs{{ Value: *v1.NewStructuredValues("aResultValue"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "aResult", + Result: "a.Result", }, FromTaskRun: "aTaskRun", }}, @@ -2913,8 +2569,9 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { Matrix: &v1.Matrix{ Params: v1.Params{{ Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult)"), - }}}, + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"])`), + }}, + }, }, }}, want: resources.PipelineRunState{{ @@ -2924,35 +2581,52 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { Matrix: &v1.Matrix{ Params: v1.Params{{ Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> aResultValue"), - }}}, + Value: *v1.NewStructuredValues("aResultValue"), + }}, + }, }, }}, }, { - name: "test result substitution for strings and arrays in matrix params", + name: "Test array indexing result substitution on minimal variable substitution expression - matrix", resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("foo"), + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "foo", + Result: "a.Result", }, FromTaskRun: "aTaskRun", - }, { - Value: *v1.NewStructuredValues("b", "a", "r"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "bar", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][1])`), + }}, + }, }, - FromTaskRun: "aTaskRun", - }, { - Value: *v1.NewObject(map[string]string{ - "key1": "r", - "key2": "a", - "key3": "d", - }), + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("arrayResultValueTwo"), + }}, + }, + }, + }}, + }, { + name: "Test array indexing result substitution out of bound - matrix", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "rad", + Result: "a.Result", }, FromTaskRun: "aTaskRun", }}, @@ -2962,8 +2636,8 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { TaskRef: &v1.TaskRef{Name: "bTask"}, Matrix: &v1.Matrix{ Params: v1.Params{{ - // string replacements from string param, array param and object results - Name: "first-param", Value: *v1.NewStructuredValues("$(tasks.aTask.results.foo)", "$(tasks.aTask.results.bar[0])", "$(tasks.aTask.results.rad.key1)"), + Name: "bParam", + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), }}, }, }, @@ -2974,37 +2648,52 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { TaskRef: &v1.TaskRef{Name: "bTask"}, Matrix: &v1.Matrix{ Params: v1.Params{{ - // string replacements from string param, array param and object results - Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), + Name: "bParam", + Value: *v1.NewStructuredValues(`$(tasks.aTask.results["a.Result"][3])`), }}, }, }, }}, }, { - name: "test result substitution for strings from string, arr, obj results in matrix include params", + name: "Test array result substitution on minimal variable substitution expression - when expressions", resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("foo"), + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "foo", + Result: "aResult", }, FromTaskRun: "aTaskRun", - }, { - Value: *v1.NewStructuredValues("b", "a", "r"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "bar", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + When: []v1.WhenExpression{{ + // Note that Input doesn't support array replacement. + Input: "anInput", + Operator: selection.In, + Values: []string{"$(tasks.aTask.results.aResult[*])"}, + }}, }, - FromTaskRun: "aTaskRun", - }, { - Value: *v1.NewObject(map[string]string{ - "key1": "r", - "key2": "a", - "key3": "d", - }), + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + When: []v1.WhenExpression{{ + Input: "anInput", + Operator: selection.In, + Values: []string{"arrayResultValueOne", "arrayResultValueTwo"}, + }}, + }, + }}, + }, { + name: "Test result substitution on minimal variable substitution expression - when expressions", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", - Result: "rad", + Result: "aResult", }, FromTaskRun: "aTaskRun", }}, @@ -3012,36 +2701,28 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", - Params: v1.Params{{ - // string replacements from string results, array results and object results - Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), - }}, - }}, - }, + When: []v1.WhenExpression{{ + Input: "$(tasks.aTask.results.aResult)", + Operator: selection.In, + Values: []string{"$(tasks.aTask.results.aResult)"}, + }}, }, }}, want: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", - Params: v1.Params{{ - // string replacements from string results, array results and object results - Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), - }}, - }}, - }, + When: []v1.WhenExpression{{ + Input: "aResultValue", + Operator: selection.In, + Values: []string{"aResultValue"}, + }}, }, }}, }, { - name: "Test result substitution on embedded variable substitution expression - when expressions", + name: "Test array indexing result substitution on minimal variable substitution expression - when expressions", resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", Result: "aResult", @@ -3052,13 +2733,11 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{ - { - Input: "Result value --> $(tasks.aTask.results.aResult)", - Operator: selection.In, - Values: []string{"Result value --> $(tasks.aTask.results.aResult)"}, - }, - }, + When: []v1.WhenExpression{{ + Input: "$(tasks.aTask.results.aResult[1])", + Operator: selection.In, + Values: []string{"$(tasks.aTask.results.aResult[0])"}, + }}, }, }}, want: resources.PipelineRunState{{ @@ -3066,14 +2745,14 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { Name: "bTask", TaskRef: &v1.TaskRef{Name: "bTask"}, When: []v1.WhenExpression{{ - Input: "Result value --> aResultValue", + Input: "arrayResultValueTwo", Operator: selection.In, - Values: []string{"Result value --> aResultValue"}, + Values: []string{"arrayResultValueOne"}, }}, }, }}, }, { - name: "Test array indexing result substitution on embedded variable substitution expression - when expressions", + name: "Test array result substitution on minimal variable substitution expression - resolver params", resolvedResultRefs: resources.ResolvedResultRefs{{ Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ @@ -3084,32 +2763,72 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { }}, targets: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{ - { - Input: "Result value --> $(tasks.aTask.results.aResult[1])", - Operator: selection.In, - Values: []string{"Result value --> $(tasks.aTask.results.aResult[0])"}, + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: v1.ParamValue{ + Type: v1.ParamTypeArray, + ArrayVal: []string{`$(tasks.aTask.results["aResult"][*])`}, + }, + }}, + }, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: v1.ParamValue{ + Type: v1.ParamTypeArray, + ArrayVal: []string{"arrayResultValueOne", "arrayResultValueTwo"}, + }, + }}, + }, + }, + }, + }}, + }, { + name: "Test result substitution on minimal variable substitution expression - resolver params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("$(tasks.aTask.results.aResult)"), + }}, }, }, }, }}, want: resources.PipelineRunState{{ PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - When: []v1.WhenExpression{{ - Input: "Result value --> arrayResultValueTwo", - Operator: selection.In, - Values: []string{"Result value --> arrayResultValueOne"}, - }}, + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("aResultValue"), + }}, + }, + }, }, }}, }, { - name: "Test result substitution on embedded variable substitution expression - resolver params", + name: "Test array indexing result substitution on minimal variable substitution expression - resolver params", resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), ResultReference: v1.ResultRef{ PipelineTask: "aTask", Result: "aResult", @@ -3122,7 +2841,10 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { ResolverRef: v1.ResolverRef{ Params: v1.Params{{ Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult)"), + Value: *v1.NewStructuredValues("$(tasks.aTask.results.aResult[0])"), + }, { + Name: "cParam", + Value: *v1.NewStructuredValues("$(tasks.aTask.results.aResult[1])"), }}, }, }, @@ -3132,79 +2854,414 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { PipelineTask: &v1.PipelineTask{ TaskRef: &v1.TaskRef{ ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("arrayResultValueOne"), + }, { + Name: "cParam", + Value: *v1.NewStructuredValues("arrayResultValueTwo"), + }}, + }, + }, + }, + }}, + }} { + t.Run(tt.name, func(t *testing.T) { + resources.ApplyTaskResults(tt.targets, tt.resolvedResultRefs) + if d := cmp.Diff(tt.want, tt.targets); d != "" { + t.Fatalf("ApplyTaskResults() %s", diff.PrintWantGot(d)) + } + }) + } +} + +func TestApplyTaskResults_EmbeddedExpression(t *testing.T) { + for _, tt := range []struct { + name string + targets resources.PipelineRunState + resolvedResultRefs resources.ResolvedResultRefs + want resources.PipelineRunState + }{ + { + name: "Test result substitution on embedded variable substitution expression - params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult)"), + }}, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> aResultValue"), + }}, + }, + }}, + }, + { + name: "Test array indexing result substitution on embedded variable substitution expression - params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult[0])"), + }}, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> arrayResultValueOne"), + }}, + }, + }}, + }, + { + name: "Test result substitution on embedded variable substitution expression - matrix", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult)"), + }}, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ Params: v1.Params{{ Name: "bParam", Value: *v1.NewStructuredValues("Result value --> aResultValue"), }}, }, }, - }, - }}, - }, { - name: "Test array indexing result substitution on embedded variable substitution expression - resolver params", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "aResult", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult[0])"), - }, { - Name: "cParam", - Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult[1])"), - }}, + }}, + }, + { + name: "test result substitution for strings and arrays in matrix params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("foo"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "foo", + }, + FromTaskRun: "aTaskRun", + }, { + Value: *v1.NewStructuredValues("b", "a", "r"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "bar", + }, + FromTaskRun: "aTaskRun", + }, { + Value: *v1.NewObject(map[string]string{ + "key1": "r", + "key2": "a", + "key3": "d", + }), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "rad", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Params: v1.Params{{ + // string replacements from string param, array param and object results + Name: "first-param", Value: *v1.NewStructuredValues("$(tasks.aTask.results.foo)", "$(tasks.aTask.results.bar[0])", "$(tasks.aTask.results.rad.key1)"), + }}, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Params: v1.Params{{ + // string replacements from string param, array param and object results + Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), + }}, + }, + }, + }}, + }, + { + name: "test result substitution for strings from string, arr, obj results in matrix include params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("foo"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "foo", + }, + FromTaskRun: "aTaskRun", + }, { + Value: *v1.NewStructuredValues("b", "a", "r"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "bar", + }, + FromTaskRun: "aTaskRun", + }, { + Value: *v1.NewObject(map[string]string{ + "key1": "r", + "key2": "a", + "key3": "d", + }), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "rad", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + // string replacements from string results, array results and object results + Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), + }}, + }}, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + // string replacements from string results, array results and object results + Name: "first-param", Value: *v1.NewStructuredValues("foo", "b", "r"), + }}, + }}, + }, + }, + }}, + }, + { + name: "Test result substitution on embedded variable substitution expression - when expressions", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + When: []v1.WhenExpression{ + { + Input: "Result value --> $(tasks.aTask.results.aResult)", + Operator: selection.In, + Values: []string{"Result value --> $(tasks.aTask.results.aResult)"}, + }, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + When: []v1.WhenExpression{{ + Input: "Result value --> aResultValue", + Operator: selection.In, + Values: []string{"Result value --> aResultValue"}, + }}, + }, + }}, + }, + { + name: "Test array indexing result substitution on embedded variable substitution expression - when expressions", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + When: []v1.WhenExpression{ + { + Input: "Result value --> $(tasks.aTask.results.aResult[1])", + Operator: selection.In, + Values: []string{"Result value --> $(tasks.aTask.results.aResult[0])"}, + }, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + When: []v1.WhenExpression{{ + Input: "Result value --> arrayResultValueTwo", + Operator: selection.In, + Values: []string{"Result value --> arrayResultValueOne"}, + }}, + }, + }}, + }, + { + name: "Test result substitution on embedded variable substitution expression - resolver params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult)"), + }}, + }, + }, + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> aResultValue"), + }}, + }, + }, + }, + }}, + }, + { + name: "Test array indexing result substitution on embedded variable substitution expression - resolver params", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("arrayResultValueOne", "arrayResultValueTwo"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult[0])"), + }, { + Name: "cParam", + Value: *v1.NewStructuredValues("Result value --> $(tasks.aTask.results.aResult[1])"), + }}, + }, }, }, - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - TaskRef: &v1.TaskRef{ - ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "bParam", - Value: *v1.NewStructuredValues("Result value --> arrayResultValueOne"), - }, { - Name: "cParam", - Value: *v1.NewStructuredValues("Result value --> arrayResultValueTwo"), - }}, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Params: v1.Params{{ + Name: "bParam", + Value: *v1.NewStructuredValues("Result value --> arrayResultValueOne"), + }, { + Name: "cParam", + Value: *v1.NewStructuredValues("Result value --> arrayResultValueTwo"), + }}, + }, }, }, - }, - }}, - }, { - name: "Test result substitution on embedded variable substitution expression - displayName", - resolvedResultRefs: resources.ResolvedResultRefs{{ - Value: *v1.NewStructuredValues("aResultValue"), - ResultReference: v1.ResultRef{ - PipelineTask: "aTask", - Result: "aResult", - }, - FromTaskRun: "aTaskRun", - }}, - targets: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - DisplayName: "Result value --> $(tasks.aTask.results.aResult)", - }, - }}, - want: resources.PipelineRunState{{ - PipelineTask: &v1.PipelineTask{ - Name: "bTask", - TaskRef: &v1.TaskRef{Name: "bTask"}, - DisplayName: "Result value --> aResultValue", - }, - }}, - }, + }}, + }, + { + name: "Test result substitution on embedded variable substitution expression - displayName", + resolvedResultRefs: resources.ResolvedResultRefs{{ + Value: *v1.NewStructuredValues("aResultValue"), + ResultReference: v1.ResultRef{ + PipelineTask: "aTask", + Result: "aResult", + }, + FromTaskRun: "aTaskRun", + }}, + targets: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + DisplayName: "Result value --> $(tasks.aTask.results.aResult)", + }, + }}, + want: resources.PipelineRunState{{ + PipelineTask: &v1.PipelineTask{ + Name: "bTask", + TaskRef: &v1.TaskRef{Name: "bTask"}, + DisplayName: "Result value --> aResultValue", + }, + }}, + }, { name: "Test result substitution on embedded variable substitution expression - workspace.subPath", resolvedResultRefs: resources.ResolvedResultRefs{{ @@ -3316,12 +3373,14 @@ func TestContext(t *testing.T) { orig := &v1.Pipeline{ ObjectMeta: metav1.ObjectMeta{Name: "test-pipeline"}, Spec: v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - DisplayName: tc.displayName, - Params: v1.Params{tc.original}, - Matrix: &v1.Matrix{ - Params: v1.Params{tc.original}, - }}, + Tasks: []v1.PipelineTask{ + { + DisplayName: tc.displayName, + Params: v1.Params{tc.original}, + Matrix: &v1.Matrix{ + Params: v1.Params{tc.original}, + }, + }, }, Finally: []v1.PipelineTask{{ DisplayName: tc.displayName, @@ -3455,10 +3514,12 @@ func TestApplyPipelineTaskContexts(t *testing.T) { Params: v1.Params{ {Name: "platform", Value: *v1.NewStructuredValues("linux", "mac", "windows")}, {Name: "browser", Value: *v1.NewStructuredValues("chrome", "firefox", "safari")}, - }}, + }, + }, }}, }, - }}, + }, + }, want: v1.PipelineTask{ Params: v1.Params{{ Name: "matrixlength", @@ -3480,51 +3541,53 @@ func TestApplyPipelineTaskContexts(t *testing.T) { prstatus: v1.PipelineRunStatus{ PipelineRunStatusFields: v1.PipelineRunStatusFields{ PipelineSpec: &v1.PipelineSpec{ - Tasks: []v1.PipelineTask{{ - Name: "matrix-emitting-results", - TaskSpec: &v1.EmbeddedTask{ - TaskSpec: v1.TaskSpec{ - Params: []v1.ParamSpec{{ - Name: "IMAGE", - Type: v1.ParamTypeString, - }, { - Name: "DIGEST", - Type: v1.ParamTypeString, - }}, - Results: []v1.TaskResult{{ - Name: "IMAGE-DIGEST", - }}, - Steps: []v1.Step{{ - Name: "produce-results", - Image: "bash:latest", - Script: `#!/usr/bin/env bash\necho -n "$(params.DIGEST)" | sha256sum | tee $(results.IMAGE-DIGEST.path)"`, - }}, + Tasks: []v1.PipelineTask{ + { + Name: "matrix-emitting-results", + TaskSpec: &v1.EmbeddedTask{ + TaskSpec: v1.TaskSpec{ + Params: []v1.ParamSpec{{ + Name: "IMAGE", + Type: v1.ParamTypeString, + }, { + Name: "DIGEST", + Type: v1.ParamTypeString, + }}, + Results: []v1.TaskResult{{ + Name: "IMAGE-DIGEST", + }}, + Steps: []v1.Step{{ + Name: "produce-results", + Image: "bash:latest", + Script: `#!/usr/bin/env bash\necho -n "$(params.DIGEST)" | sha256sum | tee $(results.IMAGE-DIGEST.path)"`, + }}, + }, }, - }, - Matrix: &v1.Matrix{ - Include: []v1.IncludeParams{{ - Name: "build-1", - Params: v1.Params{{ - Name: "DOCKERFILE", Value: *v1.NewStructuredValues("path/to/Dockerfile1"), + Matrix: &v1.Matrix{ + Include: []v1.IncludeParams{{ + Name: "build-1", + Params: v1.Params{{ + Name: "DOCKERFILE", Value: *v1.NewStructuredValues("path/to/Dockerfile1"), + }, { + Name: "IMAGE", Value: *v1.NewStructuredValues("image-1"), + }}, }, { - Name: "IMAGE", Value: *v1.NewStructuredValues("image-1"), - }}, - }, { - Name: "build-2", - Params: v1.Params{{ - Name: "DOCKERFILE", Value: *v1.NewStructuredValues("path/to/Dockerfile2"), - }, { - Name: "IMAGE", Value: *v1.NewStructuredValues("image-2"), - }}, - }, { - Name: "build-3", - Params: v1.Params{{ - Name: "DOCKERFILE", Value: *v1.NewStructuredValues("path/to/Dockerfile3"), + Name: "build-2", + Params: v1.Params{{ + Name: "DOCKERFILE", Value: *v1.NewStructuredValues("path/to/Dockerfile2"), + }, { + Name: "IMAGE", Value: *v1.NewStructuredValues("image-2"), + }}, }, { - Name: "IMAGE", Value: *v1.NewStructuredValues("image-3"), + Name: "build-3", + Params: v1.Params{{ + Name: "DOCKERFILE", Value: *v1.NewStructuredValues("path/to/Dockerfile3"), + }, { + Name: "IMAGE", Value: *v1.NewStructuredValues("image-3"), + }}, }}, - }}, - }}, + }, + }, }, }, }, @@ -3535,44 +3598,45 @@ func TestApplyPipelineTaskContexts(t *testing.T) { Name: "matrix-emitting-results", }, TaskRunNames: []string{"matrix-emitting-results-0"}, - TaskRuns: []*v1.TaskRun{{ - ObjectMeta: metav1.ObjectMeta{ - Name: "matrix-emitting-results-0", - }, - Status: v1.TaskRunStatus{ - TaskRunStatusFields: v1.TaskRunStatusFields{ - Results: []v1.TaskRunResult{{ - Name: "IMAGE-DIGEST", - Value: *v1.NewStructuredValues("123"), - }}, + TaskRuns: []*v1.TaskRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "matrix-emitting-results-0", }, - }, - }, { - ObjectMeta: metav1.ObjectMeta{ - Name: "matrix-emitting-results-1", - }, - Status: v1.TaskRunStatus{ - TaskRunStatusFields: v1.TaskRunStatusFields{ - Results: []v1.TaskRunResult{{ - Name: "IMAGE-DIGEST", - Value: *v1.NewStructuredValues("456"), - }}, + Status: v1.TaskRunStatus{ + TaskRunStatusFields: v1.TaskRunStatusFields{ + Results: []v1.TaskRunResult{{ + Name: "IMAGE-DIGEST", + Value: *v1.NewStructuredValues("123"), + }}, + }, }, - }, - }, { - ObjectMeta: metav1.ObjectMeta{ - Name: "matrix-emitting-results-2", - }, - Status: v1.TaskRunStatus{ - TaskRunStatusFields: v1.TaskRunStatusFields{ - Results: []v1.TaskRunResult{{ - Name: "IMAGE-DIGEST", - Value: *v1.NewStructuredValues("789"), - }}, + }, { + ObjectMeta: metav1.ObjectMeta{ + Name: "matrix-emitting-results-1", + }, + Status: v1.TaskRunStatus{ + TaskRunStatusFields: v1.TaskRunStatusFields{ + Results: []v1.TaskRunResult{{ + Name: "IMAGE-DIGEST", + Value: *v1.NewStructuredValues("456"), + }}, + }, + }, + }, { + ObjectMeta: metav1.ObjectMeta{ + Name: "matrix-emitting-results-2", + }, + Status: v1.TaskRunStatus{ + TaskRunStatusFields: v1.TaskRunStatusFields{ + Results: []v1.TaskRunResult{{ + Name: "IMAGE-DIGEST", + Value: *v1.NewStructuredValues("789"), + }}, + }, }, }, }, - }, ResultsCache: map[string][]string{}, }}, }, @@ -3656,85 +3720,89 @@ func TestApplyFinallyResultsToPipelineResults(t *testing.T) { skippedTasks []v1.SkippedTask expected []v1.PipelineRunResult expectedError error - }{{ - description: "single-string-result-single-successful-task", - results: []v1.PipelineResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("$(finally.pt1.results.foo)"), - }}, - taskResults: map[string][]v1.TaskRunResult{ - "pt1": { - { - Name: "foo", - Value: *v1.NewStructuredValues("do"), + }{ + { + description: "single-string-result-single-successful-task", + results: []v1.PipelineResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("$(finally.pt1.results.foo)"), + }}, + taskResults: map[string][]v1.TaskRunResult{ + "pt1": { + { + Name: "foo", + Value: *v1.NewStructuredValues("do"), + }, }, }, + expected: []v1.PipelineRunResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("do"), + }}, }, - expected: []v1.PipelineRunResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("do"), - }}, - }, { - description: "single-array-result-single-successful-task", - results: []v1.PipelineResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("$(finally.pt1.results.foo[*])"), - }}, - taskResults: map[string][]v1.TaskRunResult{ - "pt1": { - { - Name: "foo", - Value: *v1.NewStructuredValues("do", "rae"), + { + description: "single-array-result-single-successful-task", + results: []v1.PipelineResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("$(finally.pt1.results.foo[*])"), + }}, + taskResults: map[string][]v1.TaskRunResult{ + "pt1": { + { + Name: "foo", + Value: *v1.NewStructuredValues("do", "rae"), + }, }, }, + expected: []v1.PipelineRunResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("do", "rae"), + }}, }, - expected: []v1.PipelineRunResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("do", "rae"), - }}, - }, { - description: "multiple-results-custom-and-normal-tasks", - results: []v1.PipelineResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("$(finally.customtask.results.foo)"), - }}, - runResults: map[string][]v1beta1.CustomRunResult{ - "customtask": { - { - Name: "foo", - Value: "do", + { + description: "multiple-results-custom-and-normal-tasks", + results: []v1.PipelineResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("$(finally.customtask.results.foo)"), + }}, + runResults: map[string][]v1beta1.CustomRunResult{ + "customtask": { + { + Name: "foo", + Value: "do", + }, }, }, + expected: []v1.PipelineRunResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("do"), + }}, }, - expected: []v1.PipelineRunResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("do"), - }}, - }, { - description: "apply-object-results", - results: []v1.PipelineResult{{ - Name: "pipeline-result-1", - Value: *v1.NewStructuredValues("$(finally.pt1.results.foo[*])"), - }}, - taskResults: map[string][]v1.TaskRunResult{ - "pt1": { - { - Name: "foo", - Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), + { + description: "apply-object-results", + results: []v1.PipelineResult{{ + Name: "pipeline-result-1", + Value: *v1.NewStructuredValues("$(finally.pt1.results.foo[*])"), + }}, + taskResults: map[string][]v1.TaskRunResult{ + "pt1": { + { + Name: "foo", + Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), + }, }, }, + expected: []v1.PipelineRunResult{{ + Name: "pipeline-result-1", + Value: *v1.NewObject(map[string]string{ + "key1": "val1", + "key2": "val2", + }), + }}, }, - expected: []v1.PipelineRunResult{{ - Name: "pipeline-result-1", - Value: *v1.NewObject(map[string]string{ - "key1": "val1", - "key2": "val2", - }), - }}, - }, { description: "referencing-invalid-finally-task", results: []v1.PipelineResult{{ @@ -3750,7 +3818,7 @@ func TestApplyFinallyResultsToPipelineResults(t *testing.T) { }, }, expected: nil, - expectedError: fmt.Errorf("invalid pipelineresults [pipeline-result-1], the referred result don't exist"), + expectedError: errors.New("invalid pipelineresults [pipeline-result-1], the referred result don't exist"), }, } { t.Run(tc.description, func(t *testing.T) { @@ -4078,7 +4146,8 @@ func TestApplyTaskResultsToPipelineResults_Success(t *testing.T) { Name: "foo", Value: *v1.NewStructuredValues("do", "rae", "mi"), }, - }}, + }, + }, taskstatus: map[string]string{resources.PipelineTaskStatusPrefix + "pt1" + resources.PipelineTaskStatusSuffix: v1beta1.TaskRunReasonFailed.String()}, expectedResults: []v1.PipelineRunResult{{ Name: "foo", @@ -4120,7 +4189,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [pipeline-result-1], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [pipeline-result-1], the referenced results don't exist"), }, { description: "object-reference-key-not-exist", results: []v1.PipelineResult{{ @@ -4139,7 +4208,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [pipeline-result-1], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [pipeline-result-1], the referenced results don't exist"), }, { description: "object-results-resultname-not-exist", results: []v1.PipelineResult{{ @@ -4158,7 +4227,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [pipeline-result-1], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [pipeline-result-1], the referenced results don't exist"), }, { description: "invalid-result-variable-no-returned-result", results: []v1.PipelineResult{{ @@ -4172,7 +4241,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "no-taskrun-results-no-returned-results", results: []v1.PipelineResult{{ @@ -4183,7 +4252,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { "pt1": {}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "invalid-taskrun-name-no-returned-result", results: []v1.PipelineResult{{ @@ -4197,7 +4266,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "invalid-result-name-no-returned-result", results: []v1.PipelineResult{{ @@ -4211,7 +4280,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "unsuccessful-taskrun-no-returned-result", results: []v1.PipelineResult{{ @@ -4220,7 +4289,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, taskResults: map[string][]v1.TaskRunResult{}, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "mixed-success-tasks-some-returned-results", results: []v1.PipelineResult{{ @@ -4240,7 +4309,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { Name: "bar", Value: *v1.NewStructuredValues("rae"), }}, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "no-run-results-no-returned-results", results: []v1.PipelineResult{{ @@ -4249,7 +4318,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, runResults: map[string][]v1beta1.CustomRunResult{}, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "wrong-customtask-name-no-returned-result", results: []v1.PipelineResult{{ @@ -4263,7 +4332,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "right-customtask-name-wrong-result-name-no-returned-result", results: []v1.PipelineResult{{ @@ -4277,7 +4346,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { }}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "unsuccessful-run-no-returned-result", results: []v1.PipelineResult{{ @@ -4288,7 +4357,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { "customtask": {}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }, { description: "wrong-result-reference-expression", results: []v1.PipelineResult{{ @@ -4299,7 +4368,7 @@ func TestApplyTaskResultsToPipelineResults_Error(t *testing.T) { "customtask": {}, }, expectedResults: nil, - expectedError: fmt.Errorf("invalid pipelineresults [foo], the referenced results don't exist"), + expectedError: errors.New("invalid pipelineresults [foo], the referenced results don't exist"), }} { t.Run(tc.description, func(t *testing.T) { received, err := resources.ApplyTaskResultsToPipelineResults(context.Background(), tc.results, tc.taskResults, tc.runResults, nil /*skipped tasks*/) @@ -4683,6 +4752,7 @@ func TestPropagateResults(t *testing.T) { }) } } + func TestApplyParametersToWorkspaceBindings(t *testing.T) { testCases := []struct { name string @@ -5057,6 +5127,7 @@ func TestApplyParametersToWorkspaceBindings(t *testing.T) { }) } } + func TestApplyResultsToWorkspaceBindings(t *testing.T) { testCases := []struct { name string diff --git a/pkg/reconciler/pipelinerun/resources/pipelineref_test.go b/pkg/reconciler/pipelinerun/resources/pipelineref_test.go index 564a5160996..93d01a52ecc 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelineref_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelineref_test.go @@ -74,7 +74,8 @@ var ( unsignedV1beta1Pipeline = &v1beta1.Pipeline{ TypeMeta: metav1.TypeMeta{ APIVersion: "tekton.dev/v1beta1", - Kind: "Pipeline"}, + Kind: "Pipeline", + }, ObjectMeta: metav1.ObjectMeta{ Name: "test-pipeline", Namespace: "trusted-resources", @@ -553,6 +554,7 @@ func TestGetPipelineFunc_RemoteResolutionInvalidData(t *testing.T) { } } +//nolint:musttag func TestGetPipelineFunc_V1beta1Pipeline_VerifyNoError(t *testing.T) { ctx := context.Background() signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) @@ -657,76 +659,77 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyNoError(t *testing.T) { expected runtime.Object expectedRefSource *v1.RefSource expectedVerificationResult *trustedresources.VerificationResult - }{{ - name: "signed pipeline with matching policy pass verification with enforce no match policy", - requester: requesterMatched, - verificationNoMatchPolicy: config.FailNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: signedV1Pipeline, - expectedRefSource: matchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, - }, { - name: "signed pipeline with matching policy pass verification with warn no match policy", - requester: requesterMatched, - verificationNoMatchPolicy: config.WarnNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: signedV1Pipeline, - expectedRefSource: matchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, - }, { - name: "signed pipeline with matching policy pass verification with ignore no match policy", - requester: requesterMatched, - verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: signedV1Pipeline, - expectedRefSource: matchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, - }, { - name: "warn unsigned pipeline without matching policies", - requester: requesterUnmatched, - verificationNoMatchPolicy: config.WarnNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: unsignedV1Pipeline, - expectedRefSource: noMatchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrNoMatchedPolicies}, - }, { - name: "unsigned pipeline fails warn mode policies doesn't return error", - requester: requesterUnsignedMatched, - verificationNoMatchPolicy: config.FailNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: unsignedV1Pipeline, - expectedRefSource: warnPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrResourceVerificationFailed}, - }, { - name: "ignore unsigned pipeline without matching policies", - requester: requesterUnmatched, - verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: unsignedV1Pipeline, - expectedRefSource: noMatchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationSkip}, - }, { - name: "signed pipeline in status no need to verify", - requester: requesterMatched, - verificationNoMatchPolicy: config.FailNoMatchPolicy, - pipelinerun: prWithStatus, - policies: vps, - expected: &v1.Pipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: signedV1Pipeline.Name, - Namespace: signedV1Pipeline.Namespace, + }{ + { + name: "signed pipeline with matching policy pass verification with enforce no match policy", + requester: requesterMatched, + verificationNoMatchPolicy: config.FailNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: signedV1Pipeline, + expectedRefSource: matchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, + }, { + name: "signed pipeline with matching policy pass verification with warn no match policy", + requester: requesterMatched, + verificationNoMatchPolicy: config.WarnNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: signedV1Pipeline, + expectedRefSource: matchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, + }, { + name: "signed pipeline with matching policy pass verification with ignore no match policy", + requester: requesterMatched, + verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: signedV1Pipeline, + expectedRefSource: matchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, + }, { + name: "warn unsigned pipeline without matching policies", + requester: requesterUnmatched, + verificationNoMatchPolicy: config.WarnNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: unsignedV1Pipeline, + expectedRefSource: noMatchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrNoMatchedPolicies}, + }, { + name: "unsigned pipeline fails warn mode policies doesn't return error", + requester: requesterUnsignedMatched, + verificationNoMatchPolicy: config.FailNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: unsignedV1Pipeline, + expectedRefSource: warnPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrResourceVerificationFailed}, + }, { + name: "ignore unsigned pipeline without matching policies", + requester: requesterUnmatched, + verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: unsignedV1Pipeline, + expectedRefSource: noMatchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationSkip}, + }, { + name: "signed pipeline in status no need to verify", + requester: requesterMatched, + verificationNoMatchPolicy: config.FailNoMatchPolicy, + pipelinerun: prWithStatus, + policies: vps, + expected: &v1.Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: signedV1Pipeline.Name, + Namespace: signedV1Pipeline.Namespace, + }, + Spec: signedV1Pipeline.Spec, }, - Spec: signedV1Pipeline.Spec, + expectedRefSource: noMatchPolicyRefSource, + expectedVerificationResult: nil, }, - expectedRefSource: noMatchPolicyRefSource, - expectedVerificationResult: nil, - }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { @@ -756,6 +759,7 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyNoError(t *testing.T) { } } +//nolint:musttag func TestGetPipelineFunc_V1beta1Pipeline_VerifyError(t *testing.T) { ctx := context.Background() tektonclient := fake.NewSimpleClientset() @@ -875,6 +879,7 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyError(t *testing.T) { } } +//nolint:musttag func TestGetPipelineFunc_V1Pipeline_VerifyNoError(t *testing.T) { ctx := context.Background() signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) @@ -987,76 +992,77 @@ func TestGetPipelineFunc_V1Pipeline_VerifyNoError(t *testing.T) { expected runtime.Object expectedRefSource *v1.RefSource expectedVerificationResult *trustedresources.VerificationResult - }{{ - name: "signed pipeline with matching policy pass verification with enforce no match policy", - requester: requesterMatched, - verificationNoMatchPolicy: config.FailNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: signedPipeline, - expectedRefSource: matchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, - }, { - name: "signed pipeline with matching policy pass verification with warn no match policy", - requester: requesterMatched, - verificationNoMatchPolicy: config.WarnNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: signedPipeline, - expectedRefSource: matchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, - }, { - name: "signed pipeline with matching policy pass verification with ignore no match policy", - requester: requesterMatched, - verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: signedPipeline, - expectedRefSource: matchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, - }, { - name: "warn unsigned pipeline without matching policies", - requester: requesterUnmatched, - verificationNoMatchPolicy: config.WarnNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: unsignedV1Pipeline, - expectedRefSource: noMatchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrNoMatchedPolicies}, - }, { - name: "unsigned pipeline fails warn mode policies doesn't return error", - requester: requesterUnsignedMatched, - verificationNoMatchPolicy: config.FailNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: unsignedV1Pipeline, - expectedRefSource: warnPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrResourceVerificationFailed}, - }, { - name: "ignore unsigned pipeline without matching policies", - requester: requesterUnmatched, - verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, - pipelinerun: pr, - policies: vps, - expected: unsignedV1Pipeline, - expectedRefSource: noMatchPolicyRefSource, - expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationSkip}, - }, { - name: "signed pipeline in status no need to verify", - requester: requesterMatched, - verificationNoMatchPolicy: config.FailNoMatchPolicy, - pipelinerun: prWithStatus, - policies: vps, - expected: &v1.Pipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: signedPipeline.Name, - Namespace: signedPipeline.Namespace, + }{ + { + name: "signed pipeline with matching policy pass verification with enforce no match policy", + requester: requesterMatched, + verificationNoMatchPolicy: config.FailNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: signedPipeline, + expectedRefSource: matchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, + }, { + name: "signed pipeline with matching policy pass verification with warn no match policy", + requester: requesterMatched, + verificationNoMatchPolicy: config.WarnNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: signedPipeline, + expectedRefSource: matchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, + }, { + name: "signed pipeline with matching policy pass verification with ignore no match policy", + requester: requesterMatched, + verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: signedPipeline, + expectedRefSource: matchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationPass}, + }, { + name: "warn unsigned pipeline without matching policies", + requester: requesterUnmatched, + verificationNoMatchPolicy: config.WarnNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: unsignedV1Pipeline, + expectedRefSource: noMatchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrNoMatchedPolicies}, + }, { + name: "unsigned pipeline fails warn mode policies doesn't return error", + requester: requesterUnsignedMatched, + verificationNoMatchPolicy: config.FailNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: unsignedV1Pipeline, + expectedRefSource: warnPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationWarn, Err: trustedresources.ErrResourceVerificationFailed}, + }, { + name: "ignore unsigned pipeline without matching policies", + requester: requesterUnmatched, + verificationNoMatchPolicy: config.IgnoreNoMatchPolicy, + pipelinerun: pr, + policies: vps, + expected: unsignedV1Pipeline, + expectedRefSource: noMatchPolicyRefSource, + expectedVerificationResult: &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationSkip}, + }, { + name: "signed pipeline in status no need to verify", + requester: requesterMatched, + verificationNoMatchPolicy: config.FailNoMatchPolicy, + pipelinerun: prWithStatus, + policies: vps, + expected: &v1.Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: signedPipeline.Name, + Namespace: signedPipeline.Namespace, + }, + Spec: signedPipeline.Spec, }, - Spec: signedPipeline.Spec, + expectedRefSource: noMatchPolicyRefSource, + expectedVerificationResult: nil, }, - expectedRefSource: noMatchPolicyRefSource, - expectedVerificationResult: nil, - }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { @@ -1086,6 +1092,7 @@ func TestGetPipelineFunc_V1Pipeline_VerifyNoError(t *testing.T) { } } +//nolint:musttag func TestGetPipelineFunc_V1Pipeline_VerifyError(t *testing.T) { ctx := context.Background() tektonclient := fake.NewSimpleClientset() @@ -1202,6 +1209,7 @@ func TestGetPipelineFunc_V1Pipeline_VerifyError(t *testing.T) { } } +//nolint:musttag func TestGetPipelineFunc_GetFuncError(t *testing.T) { ctx := context.Background() tektonclient := fake.NewSimpleClientset() @@ -1215,7 +1223,7 @@ func TestGetPipelineFunc_GetFuncError(t *testing.T) { resolvedUnsigned := test.NewResolvedResource(unsignedPipelineBytes, nil, sampleRefSource.DeepCopy(), nil) requesterUnsigned := test.NewRequester(resolvedUnsigned, nil) - resolvedUnsigned.DataErr = fmt.Errorf("resolution error") + resolvedUnsigned.DataErr = errors.New("resolution error") prResolutionError := &v1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "trusted-resources"}, @@ -1361,7 +1369,7 @@ func getSignedV1Pipeline(unsigned *v1.Pipeline, signer signature.Signer, name st func signInterface(signer signature.Signer, i interface{}) ([]byte, error) { if signer == nil { - return nil, fmt.Errorf("signer is nil") + return nil, errors.New("signer is nil") } b, err := json.Marshal(i) if err != nil { diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go index 6f1cadc34af..a06b50d156e 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go @@ -676,7 +676,7 @@ func GetTaskRunName(childRefs []v1.ChildStatusReference, ptName, prName string) return cr.Name } } - return kmeta.ChildName(prName, fmt.Sprintf("-%s", ptName)) + return kmeta.ChildName(prName, "-"+ptName) } // GetNamesOfTaskRuns should return unique names for `TaskRuns` if one has not already been defined, and the existing one otherwise. @@ -702,7 +702,7 @@ func getNewRunNames(ptName, prName string, numberOfRuns int) []string { var taskRunNames []string // If it is a singular TaskRun/CustomRun, we only append the ptName if numberOfRuns == 1 { - taskRunName := kmeta.ChildName(prName, fmt.Sprintf("-%s", ptName)) + taskRunName := kmeta.ChildName(prName, "-"+ptName) return append(taskRunNames, taskRunName) } // For a matrix we append i to then end of the fanned out TaskRuns "matrixed-pr-taskrun-0" @@ -710,7 +710,7 @@ func getNewRunNames(ptName, prName string, numberOfRuns int) []string { taskRunName := kmeta.ChildName(prName, fmt.Sprintf("-%s-%d", ptName, i)) // check if the taskRun name ends with a matrix instance count if !strings.HasSuffix(taskRunName, fmt.Sprintf("-%d", i)) { - taskRunName = kmeta.ChildName(prName, fmt.Sprintf("-%s", ptName)) + taskRunName = kmeta.ChildName(prName, "-"+ptName) // kmeta.ChildName limits the size of a name to max of 63 characters based on k8s guidelines // truncate the name such that "-" can be appended to the taskRun name longest := 63 - len(fmt.Sprintf("-%d", numberOfRuns)) @@ -733,7 +733,7 @@ func getCustomRunName(childRefs []v1.ChildStatusReference, ptName, prName string } } - return kmeta.ChildName(prName, fmt.Sprintf("-%s", ptName)) + return kmeta.ChildName(prName, "-"+ptName) } // getNamesOfCustomRuns should return a unique names for `CustomRuns` if they have not already been defined, diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go index a1633b68ea6..fe6deee7c78 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go @@ -48,9 +48,11 @@ import ( func nopGetCustomRun(string) (*v1beta1.CustomRun, error) { return nil, errors.New("GetRun should not be called") } + func nopGetTask(context.Context, string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) { return nil, nil, nil, errors.New("GetTask should not be called") } + func nopGetTaskRun(string) (*v1.TaskRun, error) { return nil, errors.New("GetTaskRun should not be called") } @@ -128,14 +130,16 @@ var pts = []v1.PipelineTask{{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, }, { Name: "mytask17", Matrix: &v1.Matrix{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, }, { Name: "mytask18", TaskRef: &v1.TaskRef{Name: "task"}, @@ -144,7 +148,8 @@ var pts = []v1.PipelineTask{{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, }, { Name: "mytask19", TaskRef: &v1.TaskRef{APIVersion: "example.dev/v0", Kind: "Example", Name: "customtask"}, @@ -152,7 +157,8 @@ var pts = []v1.PipelineTask{{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, }, { Name: "mytask20", TaskRef: &v1.TaskRef{APIVersion: "example.dev/v0", Kind: "Example", Name: "customtask"}, @@ -160,7 +166,8 @@ var pts = []v1.PipelineTask{{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, }, { Name: "mytask21", TaskRef: &v1.TaskRef{Name: "task"}, @@ -169,7 +176,8 @@ var pts = []v1.PipelineTask{{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, }} var p = &v1.Pipeline{ @@ -243,12 +251,14 @@ var matrixedPipelineTask = &v1.PipelineTask{ Image: "bash:latest", Script: `#!/usr/bin/env bash\necho -n "$(params.browser)" | sha256sum | tee $(results.BROWSER.path)"`, }}, - }}, + }, + }, Matrix: &v1.Matrix{ Params: v1.Params{{ Name: "browser", Value: v1.ParamValue{ArrayVal: []string{"safari", "chrome"}}, - }}}, + }}, + }, } func makeScheduled(tr v1.TaskRun) *v1.TaskRun { @@ -1137,7 +1147,8 @@ func TestIsSkipped(t *testing.T) { Type: v1.ParamTypeArray, ArrayVal: []string{"foo", "bar"}, }, - }}}, + }}, + }, }, TaskRunNames: []string{"pipelinerun-matrix-empty-params"}, TaskRuns: nil, @@ -1156,7 +1167,8 @@ func TestIsSkipped(t *testing.T) { Type: v1.ParamTypeArray, ArrayVal: []string{}, }, - }}}, + }}, + }, }, TaskRunNames: []string{"pipelinerun-matrix-empty-params"}, TaskRuns: nil, @@ -1181,7 +1193,8 @@ func TestIsSkipped(t *testing.T) { Type: v1.ParamTypeArray, ArrayVal: []string{}, }, - }}}, + }}, + }, }, TaskRunNames: []string{"pipelinerun-matrix-empty-params"}, TaskRuns: nil, @@ -2317,7 +2330,8 @@ func TestSkipBecauseParentTaskWasSkipped(t *testing.T) { } func getExpectedMessage(runName string, specStatus v1.PipelineRunSpecStatus, status corev1.ConditionStatus, - successful, incomplete, skipped, failed, cancelled int) string { + successful, incomplete, skipped, failed, cancelled int, +) string { if status == corev1.ConditionFalse && (specStatus == v1.PipelineRunSpecStatusCancelledRunFinally || specStatus == v1.PipelineRunSpecStatusStoppedRunFinally) { @@ -2475,7 +2489,8 @@ func TestResolvePipelineRun_TaskDoesntExist(t *testing.T) { Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r"), }}, - }}} + }, + }} // Return an error when the Task is retrieved, as if it didn't exist getTask := func(ctx context.Context, name string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) { @@ -2518,7 +2533,8 @@ func TestResolvePipelineRun_VerificationFailed(t *testing.T) { Name: "bar", Value: *v1.NewStructuredValues("b", "a", "r"), }}, - }}} + }, + }} verificationResult := &trustedresources.VerificationResult{VerificationResultType: trustedresources.VerificationError, Err: trustedresources.ErrResourceVerificationFailed} getTask := func(ctx context.Context, name string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) { return task, nil, verificationResult, nil @@ -2984,7 +3000,8 @@ func TestResolvedPipelineRunTask_IsFinallySkipped(t *testing.T) { Params: v1.Params{{ Name: "platform", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{}}, - }}}, + }}, + }, }, }} @@ -3206,7 +3223,8 @@ func TestResolvedPipelineRunTask_IsFinallySkippedByCondition(t *testing.T) { }, }, }, - }}, + }, + }, want: TaskSkipStatus{ IsSkipped: false, SkippingReason: v1.None, @@ -3271,23 +3289,24 @@ func TestResolvedPipelineRunTask_IsFinalTask(t *testing.T) { }, } - state := PipelineRunState{{ - TaskRunNames: []string{"dag-task"}, - TaskRuns: []*v1.TaskRun{tr}, - PipelineTask: &v1.PipelineTask{ - Name: "dag-task", - TaskRef: &v1.TaskRef{Name: "task"}, - }, - }, { - PipelineTask: &v1.PipelineTask{ - Name: "final-task", - TaskRef: &v1.TaskRef{Name: "task"}, - Params: v1.Params{{ - Name: "commit", - Value: *v1.NewStructuredValues("$(tasks.dag-task.results.commit)"), - }}, + state := PipelineRunState{ + { + TaskRunNames: []string{"dag-task"}, + TaskRuns: []*v1.TaskRun{tr}, + PipelineTask: &v1.PipelineTask{ + Name: "dag-task", + TaskRef: &v1.TaskRef{Name: "task"}, + }, + }, { + PipelineTask: &v1.PipelineTask{ + Name: "final-task", + TaskRef: &v1.TaskRef{Name: "task"}, + Params: v1.Params{{ + Name: "commit", + Value: *v1.NewStructuredValues("$(tasks.dag-task.results.commit)"), + }}, + }, }, - }, } tasks := v1.PipelineTaskList([]v1.PipelineTask{*state[0].PipelineTask}) @@ -3575,7 +3594,8 @@ func TestIsMatrixed(t *testing.T) { Params: v1.Params{{ Name: "platform", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}}, - }}}, + }}, + }, }, want: true, }, { @@ -3597,7 +3617,8 @@ func TestIsMatrixed(t *testing.T) { Params: v1.Params{{ Name: "platform", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}}, - }}}, + }}, + }, }, want: true, }, { @@ -3665,7 +3686,8 @@ func TestResolvePipelineRunTask_WithMatrix(t *testing.T) { Params: v1.Params{{ Name: "platform", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}}, - }}}, + }}, + }, }, { Name: "pipelinetask", TaskRef: &v1.TaskRef{ @@ -3699,7 +3721,7 @@ func TestResolvePipelineRunTask_WithMatrix(t *testing.T) { }}}, } - var pipelineRunState = PipelineRunState{{ + pipelineRunState := PipelineRunState{{ TaskRunNames: []string{"get-platforms"}, TaskRuns: []*v1.TaskRun{{ ObjectMeta: metav1.ObjectMeta{ @@ -3824,7 +3846,8 @@ func TestResolvePipelineRunTask_WithMatrixedCustomTask(t *testing.T) { Params: v1.Params{{ Name: "platform", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"linux", "mac", "windows"}}, - }}}, + }}, + }, }, { Name: "pipelinetask", TaskRef: &v1.TaskRef{ @@ -3839,7 +3862,8 @@ func TestResolvePipelineRunTask_WithMatrixedCustomTask(t *testing.T) { }, { Name: "browsers", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"chrome", "safari", "firefox"}}, - }}}, + }}, + }, }, { Name: "customTask-with-whole-array-results", TaskRef: &v1.TaskRef{APIVersion: "example.dev/v0", Kind: "Example", Name: "aTask"}, @@ -3849,7 +3873,7 @@ func TestResolvePipelineRunTask_WithMatrixedCustomTask(t *testing.T) { }}, }} - var pipelineRunState = PipelineRunState{{ + pipelineRunState := PipelineRunState{{ TaskRunNames: []string{"get-platforms"}, TaskRuns: []*v1.TaskRun{{ ObjectMeta: metav1.ObjectMeta{ @@ -4997,25 +5021,26 @@ func TestEvaluateCEL_invalid(t *testing.T) { for _, tc := range []struct { name string rpt *ResolvedPipelineTask - }{{ - name: "compile error - token unrecogniezd", - rpt: &ResolvedPipelineTask{ - PipelineTask: &v1.PipelineTask{ - When: v1.WhenExpressions{{ - CEL: "$(params.foo)=='foo'", - }}, + }{ + { + name: "compile error - token unrecogniezd", + rpt: &ResolvedPipelineTask{ + PipelineTask: &v1.PipelineTask{ + When: v1.WhenExpressions{{ + CEL: "$(params.foo)=='foo'", + }}, + }, }, - }, - }, { - name: "CEL result is not true or false", - rpt: &ResolvedPipelineTask{ - PipelineTask: &v1.PipelineTask{ - When: v1.WhenExpressions{{ - CEL: "{'blue': '0x000080', 'red': '0xFF0000'}['red']", - }}, + }, { + name: "CEL result is not true or false", + rpt: &ResolvedPipelineTask{ + PipelineTask: &v1.PipelineTask{ + When: v1.WhenExpressions{{ + CEL: "{'blue': '0x000080', 'red': '0xFF0000'}['red']", + }}, + }, }, }, - }, } { t.Run(tc.name, func(t *testing.T) { err := tc.rpt.EvaluateCEL() @@ -5256,7 +5281,7 @@ func TestValidateParamEnumSubset_Invalid(t *testing.T) { }, }, }, - wantErr: fmt.Errorf("pipeline param \"p1\" enum: [v1 v2] is not a subset of the referenced in \"ref1\" task param enum: [v1 v3]"), + wantErr: errors.New("pipeline param \"p1\" enum: [v1 v2] is not a subset of the referenced in \"ref1\" task param enum: [v1 v3]"), }, { name: "empty pipeline enum with non-empty task enum - fail", params: []v1.Param{ @@ -5284,7 +5309,7 @@ func TestValidateParamEnumSubset_Invalid(t *testing.T) { }, }, }, - wantErr: fmt.Errorf("pipeline param \"p1\" has no enum, but referenced in \"ref1\" task has enums: [v1 v3]"), + wantErr: errors.New("pipeline param \"p1\" has no enum, but referenced in \"ref1\" task has enums: [v1 v3]"), }, { name: "invalid param syntax - failure", params: []v1.Param{ @@ -5295,7 +5320,7 @@ func TestValidateParamEnumSubset_Invalid(t *testing.T) { }, }, }, - wantErr: fmt.Errorf("unexpected error in ExtractVariablesFromString: Invalid referencing of parameters in \"$(params.p1.aaa.bbb)\"! Only two dot-separated components after the prefix \"params\" are allowed."), + wantErr: errors.New("unexpected error in ExtractVariablesFromString: Invalid referencing of parameters in \"$(params.p1.aaa.bbb)\"! Only two dot-separated components after the prefix \"params\" are allowed."), }} for _, tc := range tcs { diff --git a/pkg/reconciler/pipelinerun/resources/validate_params_test.go b/pkg/reconciler/pipelinerun/resources/validate_params_test.go index 4b6e667d8fc..9f32d1d6290 100644 --- a/pkg/reconciler/pipelinerun/resources/validate_params_test.go +++ b/pkg/reconciler/pipelinerun/resources/validate_params_test.go @@ -17,7 +17,7 @@ limitations under the License. package resources_test import ( - "fmt" + "errors" "testing" "github.com/google/go-cmp/cmp" @@ -212,7 +212,8 @@ func TestValidateObjectParamRequiredKeys_Invalid(t *testing.T) { Name: "an-object-param", Value: *v1.NewObject(map[string]string{ "foo": "val1", - })}, + }), + }, }, }, { name: "miss one of the required keys", @@ -231,7 +232,8 @@ func TestValidateObjectParamRequiredKeys_Invalid(t *testing.T) { Name: "an-object-param", Value: *v1.NewObject(map[string]string{ "key1": "foo", - })}, + }), + }, }, }} { t.Run(tc.name, func(t *testing.T) { @@ -270,7 +272,8 @@ func TestValidateObjectParamRequiredKeys_Valid(t *testing.T) { Name: "an-object-param", Value: *v1.NewObject(map[string]string{ "key2": "val2", - })}, + }), + }, }, }, { name: "all keys are provided with a value", @@ -290,7 +293,8 @@ func TestValidateObjectParamRequiredKeys_Valid(t *testing.T) { Value: *v1.NewObject(map[string]string{ "key1": "val1", "key2": "val2", - })}, + }), + }, }, }, { name: "extra keys are provided", @@ -311,7 +315,8 @@ func TestValidateObjectParamRequiredKeys_Valid(t *testing.T) { "key1": "val1", "key2": "val2", "key3": "val3", - })}, + }), + }, }, }} { t.Run(tc.name, func(t *testing.T) { @@ -338,7 +343,8 @@ func TestValidatePipelineParameterTypes(t *testing.T) { Params: v1.Params{{ Name: "foobar", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"foo", "bar"}}, }, { - Name: "barfoo", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"bar", "foo"}}}}, + Name: "barfoo", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"bar", "foo"}}, + }}, }, }, }}, @@ -352,7 +358,8 @@ func TestValidatePipelineParameterTypes(t *testing.T) { Name: "foo", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "foo"}, }, { Name: "bar", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "bar"}, - }}}, + }}, + }, }, }}, wantErrs: "parameters of type array only are allowed, but param \"foo\" has type \"string\" in pipelineTask \"task\"", @@ -367,8 +374,10 @@ func TestValidatePipelineParameterTypes(t *testing.T) { Params: v1.Params{{ Name: "foo", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "foo"}, }, { - Name: "bar", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "bar"}}}, - }}}, + Name: "bar", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "bar"}, + }}, + }}, + }, }, }}, }, { @@ -382,8 +391,10 @@ func TestValidatePipelineParameterTypes(t *testing.T) { Params: v1.Params{{ Name: "foobar", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"foo", "bar"}}, }, { - Name: "barfoo", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"bar", "foo"}}}}, - }}}, + Name: "barfoo", Value: v1.ParamValue{Type: v1.ParamTypeArray, ArrayVal: []string{"bar", "foo"}}, + }}, + }}, + }, }, }}, wantErrs: "parameters of type string only are allowed, but param \"foobar\" has type \"array\" in pipelineTask \"task\"", @@ -406,7 +417,8 @@ func TestValidatePipelineParameterTypes(t *testing.T) { "commit": "$(params.myString)", }}, }}, - }}}, + }}, + }, }, }}, wantErrs: "parameters of type string only are allowed, but param \"barfoo\" has type \"object\" in pipelineTask \"task\"", @@ -418,7 +430,8 @@ func TestValidatePipelineParameterTypes(t *testing.T) { Matrix: &v1.Matrix{ Params: v1.Params{{ Name: "url", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: `$(tasks.matrix-emitting-results.results.report-url[*])`}, - }}}, + }}, + }, }, }}, }} { @@ -439,162 +452,163 @@ func TestValidateParamArrayIndex_valid(t *testing.T) { name string original v1.PipelineSpec params v1.Params - }{{ - name: "single parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[1])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[0])")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }{ + { + name: "single parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - }, { - name: "single parameter with when expression", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "$(params.first-param[1])", - Operator: selection.In, - Values: []string{"$(params.second-param[0])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[1])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[0])")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - }, { - name: "pipeline parameter nested inside task parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param[0]))")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param[1]))")}, - }, - }}, - }, - params: nil, // no parameter values. - }, { - name: "array parameter", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param)")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param[0])")}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + }, { + name: "single parameter with when expression", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: v1.Params{ - {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, - }, - }, { - name: "parameter evaluation with final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "$(params.first-param[1])", + Operator: selection.In, + Values: []string{"$(params.second-param[0])"}, + }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + }, { + name: "pipeline parameter nested inside task parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param[0])", - Operator: selection.In, - Values: []string{"$(params.second-param[1])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param[0]))")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param[1]))")}, + }, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - }, { - name: "parameter evaluation with both tasks and final tasks", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, + params: nil, // no parameter values. + }, { + name: "array parameter", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param)")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param[0])")}, + }, + }}, + }, + params: v1.Params{ + {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, + }, + }, { + name: "parameter evaluation with final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param[0])", - Operator: selection.In, - Values: []string{"$(params.second-param[1])"}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param[0])", + Operator: selection.In, + Values: []string{"$(params.second-param[1])"}, + }}, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - }, { - name: "parameter references with bracket notation and special characters", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second/param", Type: v1.ParamTypeArray}, - {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "fourth/param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"][0])`)}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"][0])`)}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'][1])`)}, - {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'][1])`)}, - {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + }, { + name: "parameter evaluation with both tasks and final tasks", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - }, - params: v1.Params{ - {Name: "second/param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}, - {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value", "fourth-value-again")}, - }, - }, { - name: "single parameter in workspace subpath", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, + }}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[1])")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param[0])", + Operator: selection.In, + Values: []string{"$(params.second-param[1])"}, + }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + }, { + name: "parameter references with bracket notation and special characters", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second/param", Type: v1.ParamTypeArray}, + {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "fourth/param", Type: v1.ParamTypeArray}, }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "$(params.second-param[1])", + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"][0])`)}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"][0])`)}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'][1])`)}, + {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'][1])`)}, + {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, }, + }}, + }, + params: v1.Params{ + {Name: "second/param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}, + {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value", "fourth-value-again")}, + }, + }, { + name: "single parameter in workspace subpath", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[0])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "$(params.second-param[1])", + }, + }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - }, } { tt := tt // capture range variable t.Run(tt.name, func(t *testing.T) { @@ -613,213 +627,215 @@ func TestValidateParamArrayIndex_invalid(t *testing.T) { original v1.PipelineSpec params v1.Params expected error - }{{ - name: "single parameter reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[2])")}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }{ + { + name: "single parameter reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), - }, { - name: "single parameter reference with when expression out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeString}, - }, - Tasks: []v1.PipelineTask{{ - When: []v1.WhenExpression{{ - Input: "$(params.first-param[2])", - Operator: selection.In, - Values: []string{"$(params.second-param[2])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[2])")}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues("static value")}, + }, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), - }, { - name: "pipeline parameter reference nested inside task parameter out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param[2]))")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param[2]))")}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: errors.New("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), + }, { + name: "single parameter reference with when expression out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeString}, }, - }}, - }, - params: nil, // no parameter values. - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), - }, { - name: "array parameter reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param[3])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param[4])")}, + Tasks: []v1.PipelineTask{{ + When: []v1.WhenExpression{{ + Input: "$(params.first-param[2])", + Operator: selection.In, + Values: []string{"$(params.second-param[2])"}, + }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: errors.New("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), + }, { + name: "pipeline parameter reference nested inside task parameter out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, }, - }}, - }, - params: v1.Params{ - {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, - }, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[3]) $(params.second-param[4])]"), - }, { - name: "object parameter reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewObject(map[string]string{ - "val1": "$(params.first-param[4])", - "val2": "$(params.second-param[4])", - })}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.first-param[2]))")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("$(input.workspace.$(params.second-param[2]))")}, + }, + }}, + }, + params: nil, // no parameter values. + expected: errors.New("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), + }, { + name: "array parameter reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - }, - params: v1.Params{ - {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, - }, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[4]) $(params.second-param[4])]"), - }, { - name: "parameter evaluation with final tasks reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[2])")}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("firstelement", "$(params.first-param[3])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("firstelement", "$(params.second-param[4])")}, + }, + }}, + }, + params: v1.Params{ + {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, + }, + expected: errors.New("non-existent param references:[$(params.first-param[3]) $(params.second-param[4])]"), + }, { + name: "object parameter reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default", "array", "value")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param[0])", - Operator: selection.In, - Values: []string{"$(params.second-param[1])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewObject(map[string]string{ + "val1": "$(params.first-param[4])", + "val2": "$(params.second-param[4])", + })}, + }, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), - }, { - name: "parameter evaluation with both tasks and final tasks reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[2])")}, + }, + params: v1.Params{ + {Name: "second-param", Value: *v1.NewStructuredValues("second-value", "array")}, + }, + expected: errors.New("non-existent param references:[$(params.first-param[4]) $(params.second-param[4])]"), + }, { + name: "parameter evaluation with final tasks reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - }}, - Finally: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[3])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[3])")}, + Finally: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[2])")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param[0])", + Operator: selection.In, + Values: []string{"$(params.second-param[1])"}, + }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: errors.New("non-existent param references:[$(params.first-param[2]) $(params.second-param[2])]"), + }, { + name: "parameter evaluation with both tasks and final tasks reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, }, - When: v1.WhenExpressions{{ - Input: "$(params.first-param[2])", - Operator: selection.In, - Values: []string{"$(params.second-param[2])"}, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[2])")}, + }, }}, - Matrix: &v1.Matrix{ + Finally: []v1.PipelineTask{{ Params: v1.Params{ - {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[4])")}, - {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[4])")}, + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[3])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[3])")}, + }, + When: v1.WhenExpressions{{ + Input: "$(params.first-param[2])", + Operator: selection.In, + Values: []string{"$(params.second-param[2])"}, }}, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2]) $(params.first-param[3]) $(params.first-param[4]) $(params.second-param[2]) $(params.second-param[3]) $(params.second-param[4])]"), - }, { - name: "parameter in matrix reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, + Matrix: &v1.Matrix{ + Params: v1.Params{ + {Name: "final-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[4])")}, + {Name: "final-task-second-param", Value: *v1.NewStructuredValues("$(params.second-param[4])")}, + }, + }, + }}, }, - Tasks: []v1.PipelineTask{{ - Matrix: &v1.Matrix{ + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: errors.New("non-existent param references:[$(params.first-param[2]) $(params.first-param[3]) $(params.first-param[4]) $(params.second-param[2]) $(params.second-param[3]) $(params.second-param[4])]"), + }, { + name: "parameter in matrix reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, + }, + Tasks: []v1.PipelineTask{{ + Matrix: &v1.Matrix{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, + }, + }, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: errors.New("non-existent param references:[$(params.first-param[2])]"), + }, { + name: "parameter references with bracket notation and special characters reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second/param", Type: v1.ParamTypeArray}, + {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "fourth/param", Type: v1.ParamTypeArray}, + }, + Tasks: []v1.PipelineTask{{ + Params: v1.Params{ + {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"][2])`)}, + {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"][2])`)}, + {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'][2])`)}, + {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'][2])`)}, + {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, + }, + }}, + }, + params: v1.Params{ + {Name: "second/param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}, + {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value", "fourth-value-again")}, + }, + expected: errors.New("non-existent param references:[$(params[\"first.param\"][2]) $(params[\"second/param\"][2]) $(params['fourth/param'][2]) $(params['third.param'][2])]"), + }, { + name: "single parameter in workspace subpath reference out of bound", + original: v1.PipelineSpec{ + Params: []v1.ParamSpec{ + {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, + {Name: "second-param", Type: v1.ParamTypeArray}, + }, + Tasks: []v1.PipelineTask{{ Params: v1.Params{ {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, }, - }, - }}, - }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2])]"), - }, { - name: "parameter references with bracket notation and special characters reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second/param", Type: v1.ParamTypeArray}, - {Name: "third.param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "fourth/param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues(`$(params["first.param"][2])`)}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues(`$(params["second/param"][2])`)}, - {Name: "first-task-third-param", Value: *v1.NewStructuredValues(`$(params['third.param'][2])`)}, - {Name: "first-task-fourth-param", Value: *v1.NewStructuredValues(`$(params['fourth/param'][2])`)}, - {Name: "first-task-fifth-param", Value: *v1.NewStructuredValues("static value")}, - }, - }}, - }, - params: v1.Params{ - {Name: "second/param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}, - {Name: "fourth/param", Value: *v1.NewStructuredValues("fourth-value", "fourth-value-again")}, - }, - expected: fmt.Errorf("non-existent param references:[$(params[\"first.param\"][2]) $(params[\"second/param\"][2]) $(params['fourth/param'][2]) $(params['third.param'][2])]"), - }, { - name: "single parameter in workspace subpath reference out of bound", - original: v1.PipelineSpec{ - Params: []v1.ParamSpec{ - {Name: "first-param", Type: v1.ParamTypeArray, Default: v1.NewStructuredValues("default-value", "default-value-again")}, - {Name: "second-param", Type: v1.ParamTypeArray}, - }, - Tasks: []v1.PipelineTask{{ - Params: v1.Params{ - {Name: "first-task-first-param", Value: *v1.NewStructuredValues("$(params.first-param[2])")}, - {Name: "first-task-second-param", Value: *v1.NewStructuredValues("static value")}, - }, - Workspaces: []v1.WorkspacePipelineTaskBinding{ - { - Name: "first-workspace", - Workspace: "first-workspace", - SubPath: "$(params.second-param[3])", + Workspaces: []v1.WorkspacePipelineTaskBinding{ + { + Name: "first-workspace", + Workspace: "first-workspace", + SubPath: "$(params.second-param[3])", + }, }, - }, - }}, + }}, + }, + params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, + expected: errors.New("non-existent param references:[$(params.first-param[2]) $(params.second-param[3])]"), }, - params: v1.Params{{Name: "second-param", Value: *v1.NewStructuredValues("second-value", "second-value-again")}}, - expected: fmt.Errorf("non-existent param references:[$(params.first-param[2]) $(params.second-param[3])]"), - }, } { tt := tt // capture range variable t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/reconciler/pipelinerun/tracing.go b/pkg/reconciler/pipelinerun/tracing.go index 461c7d86f73..8aedd34948e 100644 --- a/pkg/reconciler/pipelinerun/tracing.go +++ b/pkg/reconciler/pipelinerun/tracing.go @@ -19,7 +19,7 @@ package pipelinerun import ( "context" "encoding/json" - "fmt" + "errors" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "go.opentelemetry.io/otel" @@ -88,7 +88,7 @@ func getMarshalledSpanFromContext(ctx context.Context) (string, error) { pro.Inject(ctx, propagation.MapCarrier(carrier)) if len(carrier) == 0 { - return "", fmt.Errorf("spanContext not present in the context, unable to marshall") + return "", errors.New("spanContext not present in the context, unable to marshall") } marshalled, err := json.Marshal(carrier) @@ -96,7 +96,7 @@ func getMarshalledSpanFromContext(ctx context.Context) (string, error) { return "", err } if len(marshalled) >= 1024 { - return "", fmt.Errorf("marshalled spanContext size is too big") + return "", errors.New("marshalled spanContext size is too big") } return string(marshalled), nil } diff --git a/pkg/reconciler/taskrun/resources/taskref_test.go b/pkg/reconciler/taskrun/resources/taskref_test.go index 27379a2f94b..a88928b708a 100644 --- a/pkg/reconciler/taskrun/resources/taskref_test.go +++ b/pkg/reconciler/taskrun/resources/taskref_test.go @@ -298,7 +298,7 @@ func TestLocalTaskRef(t *testing.T) { ref: &v1.TaskRef{ Name: "simple", }, - wantErr: fmt.Errorf("must specify namespace to resolve reference to task simple"), + wantErr: errors.New("must specify namespace to resolve reference to task simple"), }, } @@ -433,7 +433,7 @@ func TestStepActionRef_Error(t *testing.T) { ref: &v1.Ref{ Name: "simple", }, - wantErr: fmt.Errorf("must specify namespace to resolve reference to step action simple"), + wantErr: errors.New("must specify namespace to resolve reference to step action simple"), }, } @@ -1053,6 +1053,7 @@ func TestGetPipelineFunc_RemoteResolutionInvalidData(t *testing.T) { } } +//nolint:musttag func TestGetTaskFunc_V1beta1Task_VerifyNoError(t *testing.T) { ctx := context.Background() signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) @@ -1187,6 +1188,7 @@ func TestGetTaskFunc_V1beta1Task_VerifyNoError(t *testing.T) { } } +//nolint:musttag func TestGetTaskFunc_V1beta1Task_VerifyError(t *testing.T) { ctx := context.Background() signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) @@ -1307,6 +1309,7 @@ func TestGetTaskFunc_V1beta1Task_VerifyError(t *testing.T) { } } +//nolint:musttag func TestGetTaskFunc_V1Task_VerifyNoError(t *testing.T) { ctx := context.Background() signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) @@ -1451,6 +1454,7 @@ func TestGetTaskFunc_V1Task_VerifyNoError(t *testing.T) { } } +//nolint:musttag func TestGetTaskFunc_V1Task_VerifyError(t *testing.T) { ctx := context.Background() signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) @@ -1566,6 +1570,7 @@ func TestGetTaskFunc_V1Task_VerifyError(t *testing.T) { } } +//nolint:musttag func TestGetTaskFunc_GetFuncError(t *testing.T) { ctx := context.Background() _, k8sclient, vps := test.SetupMatchAllVerificationPolicies(t, "trusted-resources") @@ -1579,7 +1584,7 @@ func TestGetTaskFunc_GetFuncError(t *testing.T) { resolvedUnsigned := test.NewResolvedResource(unsignedTaskBytes, nil, sampleRefSource.DeepCopy(), nil) requesterUnsigned := test.NewRequester(resolvedUnsigned, nil) - resolvedUnsigned.DataErr = fmt.Errorf("resolution error") + resolvedUnsigned.DataErr = errors.New("resolution error") trResolutionError := &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "trusted-resources"}, @@ -1688,7 +1693,7 @@ func getSignedV1Task(unsigned *v1.Task, signer signature.Signer, name string) (* func signInterface(signer signature.Signer, i interface{}) ([]byte, error) { if signer == nil { - return nil, fmt.Errorf("signer is nil") + return nil, errors.New("signer is nil") } b, err := json.Marshal(i) if err != nil { diff --git a/pkg/reconciler/taskrun/resources/taskspec_test.go b/pkg/reconciler/taskrun/resources/taskspec_test.go index 2fdde6b2b6e..361ce2f0050 100644 --- a/pkg/reconciler/taskrun/resources/taskspec_test.go +++ b/pkg/reconciler/taskrun/resources/taskspec_test.go @@ -19,7 +19,6 @@ package resources_test import ( "context" "errors" - "fmt" "testing" "time" @@ -61,7 +60,6 @@ func TestGetTaskSpec_Ref(t *testing.T) { return task, sampleRefSource.DeepCopy(), nil, nil } resolvedObjectMeta, taskSpec, err := resources.GetTaskData(context.Background(), tr, gt) - if err != nil { t.Fatalf("Did not expect error getting task spec but got: %s", err) } @@ -95,7 +93,6 @@ func TestGetTaskSpec_Embedded(t *testing.T) { return nil, nil, nil, errors.New("shouldn't be called") } resolvedObjectMeta, taskSpec, err := resources.GetTaskData(context.Background(), tr, gt) - if err != nil { t.Fatalf("Did not expect error getting task spec but got: %s", err) } @@ -1002,7 +999,7 @@ func TestGetStepActionsData_Error(t *testing.T) { }, }, stepAction: &v1alpha1.StepAction{}, - expectedError: fmt.Errorf("must specify namespace to resolve reference to step action stepActionError"), + expectedError: errors.New("must specify namespace to resolve reference to step action stepActionError"), }, { name: "params missing", tr: &v1.TaskRun{ @@ -1033,7 +1030,7 @@ func TestGetStepActionsData_Error(t *testing.T) { }}, }, }, - expectedError: fmt.Errorf("non-existent params in Step: [string-param]"), + expectedError: errors.New("non-existent params in Step: [string-param]"), }, { name: "params extra", tr: &v1.TaskRun{ @@ -1064,7 +1061,7 @@ func TestGetStepActionsData_Error(t *testing.T) { Image: "myimage", }, }, - expectedError: fmt.Errorf("extra params passed by Step to StepAction: [string-param]"), + expectedError: errors.New("extra params passed by Step to StepAction: [string-param]"), }} for _, tt := range tests { ctx := context.Background() diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index 256364c2333..2440624d563 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -169,14 +169,15 @@ var ( ObjectMeta: objectMeta("test-results-task", "foo"), Spec: v1.TaskSpec{ Steps: []v1.Step{simpleStep}, - Results: []v1.TaskResult{{ - Name: "aResult", - Type: v1.ResultsTypeArray, - }, { - Name: "objectResult", - Type: v1.ResultsTypeObject, - Properties: map[string]v1.PropertySpec{"url": {Type: "string"}, "commit": {Type: "string"}}, - }, + Results: []v1.TaskResult{ + { + Name: "aResult", + Type: v1.ResultsTypeArray, + }, { + Name: "objectResult", + Type: v1.ResultsTypeObject, + Properties: map[string]v1.PropertySpec{"url": {Type: "string"}, "commit": {Type: "string"}}, + }, }, }, } @@ -1185,7 +1186,7 @@ spec: } // Mock a successful resolution - var taskBytes = []byte(` + taskBytes := []byte(` kind: Task apiVersion: tekton.dev/v1 metadata: @@ -1651,7 +1652,7 @@ status: startTime: "2021-12-31T23:59:59Z" completionTime: "2022-01-01T00:00:00Z" `) - prepareError = fmt.Errorf("1 error occurred:\n\t* error when listing tasks for taskRun test-taskrun-run-retry-prepare-failure: tasks.tekton.dev \"test-task\" not found") + prepareError = errors.New("1 error occurred:\n\t* error when listing tasks for taskRun test-taskrun-run-retry-prepare-failure: tasks.tekton.dev \"test-task\" not found") toFailOnReconcileFailureTaskRun = parse.MustParseV1TaskRun(t, ` metadata: name: test-taskrun-results-type-mismatched @@ -1716,7 +1717,7 @@ status: MaxResultSize: 4096 Coschedule: "workspaces" `, pipelineErrors.UserErrorLabel, pipelineErrors.UserErrorLabel)) - reconciliatonError = fmt.Errorf("1 error occurred:\n\t* Provided results don't match declared results; may be invalid JSON or missing result declaration: \"aResult\": task result is expected to be \"array\" type but was initialized to a different type \"string\"") + reconciliatonError = errors.New("1 error occurred:\n\t* Provided results don't match declared results; may be invalid JSON or missing result declaration: \"aResult\": task result is expected to be \"array\" type but was initialized to a different type \"string\"") toBeRetriedTaskRun = parse.MustParseV1TaskRun(t, ` metadata: name: test-taskrun-to-be-retried @@ -2918,7 +2919,8 @@ status: - status: Unknown type: Succeeded `), - }} + }, + } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { @@ -3037,7 +3039,8 @@ status: wantEvents: []string{ "Warning Failed ", }, - }} + }, + } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { @@ -3898,7 +3901,7 @@ spec: func TestExpandMountPath(t *testing.T) { expectedMountPath := "/temppath/replaced" - expectedReplacedArgs := fmt.Sprintf("replacedArgs - %s", expectedMountPath) + expectedReplacedArgs := "replacedArgs - " + expectedMountPath // The task's Workspace has a parameter variable simpleTask := parse.MustParseV1Task(t, ` metadata: @@ -3982,7 +3985,6 @@ spec: } pod, err := r.createPod(testAssets.Ctx, taskSpec, taskRun, rtr, workspaceVolumes) - if err != nil { t.Fatalf("create pod threw error %v", err) } @@ -4137,47 +4139,48 @@ status: expectedType apis.ConditionType expectedStatus corev1.ConditionStatus expectedReason string - }{{ - description: "ResourceQuotaConflictError does not fail taskrun", - err: k8sapierrors.NewConflict(k8sruntimeschema.GroupResource{Group: "v1", Resource: "resourcequotas"}, "sample", errors.New("operation cannot be fulfilled on resourcequotas sample the object has been modified please apply your changes to the latest version and try again")), - expectedType: apis.ConditionSucceeded, - expectedStatus: corev1.ConditionUnknown, - expectedReason: podconvert.ReasonPodPending, - }, { - description: "exceeded quota errors are surfaced in taskrun condition but do not fail taskrun", - err: k8sapierrors.NewForbidden(k8sruntimeschema.GroupResource{Group: "foo", Resource: "bar"}, "baz", errors.New("exceeded quota")), - expectedType: apis.ConditionSucceeded, - expectedStatus: corev1.ConditionUnknown, - expectedReason: podconvert.ReasonExceededResourceQuota, - }, { - description: "taskrun validation failed", - err: errors.New("TaskRun validation failed"), - expectedType: apis.ConditionSucceeded, - expectedStatus: corev1.ConditionFalse, - expectedReason: v1.TaskRunReasonFailedValidation.String(), - }, { - description: "errors other than exceeded quota fail the taskrun", - err: errors.New("this is a fatal error"), - expectedType: apis.ConditionSucceeded, - expectedStatus: corev1.ConditionFalse, - expectedReason: podconvert.ReasonPodCreationFailed, - }, { - description: "errors violating PodSecurity fail the taskrun", - err: k8sapierrors.NewForbidden(k8sruntimeschema.GroupResource{Group: "foo", Resource: "bar"}, "baz", - errors.New("violates PodSecurity \"restricted:latest\": allowPrivilegeEscalation != false ("+ - "containers \"prepare\", \"place-scripts\", \"test-task\", \"test-task\" must set securityContext."+ - "allowPrivilegeEscalation=false)")), - expectedType: apis.ConditionSucceeded, - expectedStatus: corev1.ConditionFalse, - expectedReason: podconvert.ReasonPodAdmissionFailed, - }, { - description: "errors validating security context constraint (Openshift) fail the taskrun", - err: k8sapierrors.NewForbidden(k8sruntimeschema.GroupResource{Group: "foo", Resource: "bar"}, "baz", - errors.New("unable to validate against any security context constraint: [provider restricted: .spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used provider restricted: .spec.securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used")), - expectedType: apis.ConditionSucceeded, - expectedStatus: corev1.ConditionFalse, - expectedReason: podconvert.ReasonPodAdmissionFailed, - }, + }{ + { + description: "ResourceQuotaConflictError does not fail taskrun", + err: k8sapierrors.NewConflict(k8sruntimeschema.GroupResource{Group: "v1", Resource: "resourcequotas"}, "sample", errors.New("operation cannot be fulfilled on resourcequotas sample the object has been modified please apply your changes to the latest version and try again")), + expectedType: apis.ConditionSucceeded, + expectedStatus: corev1.ConditionUnknown, + expectedReason: podconvert.ReasonPodPending, + }, { + description: "exceeded quota errors are surfaced in taskrun condition but do not fail taskrun", + err: k8sapierrors.NewForbidden(k8sruntimeschema.GroupResource{Group: "foo", Resource: "bar"}, "baz", errors.New("exceeded quota")), + expectedType: apis.ConditionSucceeded, + expectedStatus: corev1.ConditionUnknown, + expectedReason: podconvert.ReasonExceededResourceQuota, + }, { + description: "taskrun validation failed", + err: errors.New("TaskRun validation failed"), + expectedType: apis.ConditionSucceeded, + expectedStatus: corev1.ConditionFalse, + expectedReason: v1.TaskRunReasonFailedValidation.String(), + }, { + description: "errors other than exceeded quota fail the taskrun", + err: errors.New("this is a fatal error"), + expectedType: apis.ConditionSucceeded, + expectedStatus: corev1.ConditionFalse, + expectedReason: podconvert.ReasonPodCreationFailed, + }, { + description: "errors violating PodSecurity fail the taskrun", + err: k8sapierrors.NewForbidden(k8sruntimeschema.GroupResource{Group: "foo", Resource: "bar"}, "baz", + errors.New("violates PodSecurity \"restricted:latest\": allowPrivilegeEscalation != false ("+ + "containers \"prepare\", \"place-scripts\", \"test-task\", \"test-task\" must set securityContext."+ + "allowPrivilegeEscalation=false)")), + expectedType: apis.ConditionSucceeded, + expectedStatus: corev1.ConditionFalse, + expectedReason: podconvert.ReasonPodAdmissionFailed, + }, { + description: "errors validating security context constraint (Openshift) fail the taskrun", + err: k8sapierrors.NewForbidden(k8sruntimeschema.GroupResource{Group: "foo", Resource: "bar"}, "baz", + errors.New("unable to validate against any security context constraint: [provider restricted: .spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used provider restricted: .spec.securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used")), + expectedType: apis.ConditionSucceeded, + expectedStatus: corev1.ConditionFalse, + expectedReason: podconvert.ReasonPodAdmissionFailed, + }, } for _, tc := range testcases { t.Run(tc.description, func(t *testing.T) { @@ -4201,6 +4204,7 @@ status: }) } } + func TestReconcile_Single_SidecarState(t *testing.T) { runningState := corev1.ContainerStateRunning{StartedAt: metav1.Time{Time: now}} taskRun := parse.MustParseV1TaskRun(t, ` @@ -5226,7 +5230,7 @@ spec: resolvedObjectMeta *resolutionutil.ResolvedObjectMeta } - var tests = []struct { + tests := []struct { name string reconcile1Args *args reconcile2Args *args @@ -5638,7 +5642,8 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { { Image: "image", Command: []string{"cmd"}, - }}, + }, + }, StepTemplate: &v1.StepTemplate{ ComputeResources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ @@ -5759,7 +5764,8 @@ func Test_validateTaskSpecRequestResources_InvalidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("4Gi"), }, }, - }}}, + }}, + }, }, { name: "step request larger than steptemplate limit", taskSpec: &v1.TaskSpec{ @@ -5920,7 +5926,7 @@ type stepForExpectedPod struct { func expectedPod(podName, taskName, taskRunName, ns, saName string, isClusterTask bool, extraVolumes []corev1.Volume, steps []stepForExpectedPod) *corev1.Pod { stepNames := make([]string, 0, len(steps)) for _, s := range steps { - stepNames = append(stepNames, fmt.Sprintf("step-%s", s.name)) + stepNames = append(stepNames, "step-"+s.name) } p := &corev1.Pod{ ObjectMeta: podObjectMeta(podName, taskName, taskRunName, ns, isClusterTask), @@ -5949,7 +5955,7 @@ func expectedPod(podName, taskName, taskRunName, ns, saName string, isClusterTas stepContainer := corev1.Container{ Image: s.image, - Name: fmt.Sprintf("step-%s", s.name), + Name: "step-" + s.name, Command: []string{entrypointLocation}, VolumeMounts: podVolumeMounts(idx, len(steps)), TerminationMessagePath: "/tekton/termination", @@ -6165,7 +6171,7 @@ spec: }}, } - expectedErr := fmt.Errorf("1 error occurred:\n\t* param `param1` value: invalid is not in the enum list") + expectedErr := errors.New("1 error occurred:\n\t* param `param1` value: invalid is not in the enum list") expectedFailureReason := "InvalidParamValue" testAssets, cancel := getTaskRunController(t, d) defer cancel() @@ -6327,13 +6333,13 @@ status: name: "taskrun results type mismatched", taskRun: taskRunResultsTypeMismatched, wantFailedReason: v1.TaskRunReasonFailedValidation.String(), - expectedError: fmt.Errorf("1 error occurred:\n\t* Provided results don't match declared results; may be invalid JSON or missing result declaration: \"aResult\": task result is expected to be \"array\" type but was initialized to a different type \"string\", \"objectResult\": task result is expected to be \"object\" type but was initialized to a different type \"string\""), + expectedError: errors.New("1 error occurred:\n\t* Provided results don't match declared results; may be invalid JSON or missing result declaration: \"aResult\": task result is expected to be \"array\" type but was initialized to a different type \"string\", \"objectResult\": task result is expected to be \"object\" type but was initialized to a different type \"string\""), expectedResults: nil, }, { name: "taskrun results object miss key", taskRun: taskRunResultsObjectMissKey, wantFailedReason: v1.TaskRunReasonFailedValidation.String(), - expectedError: fmt.Errorf("1 error occurred:\n\t* missing keys for these results which are required in TaskResult's properties map[objectResult:[commit]]"), + expectedError: errors.New("1 error occurred:\n\t* missing keys for these results which are required in TaskResult's properties map[objectResult:[commit]]"), expectedResults: []v1.TaskRunResult{ { Name: "aResult", @@ -6343,7 +6349,8 @@ status: Name: "objectResult", Type: "object", Value: *v1.NewObject(map[string]string{"url": "abc"}), - }}, + }, + }, }} { t.Run(tc.name, func(t *testing.T) { testAssets, cancel := getTaskRunController(t, d) @@ -6474,7 +6481,8 @@ spec: }, Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: "no-match"}}, - }}} + }, + }} // warnPolicy doesn't contain keys so it will fail verification but doesn't fail the run warnPolicy := []*v1alpha1.VerificationPolicy{{ ObjectMeta: metav1.ObjectMeta{ @@ -6484,7 +6492,8 @@ spec: Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: ".*"}}, Mode: v1alpha1.ModeWarn, - }}} + }, + }} tr := parse.MustParseV1TaskRun(t, fmt.Sprintf(` metadata: name: test-taskrun @@ -6520,27 +6529,28 @@ status: noMatchPolicy string verificationPolicies []*v1alpha1.VerificationPolicy wantTrustedResourcesCondition *apis.Condition - }{{ - name: "ignore no match policy", - noMatchPolicy: config.IgnoreNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: nil, - }, { - name: "warn no match policy", - noMatchPolicy: config.WarnNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: failNoMatchCondition, - }, { - name: "pass enforce policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: vps, - wantTrustedResourcesCondition: passCondition, - }, { - name: "only fail warn policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: warnPolicy, - wantTrustedResourcesCondition: failNoKeysCondition, - }, + }{ + { + name: "ignore no match policy", + noMatchPolicy: config.IgnoreNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: nil, + }, { + name: "warn no match policy", + noMatchPolicy: config.WarnNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: failNoMatchCondition, + }, { + name: "pass enforce policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: vps, + wantTrustedResourcesCondition: passCondition, + }, { + name: "only fail warn policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: warnPolicy, + wantTrustedResourcesCondition: failNoKeysCondition, + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -6729,7 +6739,8 @@ spec: }, Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: "no-match"}}, - }}} + }, + }} // warnPolicy doesn't contain keys so it will fail verification but doesn't fail the run warnPolicy := []*v1alpha1.VerificationPolicy{{ ObjectMeta: metav1.ObjectMeta{ @@ -6739,7 +6750,8 @@ spec: Spec: v1alpha1.VerificationPolicySpec{ Resources: []v1alpha1.ResourcePattern{{Pattern: ".*"}}, Mode: v1alpha1.ModeWarn, - }}} + }, + }} tr := parse.MustParseV1TaskRun(t, fmt.Sprintf(` metadata: name: test-taskrun @@ -6775,27 +6787,28 @@ status: noMatchPolicy string verificationPolicies []*v1alpha1.VerificationPolicy wantTrustedResourcesCondition *apis.Condition - }{{ - name: "ignore no match policy", - noMatchPolicy: config.IgnoreNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: nil, - }, { - name: "warn no match policy", - noMatchPolicy: config.WarnNoMatchPolicy, - verificationPolicies: noMatchPolicy, - wantTrustedResourcesCondition: failNoMatchCondition, - }, { - name: "pass enforce policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: vps, - wantTrustedResourcesCondition: passCondition, - }, { - name: "only fail warn policy", - noMatchPolicy: config.FailNoMatchPolicy, - verificationPolicies: warnPolicy, - wantTrustedResourcesCondition: failNoKeysCondition, - }, + }{ + { + name: "ignore no match policy", + noMatchPolicy: config.IgnoreNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: nil, + }, { + name: "warn no match policy", + noMatchPolicy: config.WarnNoMatchPolicy, + verificationPolicies: noMatchPolicy, + wantTrustedResourcesCondition: failNoMatchCondition, + }, { + name: "pass enforce policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: vps, + wantTrustedResourcesCondition: passCondition, + }, { + name: "only fail warn policy", + noMatchPolicy: config.FailNoMatchPolicy, + verificationPolicies: warnPolicy, + wantTrustedResourcesCondition: failNoKeysCondition, + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -7013,7 +7026,7 @@ func getSignedV1Task(unsigned *v1.Task, signer signature.Signer, name string) (* func signInterface(signer signature.Signer, i interface{}) ([]byte, error) { if signer == nil { - return nil, fmt.Errorf("signer is nil") + return nil, errors.New("signer is nil") } b, err := json.Marshal(i) if err != nil { diff --git a/pkg/reconciler/taskrun/validate_taskrun_test.go b/pkg/reconciler/taskrun/validate_taskrun_test.go index 04dac06da69..b03d023887f 100644 --- a/pkg/reconciler/taskrun/validate_taskrun_test.go +++ b/pkg/reconciler/taskrun/validate_taskrun_test.go @@ -18,7 +18,7 @@ package taskrun import ( "context" - "fmt" + "errors" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -128,6 +128,7 @@ func TestValidateResolvedTask_ValidParams(t *testing.T) { t.Errorf("Did not expect to see error when validating TaskRun with correct params but saw %v", err) } } + func TestValidateResolvedTask_ExtraValidParams(t *testing.T) { ctx := context.Background() tcs := []struct { @@ -305,7 +306,8 @@ func TestValidateResolvedTask_InvalidParams(t *testing.T) { }}, matrix: &v1.Matrix{}, wantErr: "invalid input params for task : param types don't match the user-specified type: [foo]", - }, {name: "missing-param-in-matrix", + }, { + name: "missing-param-in-matrix", task: v1.Task{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: v1.TaskSpec{ @@ -320,7 +322,8 @@ func TestValidateResolvedTask_InvalidParams(t *testing.T) { Params: v1.Params{{ Name: "missing", Value: *v1.NewStructuredValues("foo"), - }}}, + }}, + }, wantErr: "invalid input params for task : missing values for these params which have no default values: [bar]", }, { name: "missing-param-in-matrix-include", @@ -359,7 +362,8 @@ func TestValidateResolvedTask_InvalidParams(t *testing.T) { Params: v1.Params{{ Name: "bar", Value: *v1.NewStructuredValues("foo"), - }}}, + }}, + }, wantErr: "invalid input params for task : param types don't match the user-specified type: [bar]", }, { name: "invalid-str-in-matrix-include-param", @@ -773,7 +777,8 @@ func TestValidateResult(t *testing.T) { { Name: "array-result-1", Type: v1.ResultsTypeArray, - }, { + }, + { Name: "array-result-2", Type: v1.ResultsTypeArray, }, @@ -797,7 +802,8 @@ func TestValidateResult(t *testing.T) { Name: "array-result-1", Type: v1.ResultsTypeObject, Value: *v1.NewObject(map[string]string{"hello": "world"}), - }, { + }, + { Name: "array-result-2", Type: v1.ResultsTypeString, Value: *v1.NewStructuredValues(""), @@ -942,7 +948,7 @@ func TestEnumValidation_Failure(t *testing.T) { Enum: []string{"v1", "v2", "v3"}, }, }, - expectedErr: fmt.Errorf("param `p1` value: v4 is not in the enum list"), + expectedErr: errors.New("param `p1` value: v4 is not in the enum list"), }} for _, tc := range tcs { diff --git a/pkg/reconciler/volumeclaim/pvchandler.go b/pkg/reconciler/volumeclaim/pvchandler.go index b8c8de27fba..40f02fd430f 100644 --- a/pkg/reconciler/volumeclaim/pvchandler.go +++ b/pkg/reconciler/volumeclaim/pvchandler.go @@ -19,6 +19,7 @@ package volumeclaim import ( "context" "crypto/sha256" + "encoding/hex" "encoding/json" "fmt" @@ -159,6 +160,6 @@ func GeneratePVCNameFromWorkspaceBinding(claimName string, wb v1.WorkspaceBindin func getPersistentVolumeClaimIdentity(workspaceName, ownerName string) string { hashBytes := sha256.Sum256([]byte(workspaceName + ownerName)) - hashString := fmt.Sprintf("%x", hashBytes) + hashString := hex.EncodeToString(hashBytes[:]) return hashString[:10] } diff --git a/pkg/remote/oci/resolver.go b/pkg/remote/oci/resolver.go index fe44b801222..54ce6ca6f30 100644 --- a/pkg/remote/oci/resolver.go +++ b/pkg/remote/oci/resolver.go @@ -189,7 +189,7 @@ func readTarLayer(layer v1.Layer) (runtime.Object, error) { treader := tar.NewReader(rc) header, err := treader.Next() if err != nil { - return nil, fmt.Errorf("layer is not a tarball") + return nil, errors.New("layer is not a tarball") } contents := make([]byte, header.Size) diff --git a/pkg/resolution/common/interface.go b/pkg/resolution/common/interface.go index 3d2941c8aed..3a1968f3695 100644 --- a/pkg/resolution/common/interface.go +++ b/pkg/resolution/common/interface.go @@ -33,7 +33,7 @@ type ResolverName string type Requester interface { // Submit accepts the name of a resolver to submit a request to // along with the request itself. - Submit(context.Context, ResolverName, Request) (ResolvedResource, error) + Submit(ctx context.Context, name ResolverName, req Request) (ResolvedResource, error) } // Request is implemented by any type that represents a single request diff --git a/pkg/resolution/resolver/bundle/bundle.go b/pkg/resolution/resolver/bundle/bundle.go index e8f2ddac41b..0b150031b25 100644 --- a/pkg/resolution/resolver/bundle/bundle.go +++ b/pkg/resolution/resolver/bundle/bundle.go @@ -189,7 +189,7 @@ func readTarLayer(layer v1.Layer) ([]byte, error) { treader := tar.NewReader(rc) header, err := treader.Next() if err != nil { - return nil, fmt.Errorf("layer is not a tarball") + return nil, errors.New("layer is not a tarball") } contents := make([]byte, header.Size) diff --git a/pkg/resolution/resolver/bundle/params.go b/pkg/resolution/resolver/bundle/params.go index aaaf2a6cd4b..d410a699f7f 100644 --- a/pkg/resolution/resolver/bundle/params.go +++ b/pkg/resolution/resolver/bundle/params.go @@ -15,6 +15,7 @@ package bundle import ( "context" + "errors" "fmt" "github.com/google/go-containerregistry/pkg/name" @@ -67,7 +68,7 @@ func OptionsFromParams(ctx context.Context, params []pipelinev1.Param) (RequestO if kindString, ok := conf[ConfigKind]; ok { kind = kindString } else { - return opts, fmt.Errorf("default resource Kind was not set during installation of the bundle resolver") + return opts, errors.New("default resource Kind was not set during installation of the bundle resolver") } } else { kind = kindVal.StringVal diff --git a/pkg/resolution/resolver/cluster/resolver.go b/pkg/resolution/resolver/cluster/resolver.go index 44c5c800b9e..6483016b93b 100644 --- a/pkg/resolution/resolver/cluster/resolver.go +++ b/pkg/resolution/resolver/cluster/resolver.go @@ -284,7 +284,7 @@ func populateParamsWithDefaults(ctx context.Context, origParams []pipelinev1.Par } if conf[BlockedNamespacesKey] != "" && conf[BlockedNamespacesKey] == "*" { - return nil, fmt.Errorf("only explicit allowed access to namespaces is allowed") + return nil, errors.New("only explicit allowed access to namespaces is allowed") } if conf[AllowedNamespacesKey] != "" && !isInCommaSeparatedList(params[NamespaceParam], conf[AllowedNamespacesKey]) { diff --git a/pkg/resolution/resolver/framework/interface.go b/pkg/resolution/resolver/framework/interface.go index 0a0118c28da..33a9efab4d9 100644 --- a/pkg/resolution/resolver/framework/interface.go +++ b/pkg/resolution/resolver/framework/interface.go @@ -30,18 +30,18 @@ type Resolver interface { // Initialize is called at the moment the resolver controller is // instantiated and is a good place to setup things like // resource listers. - Initialize(context.Context) error + Initialize(ctx context.Context) error // GetName should give back the name of the resolver. E.g. "Git" - GetName(context.Context) string + GetName(ctx context.Context) string // GetSelector returns the labels that are used to direct resolution // requests to this resolver. - GetSelector(context.Context) map[string]string + GetSelector(ctx context.Context) map[string]string // ValidateParams is given the parameters from a resource // request and should return an error if any are missing or invalid. - ValidateParams(context.Context, []pipelinev1.Param) error + ValidateParams(ctx context.Context, params []pipelinev1.Param) error // Resolve receives the parameters passed via a resource request // and returns the resolved data along with any annotations @@ -49,7 +49,7 @@ type Resolver interface { // should be returned instead. If a resolution.Error // is returned then its Reason and Message are used as part of the // response to the request. - Resolve(context.Context, []pipelinev1.Param) (ResolvedResource, error) + Resolve(ctx context.Context, params []pipelinev1.Param) (ResolvedResource, error) } // ConfigWatcher is the interface to implement if your resolver accepts @@ -66,7 +66,7 @@ type ConfigWatcher interface { // GetConfigName should return a string name for its // configuration to be referenced by. This will map to the name // of a ConfigMap in the same namespace as the resolver. - GetConfigName(context.Context) string + GetConfigName(ctx context.Context) string } // TimedResolution is an optional interface that a resolver can @@ -88,7 +88,7 @@ type TimedResolution interface { // object, which includes any request-scoped data like // resolver config and the request's originating namespace, // along with a default. - GetResolutionTimeout(context.Context, time.Duration) time.Duration + GetResolutionTimeout(ctx context.Context, timeout time.Duration) time.Duration } // ResolvedResource returns the data and annotations of a successful diff --git a/pkg/resolution/resolver/git/resolver.go b/pkg/resolution/resolver/git/resolver.go index 3405eff6a78..34fcd6ad18f 100644 --- a/pkg/resolution/resolver/git/resolver.go +++ b/pkg/resolution/resolver/git/resolver.go @@ -221,7 +221,7 @@ func (r *Resolver) resolveAnonymousGit(ctx context.Context, params map[string]st if urlString, ok := conf[defaultURLKey]; ok { repo = urlString } else { - return nil, fmt.Errorf("default Git Repo Url was not set during installation of the git resolver") + return nil, errors.New("default Git Repo Url was not set during installation of the git resolver") } } revision := params[revisionParam] @@ -229,7 +229,7 @@ func (r *Resolver) resolveAnonymousGit(ctx context.Context, params map[string]st if revisionString, ok := conf[defaultRevisionKey]; ok { revision = revisionString } else { - return nil, fmt.Errorf("default Git Revision was not set during installation of the git resolver") + return nil, errors.New("default Git Revision was not set during installation of the git resolver") } } diff --git a/pkg/resolution/resolver/git/resolver_test.go b/pkg/resolution/resolver/git/resolver_test.go index a35ec7646a2..a9f4c0490d9 100644 --- a/pkg/resolution/resolver/git/resolver_test.go +++ b/pkg/resolution/resolver/git/resolver_test.go @@ -527,7 +527,7 @@ func TestResolve(t *testing.T) { APISecretNamespaceKey: system.Namespace(), }, expectedStatus: internal.CreateResolutionRequestFailureStatus(), - expectedErr: createError(fmt.Sprintf("cannot get API token, secret token-secret not found in namespace %s", system.Namespace())), + expectedErr: createError("cannot get API token, secret token-secret not found in namespace " + system.Namespace()), }, { name: "api: token secret name not specified", args: ¶ms{ @@ -765,7 +765,7 @@ func writeAndCommitToTestRepo(t *testing.T, worktree *git.Worktree, repoDir stri targetDir = filepath.Join(targetDir, subPath) fi, err := os.Stat(targetDir) if os.IsNotExist(err) { - if err := os.MkdirAll(targetDir, 0700); err != nil { + if err := os.MkdirAll(targetDir, 0o700); err != nil { t.Fatalf("couldn't create directory %s in worktree: %v", targetDir, err) } } else if err != nil { @@ -777,7 +777,7 @@ func writeAndCommitToTestRepo(t *testing.T, worktree *git.Worktree, repoDir stri } outfile := filepath.Join(targetDir, filename) - if err := os.WriteFile(outfile, content, 0600); err != nil { + if err := os.WriteFile(outfile, content, 0o600); err != nil { t.Fatalf("couldn't write content to file %s: %v", outfile, err) } diff --git a/pkg/resolution/resolver/http/resolver.go b/pkg/resolution/resolver/http/resolver.go index 9e920f360f8..49d75bd2dd1 100644 --- a/pkg/resolution/resolver/http/resolver.go +++ b/pkg/resolution/resolver/http/resolver.go @@ -286,6 +286,6 @@ func (r *Resolver) getBasicAuthSecret(ctx context.Context, params map[string]str r.logger.Info(err) return "", err } - return fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString( - []byte(fmt.Sprintf("%s:%s", userName, secretVal)))), nil + return "Basic " + base64.StdEncoding.EncodeToString( + []byte(fmt.Sprintf("%s:%s", userName, secretVal))), nil } diff --git a/pkg/resolution/resolver/http/resolver_test.go b/pkg/resolution/resolver/http/resolver_test.go index e2e8e7758be..630b3882d6e 100644 --- a/pkg/resolution/resolver/http/resolver_test.go +++ b/pkg/resolution/resolver/http/resolver_test.go @@ -87,14 +87,14 @@ func TestValidateParams(t *testing.T) { }, { name: "invalid/url", url: "xttps:ufoo/bar/", - expectedErr: fmt.Errorf(`url xttps:ufoo/bar/ is not a valid http(s) url`), + expectedErr: errors.New(`url xttps:ufoo/bar/ is not a valid http(s) url`), }, { name: "invalid/url empty", url: "", - expectedErr: fmt.Errorf(`cannot parse url : parse "": empty url`), + expectedErr: errors.New(`cannot parse url : parse "": empty url`), }, { name: "missing/url", - expectedErr: fmt.Errorf(`missing required http resolver params: url`), + expectedErr: errors.New(`missing required http resolver params: url`), url: "nourl", }, } @@ -129,7 +129,7 @@ func TestMakeHTTPClient(t *testing.T) { { name: "bad/duration", duration: "xxx", - expectedErr: fmt.Errorf(`error parsing timeout value xxx: time: invalid duration "xxx"`), + expectedErr: errors.New(`error parsing timeout value xxx: time: invalid duration "xxx"`), }, } for _, tc := range tests { diff --git a/pkg/resolution/resolver/hub/resolver.go b/pkg/resolution/resolver/hub/resolver.go index abbc19c1985..e94aa390fa5 100644 --- a/pkg/resolution/resolver/hub/resolver.go +++ b/pkg/resolution/resolver/hub/resolver.go @@ -237,13 +237,13 @@ func resolveCatalogName(paramsMap, conf map[string]string) (string, error) { var ok bool if configTHCatalog, ok = conf[ConfigTektonHubCatalog]; !ok { - return "", fmt.Errorf("default Tekton Hub catalog was not set during installation of the hub resolver") + return "", errors.New("default Tekton Hub catalog was not set during installation of the hub resolver") } if configAHTaskCatalog, ok = conf[ConfigArtifactHubTaskCatalog]; !ok { - return "", fmt.Errorf("default Artifact Hub task catalog was not set during installation of the hub resolver") + return "", errors.New("default Artifact Hub task catalog was not set during installation of the hub resolver") } if configAHPipelineCatalog, ok = conf[ConfigArtifactHubPipelineCatalog]; !ok { - return "", fmt.Errorf("default Artifact Hub pipeline catalog was not set during installation of the hub resolver") + return "", errors.New("default Artifact Hub pipeline catalog was not set during installation of the hub resolver") } if _, ok := paramsMap[ParamCatalog]; !ok { switch paramsMap[ParamType] { @@ -380,11 +380,11 @@ func (r *Resolver) validateParams(ctx context.Context, paramsMap map[string]stri } if hubType, ok := paramsMap[ParamType]; ok { if hubType != ArtifactHubType && hubType != TektonHubType { - return fmt.Errorf(fmt.Sprintf("type param must be %s or %s", ArtifactHubType, TektonHubType)) + return fmt.Errorf("type param must be %s or %s", ArtifactHubType, TektonHubType) } if hubType == TektonHubType && r.TektonHubURL == "" { - return fmt.Errorf("please configure TEKTON_HUB_API env variable to use tekton type") + return errors.New("please configure TEKTON_HUB_API env variable to use tekton type") } } @@ -407,7 +407,7 @@ func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[ if typeString, ok := conf[ConfigType]; ok { paramsMap[ParamType] = typeString } else { - return nil, fmt.Errorf("default type was not set during installation of the hub resolver") + return nil, errors.New("default type was not set during installation of the hub resolver") } } @@ -416,7 +416,7 @@ func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[ if kindString, ok := conf[ConfigKind]; ok { paramsMap[ParamKind] = kindString } else { - return nil, fmt.Errorf("default resource kind was not set during installation of the hub resolver") + return nil, errors.New("default resource kind was not set during installation of the hub resolver") } } diff --git a/pkg/resolution/resolver/hub/resolver_test.go b/pkg/resolution/resolver/hub/resolver_test.go index e6ba327c969..474838c1a7f 100644 --- a/pkg/resolution/resolver/hub/resolver_test.go +++ b/pkg/resolution/resolver/hub/resolver_test.go @@ -19,6 +19,7 @@ package hub import ( "context" "encoding/json" + "errors" "fmt" "net/http" "net/http/httptest" @@ -68,7 +69,7 @@ func TestValidateParams(t *testing.T) { version: "bar", catalog: "baz", hubType: TektonHubType, - expectedErr: fmt.Errorf("failed to validate params: please configure TEKTON_HUB_API env variable to use tekton type"), + expectedErr: errors.New("failed to validate params: please configure TEKTON_HUB_API env variable to use tekton type"), }, } @@ -301,7 +302,7 @@ func TestResolveConstraint(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("no version found for constraint >= 0.2.0"), + expectedErr: errors.New("no version found for constraint >= 0.2.0"), }, { name: "bad/tekton hub/no matching constraints", kind: "task", @@ -318,7 +319,7 @@ func TestResolveConstraint(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("no version found for constraint >= 0.2.0"), + expectedErr: errors.New("no version found for constraint >= 0.2.0"), }, } for _, tt := range tests { @@ -556,7 +557,7 @@ func TestResolve(t *testing.T) { catalog: "Tekton", hubType: TektonHubType, input: `value`, - expectedErr: fmt.Errorf("fail to fetch Tekton Hub resource: error unmarshalling json response: invalid character 'v' looking for beginning of value"), + expectedErr: errors.New("fail to fetch Tekton Hub resource: error unmarshalling json response: invalid character 'v' looking for beginning of value"), }, { name: "response with empty body error from Tekton Hub", @@ -565,7 +566,7 @@ func TestResolve(t *testing.T) { version: "baz", catalog: "Tekton", hubType: TektonHubType, - expectedErr: fmt.Errorf("fail to fetch Tekton Hub resource: error unmarshalling json response: unexpected end of JSON input"), + expectedErr: errors.New("fail to fetch Tekton Hub resource: error unmarshalling json response: unexpected end of JSON input"), }, { name: "response with empty body error from Artifact Hub", @@ -574,7 +575,7 @@ func TestResolve(t *testing.T) { version: "baz", catalog: "Tekton", hubType: ArtifactHubType, - expectedErr: fmt.Errorf("fail to fetch Artifact Hub resource: error unmarshalling json response: unexpected end of JSON input"), + expectedErr: errors.New("fail to fetch Artifact Hub resource: error unmarshalling json response: unexpected end of JSON input"), }, } diff --git a/pkg/spire/config/config.go b/pkg/spire/config/config.go index f8fed32dafc..4f1a4a5f252 100644 --- a/pkg/spire/config/config.go +++ b/pkg/spire/config/config.go @@ -17,6 +17,7 @@ limitations under the License. package config import ( + "errors" "fmt" "sort" "strings" @@ -62,7 +63,7 @@ func (c SpireConfig) Validate() error { } if !strings.HasPrefix(c.NodeAliasPrefix, "/") { - return fmt.Errorf("Spire node alias should start with a /") + return errors.New("Spire node alias should start with a /") } return nil diff --git a/pkg/spire/controller.go b/pkg/spire/controller.go index e26275491ff..db7fbe40f7a 100644 --- a/pkg/spire/controller.go +++ b/pkg/spire/controller.go @@ -223,18 +223,18 @@ func (sc *spireControllerAPIClient) CreateEntries(ctx context.Context, tr *v1bet return err } - if len(resp.Results) != len(entries) { + if len(resp.GetResults()) != len(entries) { return fmt.Errorf("batch create entry failed, malformed response expected %v result", len(entries)) } var errPaths []string var errCodes []int32 - for _, r := range resp.Results { - if codes.Code(r.Status.Code) != codes.AlreadyExists && - codes.Code(r.Status.Code) != codes.OK { - errPaths = append(errPaths, r.Entry.SpiffeId.Path) - errCodes = append(errCodes, r.Status.Code) + for _, r := range resp.GetResults() { + if codes.Code(r.GetStatus().GetCode()) != codes.AlreadyExists && + codes.Code(r.GetStatus().GetCode()) != codes.OK { + errPaths = append(errPaths, r.GetEntry().GetSpiffeId().GetPath()) + errCodes = append(errCodes, r.GetStatus().GetCode()) } } @@ -261,13 +261,13 @@ func (sc *spireControllerAPIClient) getEntries(ctx context.Context, tr *v1beta1. return nil, err } - entries = append(entries, resp.Entries...) + entries = append(entries, resp.GetEntries()...) - if resp.NextPageToken == "" { + if resp.GetNextPageToken() == "" { break } - req.PageToken = resp.NextPageToken + req.PageToken = resp.GetNextPageToken() } return entries, nil @@ -281,7 +281,7 @@ func (sc *spireControllerAPIClient) DeleteEntry(ctx context.Context, tr *v1beta1 var ids []string for _, e := range entries { - ids = append(ids, e.Id) + ids = append(ids, e.GetId()) } req := &entryv1.BatchDeleteEntryRequest{ @@ -295,11 +295,11 @@ func (sc *spireControllerAPIClient) DeleteEntry(ctx context.Context, tr *v1beta1 var errIds []string var errCodes []int32 - for _, r := range resp.Results { - if codes.Code(r.Status.Code) != codes.NotFound && - codes.Code(r.Status.Code) != codes.OK { - errIds = append(errIds, r.Id) - errCodes = append(errCodes, r.Status.Code) + for _, r := range resp.GetResults() { + if codes.Code(r.GetStatus().GetCode()) != codes.NotFound && + codes.Code(r.GetStatus().GetCode()) != codes.OK { + errIds = append(errIds, r.GetId()) + errCodes = append(errCodes, r.GetStatus().GetCode()) } } diff --git a/pkg/spire/verify.go b/pkg/spire/verify.go index fab083608fb..23616676899 100644 --- a/pkg/spire/verify.go +++ b/pkg/spire/verify.go @@ -150,6 +150,7 @@ func (sc *spireControllerAPIClient) CheckSpireVerifiedFlag(tr *v1beta1.TaskRun) return false } +//nolint:musttag func hashTaskrunStatusInternal(tr *v1beta1.TaskRun) (string, error) { s, err := json.Marshal(tr.Status.TaskRunStatusFields) if err != nil { diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index 7831d9af8b2..0a3904ee75d 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -171,14 +171,13 @@ func createTracerProvider(service string, cfg *config.Tracing, user, pass string creds := fmt.Sprintf("%s:%s", user, pass) enc := base64.StdEncoding.EncodeToString([]byte(creds)) o := otlptracehttp.WithHeaders(map[string]string{ - "Authorization": fmt.Sprintf("Basic %s", enc), + "Authorization": "Basic " + enc, }) opts = append(opts, o) } ctx := context.Background() exp, err := otlptracehttp.New(ctx, opts...) - if err != nil { return nil, err } diff --git a/pkg/trustedresources/verify_test.go b/pkg/trustedresources/verify_test.go index da972d3052a..04fde6cfeaf 100644 --- a/pkg/trustedresources/verify_test.go +++ b/pkg/trustedresources/verify_test.go @@ -25,7 +25,6 @@ import ( "encoding/base64" "encoding/json" "errors" - "fmt" "testing" "github.com/sigstore/sigstore/pkg/signature" @@ -48,7 +47,8 @@ var ( unsignedV1beta1Task = &v1beta1.Task{ TypeMeta: metav1.TypeMeta{ APIVersion: "tekton.dev/v1beta1", - Kind: "Task"}, + Kind: "Task", + }, ObjectMeta: metav1.ObjectMeta{ Name: "test-task", Namespace: "trusted-resources", @@ -64,7 +64,8 @@ var ( unsignedV1Task = v1.Task{ TypeMeta: metav1.TypeMeta{ APIVersion: "tekton.dev/v1", - Kind: "Task"}, + Kind: "Task", + }, ObjectMeta: metav1.ObjectMeta{ Name: "task", Annotations: map[string]string{"foo": "bar"}, @@ -79,7 +80,8 @@ var ( unsignedV1beta1Pipeline = &v1beta1.Pipeline{ TypeMeta: metav1.TypeMeta{ APIVersion: "tekton.dev/v1beta1", - Kind: "Pipeline"}, + Kind: "Pipeline", + }, ObjectMeta: metav1.ObjectMeta{ Name: "test-pipeline", Namespace: "trusted-resources", @@ -96,7 +98,8 @@ var ( unsignedV1Pipeline = v1.Pipeline{ TypeMeta: metav1.TypeMeta{ APIVersion: "tekton.dev/v1", - Kind: "Pipeline"}, + Kind: "Pipeline", + }, ObjectMeta: metav1.ObjectMeta{ Name: "pipeline", Annotations: map[string]string{"foo": "bar"}, @@ -500,6 +503,7 @@ func TestVerifyResource_V1Task_Success(t *testing.T) { t.Errorf("VerificationResult mismatch: want %v, got %v", VerificationPass, vr.VerificationResultType) } } + func TestVerifyResource_V1Task_Error(t *testing.T) { signer, _, k8sclient, vps := test.SetupVerificationPolicies(t) signedTask, err := getSignedV1Task(unsignedV1Task.DeepCopy(), signer, "signed") @@ -552,7 +556,7 @@ func TestVerifyResource_TypeNotSupported(t *testing.T) { func signInterface(signer signature.Signer, i interface{}) ([]byte, error) { if signer == nil { - return nil, fmt.Errorf("signer is nil") + return nil, errors.New("signer is nil") } b, err := json.Marshal(i) if err != nil { diff --git a/pkg/workspace/validate.go b/pkg/workspace/validate.go index 69a7d8b8ccf..879e6bda2b6 100644 --- a/pkg/workspace/validate.go +++ b/pkg/workspace/validate.go @@ -18,6 +18,7 @@ package workspace import ( "context" + "errors" "fmt" pipelineErrors "github.com/tektoncd/pipeline/pkg/apis/pipeline/errors" @@ -79,7 +80,7 @@ func ValidateOnlyOnePVCIsUsed(wb []v1.WorkspaceBinding) error { } if len(workspaceVolumes) > 1 { - return pipelineErrors.WrapUserError(fmt.Errorf("more than one PersistentVolumeClaim is bound")) + return pipelineErrors.WrapUserError(errors.New("more than one PersistentVolumeClaim is bound")) } return nil } diff --git a/test/conversion_test.go b/test/conversion_test.go index 1bbe8d3e200..aead7504501 100644 --- a/test/conversion_test.go +++ b/test/conversion_test.go @@ -1172,7 +1172,7 @@ func TestBundleConversion(t *testing.T) { knativetest.CleanupOnInterrupt(func() { tearDown(ctx, t, c, namespace) }, t.Logf) defer tearDown(ctx, t, c, namespace) - repo := fmt.Sprintf("%s:5000/tektonbundlessimple", getRegistryServiceIP(ctx, t, c, namespace)) + repo := getRegistryServiceIP(ctx, t, c, namespace) + ":5000/tektonbundlessimple" taskName := helpers.ObjectNameForTest(t) pipelineName := helpers.ObjectNameForTest(t) task := parse.MustParseV1beta1Task(t, fmt.Sprintf(v1beta1TaskWithBundleYaml, taskName, namespace)) diff --git a/test/custom_task_test.go b/test/custom_task_test.go index 657f7fb3974..001e61285a0 100644 --- a/test/custom_task_test.go +++ b/test/custom_task_test.go @@ -348,7 +348,7 @@ spec: t.Errorf("Error waiting for PipelineRun %s to finish: %s", pipelineRun.Name, err) } - customRunList, err := c.V1beta1CustomRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", pipelineRun.Name)}) + customRunList, err := c.V1beta1CustomRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + pipelineRun.Name}) if err != nil { t.Fatalf("Error listing Runs for PipelineRun %s: %s", pipelineRun.Name, err) } diff --git a/test/diff/print.go b/test/diff/print.go index f38803c348a..9c8a90f5f97 100644 --- a/test/diff/print.go +++ b/test/diff/print.go @@ -16,12 +16,10 @@ limitations under the License. package diff -import "fmt" - // PrintWantGot takes a diff string generated by cmp.Diff and returns it // in a consistent format for reuse across all of our tests. This // func assumes that the order of arguments passed to cmp.Diff was // (want, got) or, in other words, the expectedResult then the actualResult. func PrintWantGot(diff string) string { - return fmt.Sprintf("(-want, +got): %s", diff) + return "(-want, +got): " + diff } diff --git a/test/gohelloworld/main.go b/test/gohelloworld/main.go index f91732061f4..8c0bd0f8a5b 100644 --- a/test/gohelloworld/main.go +++ b/test/gohelloworld/main.go @@ -31,6 +31,7 @@ func main() { log.Print("Hello world sample started.") http.HandleFunc("/", handler) + //nolint:gosec // #nosec G114 -- see https://github.com/securego/gosec#available-rules if err := http.ListenAndServe(":8080", nil); err != nil { panic(err) diff --git a/test/hermetic_taskrun_test.go b/test/hermetic_taskrun_test.go index 2f262798066..6f256cc488c 100644 --- a/test/hermetic_taskrun_test.go +++ b/test/hermetic_taskrun_test.go @@ -57,7 +57,7 @@ func TestHermeticTaskRun(t *testing.T) { for _, test := range tests { t.Run(test.desc, func(t *testing.T) { // first, run the task run with hermetic=false to prove that it succeeds - regularTaskRunName := fmt.Sprintf("not-hermetic-%s", test.desc) + regularTaskRunName := "not-hermetic-" + test.desc regularTaskRun := test.getTaskRun(t, regularTaskRunName, namespace, "") t.Logf("Creating TaskRun %s, hermetic=false", regularTaskRunName) if _, err := c.V1TaskRunClient.Create(ctx, regularTaskRun, metav1.CreateOptions{}); err != nil { @@ -69,7 +69,7 @@ func TestHermeticTaskRun(t *testing.T) { // now, run the task mode with hermetic mode // it should fail, since it shouldn't be able to access any network - hermeticTaskRunName := fmt.Sprintf("hermetic-should-fail-%s", test.desc) + hermeticTaskRunName := "hermetic-should-fail-" + test.desc hermeticTaskRun := test.getTaskRun(t, hermeticTaskRunName, namespace, "hermetic") t.Logf("Creating TaskRun %s, hermetic=true", hermeticTaskRunName) if _, err := c.V1TaskRunClient.Create(ctx, hermeticTaskRun, metav1.CreateOptions{}); err != nil { diff --git a/test/matrix_test.go b/test/matrix_test.go index 02dd2728365..6dcdec5fe4e 100644 --- a/test/matrix_test.go +++ b/test/matrix_test.go @@ -21,6 +21,7 @@ package test import ( "context" + "fmt" "testing" "github.com/google/go-cmp/cmp" @@ -33,14 +34,11 @@ import ( duckv1 "knative.dev/pkg/apis/duck/v1" knativetest "knative.dev/pkg/test" "knative.dev/pkg/test/helpers" - - "fmt" ) -var ( - requireAlphaFeatureFlag = requireAnyGate(map[string]string{ - "enable-api-fields": "alpha"}) -) +var requireAlphaFeatureFlag = requireAnyGate(map[string]string{ + "enable-api-fields": "alpha", +}) // TestPipelineRunMatrixed is an integration test that verifies that a Matrixed PipelineRun // succeeds with both `matrix params` and `matrix include params`. It also tests array indexing @@ -363,7 +361,7 @@ spec: t.Fatalf("Error waiting for PipelineRun %s to finish: %s", prName, err) } - actualTaskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", prName)}) + actualTaskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + prName}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", prName, err) } diff --git a/test/pipelinerun_test.go b/test/pipelinerun_test.go index 9b69c966df4..64b8534f862 100644 --- a/test/pipelinerun_test.go +++ b/test/pipelinerun_test.go @@ -118,7 +118,7 @@ spec: t.Fatalf("Error waiting for PipelineRun %s to finish: %s", prName, err) } t.Logf("Making sure the expected TaskRuns %s were created", td.expectedTaskRuns) - actualTaskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", prName)}) + actualTaskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + prName}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", prName, err) } @@ -324,7 +324,7 @@ spec: t.Fatalf("Error waiting for PipelineRun %s to finish: %s", prName, err) } t.Logf("Making sure the expected TaskRuns %s were created", td.expectedTaskRuns) - actualTaskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", prName)}) + actualTaskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + prName}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", prName, err) } diff --git a/test/remote.go b/test/remote.go index 82c5bd877cf..382547ae993 100644 --- a/test/remote.go +++ b/test/remote.go @@ -19,6 +19,7 @@ package test import ( "archive/tar" "bytes" + "errors" "fmt" "reflect" "strings" @@ -36,16 +37,14 @@ import ( // ObjectAnnotationMapper is a func alias that maps a runtime Object to the Tekton Bundle annotations map. type ObjectAnnotationMapper func(object runtime.Object) map[string]string -var ( - // DefaultObjectAnnotationMapper does the "right" thing by conforming to the Tekton Bundle spec. - DefaultObjectAnnotationMapper = func(obj runtime.Object) map[string]string { - return map[string]string{ - tkremote.TitleAnnotation: GetObjectName(obj), - tkremote.KindAnnotation: strings.TrimSuffix(strings.ToLower(obj.GetObjectKind().GroupVersionKind().Kind), "s"), - tkremote.APIVersionAnnotation: obj.GetObjectKind().GroupVersionKind().Version, - } +// DefaultObjectAnnotationMapper does the "right" thing by conforming to the Tekton Bundle spec. +var DefaultObjectAnnotationMapper = func(obj runtime.Object) map[string]string { + return map[string]string{ + tkremote.TitleAnnotation: GetObjectName(obj), + tkremote.KindAnnotation: strings.TrimSuffix(strings.ToLower(obj.GetObjectKind().GroupVersionKind().Kind), "s"), + tkremote.APIVersionAnnotation: obj.GetObjectKind().GroupVersionKind().Version, } -) +} // CreateImage will push a new OCI image artifact with the provided raw data object as a layer and return the full image // reference with a digest to fetch the image. Key must be specified as [lowercase kind]/[object name]. The image ref @@ -75,7 +74,7 @@ func CreateImageWithAnnotations(ref string, mapper ObjectAnnotationMapper, objs writer := tar.NewWriter(&tarbundle) if err := writer.WriteHeader(&tar.Header{ Name: GetObjectName(obj), - Mode: 0600, + Mode: 0o600, Size: int64(len(data)), Typeflag: tar.TypeReg, }); err != nil { @@ -104,7 +103,7 @@ func CreateImageWithAnnotations(ref string, mapper ObjectAnnotationMapper, objs } if err := remoteimg.Write(imgRef, img); err != nil { - return "", fmt.Errorf("could not push example image to registry") + return "", errors.New("could not push example image to registry") } digest, err := img.Digest() diff --git a/test/serviceaccount_test.go b/test/serviceaccount_test.go index 1de9d653f3a..2e5013ce69c 100644 --- a/test/serviceaccount_test.go +++ b/test/serviceaccount_test.go @@ -168,7 +168,7 @@ spec: } // Verify it used those serviceAccount - taskRuns, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", pipelineRun.Name)}) + taskRuns, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + pipelineRun.Name}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", pipelineRun.Name, err) } @@ -179,7 +179,7 @@ spec: if sa != expectedSA { t.Fatalf("TaskRun %s expected SA %s, got %s", taskRun.Name, expectedSA, sa) } - pods, err := c.KubeClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/taskRun=%s", taskRun.Name)}) + pods, err := c.KubeClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/taskRun=" + taskRun.Name}) if err != nil { t.Fatalf("Error listing Pods for TaskRun %s: %s", taskRun.Name, err) } @@ -276,7 +276,7 @@ spec: } // Verify it used those serviceAccount - taskRuns, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", pipelineRun.Name)}) + taskRuns, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + pipelineRun.Name}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", pipelineRun.Name, err) } @@ -286,7 +286,7 @@ spec: if sa != expectedSA { t.Fatalf("TaskRun %s expected SA %s, got %s", taskRun.Name, expectedSA, sa) } - pods, err := c.KubeClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/taskRun=%s", taskRun.Name)}) + pods, err := c.KubeClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/taskRun=" + taskRun.Name}) if err != nil { t.Fatalf("Error listing Pods for TaskRun %s: %s", taskRun.Name, err) } diff --git a/test/sidecar_test.go b/test/sidecar_test.go index 79a50bf5202..7e6ccb23a40 100644 --- a/test/sidecar_test.go +++ b/test/sidecar_test.go @@ -139,14 +139,14 @@ spec: sidecarTerminated := false for _, c := range pod.Status.ContainerStatuses { - if c.Name == fmt.Sprintf("step-%s", primaryContainerName) { + if c.Name == "step-"+primaryContainerName { if c.State.Terminated == nil || c.State.Terminated.Reason != "Completed" { t.Errorf("Primary container has nil Terminated state or did not complete successfully. Actual Terminated state: %v", c.State.Terminated) } else { primaryTerminated = true } } - if c.Name == fmt.Sprintf("sidecar-%s", sidecarContainerName) { + if c.Name == "sidecar-"+sidecarContainerName { if c.State.Terminated == nil { t.Errorf("Sidecar container has a nil Terminated status but non-nil is expected.") } else { @@ -167,7 +167,7 @@ spec: sidecarFromStatus := trCheckSidecarStatus.Status.Sidecars[0] // Check if Sidecar ContainerName is present for SidecarStatus - if sidecarFromStatus.Container != fmt.Sprintf("sidecar-%s", sidecarContainerName) { + if sidecarFromStatus.Container != "sidecar-"+sidecarContainerName { t.Errorf("Sidecar ContainerName should be: %s", sidecarContainerName) } diff --git a/test/step_output_test.go b/test/step_output_test.go index 16e02611f87..0e0a58222be 100644 --- a/test/step_output_test.go +++ b/test/step_output_test.go @@ -56,7 +56,7 @@ func TestStepOutput(t *testing.T) { Name: "data", MountPath: "/data", }}, - Script: fmt.Sprintf("echo -n %s", wantResultValue), + Script: "echo -n " + wantResultValue, StdoutConfig: &v1.StepOutputConfig{ Path: "/data/step-echo-stdout", }, @@ -134,7 +134,7 @@ func TestStepOutputWithWorkspace(t *testing.T) { Steps: []v1.Step{{ Name: "echo", Image: "busybox", - Script: fmt.Sprintf("echo -n %s", wantResultValue), + Script: "echo -n " + wantResultValue, StdoutConfig: &v1.StepOutputConfig{ Path: "/data/step-echo-stdout", }, diff --git a/test/tektonbundles_test.go b/test/tektonbundles_test.go index e9a67bb31c8..3515dcaeb41 100644 --- a/test/tektonbundles_test.go +++ b/test/tektonbundles_test.go @@ -72,7 +72,7 @@ func TestTektonBundlesSimpleWorkingExample(t *testing.T) { taskName := helpers.ObjectNameForTest(t) pipelineName := helpers.ObjectNameForTest(t) pipelineRunName := helpers.ObjectNameForTest(t) - repo := fmt.Sprintf("%s:5000/tektonbundlessimple", getRegistryServiceIP(ctx, t, c, namespace)) + repo := getRegistryServiceIP(ctx, t, c, namespace) + ":5000/tektonbundlessimple" task := parse.MustParseV1beta1Task(t, fmt.Sprintf(` metadata: name: %s @@ -133,7 +133,6 @@ spec: t.Fatal("Error getting a PodName (empty)") } p, err := c.KubeClient.CoreV1().Pods(namespace).Get(ctx, tr.Status.PodName, metav1.GetOptions{}) - if err != nil { t.Fatalf("Error getting pod `%s` in namespace `%s`", tr.Status.PodName, namespace) } @@ -165,7 +164,7 @@ func TestTektonBundlesResolver(t *testing.T) { taskName := helpers.ObjectNameForTest(t) pipelineName := helpers.ObjectNameForTest(t) pipelineRunName := helpers.ObjectNameForTest(t) - repo := fmt.Sprintf("%s:5000/tektonbundlesresolver", getRegistryServiceIP(ctx, t, c, namespace)) + repo := getRegistryServiceIP(ctx, t, c, namespace) + ":5000/tektonbundlesresolver" task := parse.MustParseV1beta1Task(t, fmt.Sprintf(` metadata: @@ -237,7 +236,6 @@ spec: t.Fatal("Error getting a PodName (empty)") } p, err := c.KubeClient.CoreV1().Pods(namespace).Get(ctx, tr.Status.PodName, metav1.GetOptions{}) - if err != nil { t.Fatalf("Error getting pod `%s` in namespace `%s`", tr.Status.PodName, namespace) } @@ -268,7 +266,7 @@ func TestTektonBundlesUsingRegularImage(t *testing.T) { taskName := helpers.ObjectNameForTest(t) pipelineName := helpers.ObjectNameForTest(t) pipelineRunName := helpers.ObjectNameForTest(t) - repo := fmt.Sprintf("%s:5000/tektonbundlesregularimage", getRegistryServiceIP(ctx, t, c, namespace)) + repo := getRegistryServiceIP(ctx, t, c, namespace) + ":5000/tektonbundlesregularimage" pipeline := parse.MustParseV1beta1Pipeline(t, fmt.Sprintf(` metadata: @@ -321,7 +319,7 @@ func TestTektonBundlesUsingImproperFormat(t *testing.T) { taskName := helpers.ObjectNameForTest(t) pipelineName := helpers.ObjectNameForTest(t) pipelineRunName := helpers.ObjectNameForTest(t) - repo := fmt.Sprintf("%s:5000/tektonbundlesimproperformat", getRegistryServiceIP(ctx, t, c, namespace)) + repo := getRegistryServiceIP(ctx, t, c, namespace) + ":5000/tektonbundlesimproperformat" ref, err := name.ParseReference(repo) if err != nil { diff --git a/test/timeout_test.go b/test/timeout_test.go index b033f85422a..4b72f38b18f 100644 --- a/test/timeout_test.go +++ b/test/timeout_test.go @@ -97,7 +97,7 @@ spec: t.Errorf("Error waiting for PipelineRun %s to finish: %s", pipelineRun.Name, err) } - taskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", pipelineRun.Name)}) + taskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + pipelineRun.Name}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", pipelineRun.Name, err) } @@ -391,7 +391,7 @@ spec: t.Fatalf("Error waiting for PipelineRun %s to finish: %s", pipelineRun.Name, err) } - taskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", pipelineRun.Name)}) + taskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + pipelineRun.Name}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", pipelineRun.Name, err) } @@ -515,7 +515,7 @@ spec: t.Errorf("Error waiting for PipelineRun %s to finish: %s", pipelineRun.Name, err) } - taskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("tekton.dev/pipelineRun=%s", pipelineRun.Name)}) + taskrunList, err := c.V1TaskRunClient.List(ctx, metav1.ListOptions{LabelSelector: "tekton.dev/pipelineRun=" + pipelineRun.Name}) if err != nil { t.Fatalf("Error listing TaskRuns for PipelineRun %s: %s", pipelineRun.Name, err) } @@ -553,7 +553,6 @@ spec: } return false, nil }, v1.TaskRunReasonCancelled.String(), v1Version) - if err != nil { t.Errorf("Error waiting for TaskRun %s to timeout: %s", name, err) } diff --git a/test/trustedresources.go b/test/trustedresources.go index ab18c4f8bf9..a09a82fb9ad 100644 --- a/test/trustedresources.go +++ b/test/trustedresources.go @@ -26,7 +26,7 @@ import ( "crypto/sha256" "encoding/base64" "encoding/json" - "fmt" + "errors" "os" "path/filepath" "testing" @@ -50,9 +50,7 @@ const ( signatureAnnotation = "tekton.dev/signature" ) -var ( - read = readPasswordFn -) +var read = readPasswordFn // SetupTrustedResourceConfig configures the trusted-resources-verification-no-match-policy feature flag with the given mode for testing func SetupTrustedResourceConfig(ctx context.Context, verificationNoMatchPolicy string) context.Context { @@ -95,7 +93,9 @@ func SetupVerificationPolicies(t *testing.T) (signature.SignerVerifier, *ecdsa.P Data: map[string][]byte{"cosign.pub": pub}, ObjectMeta: metav1.ObjectMeta{ Name: "verification-secrets", - Namespace: namespace}} + Namespace: namespace, + }, + } keyInDataVp := getVerificationPolicy( "keyInDataVp", @@ -116,8 +116,10 @@ func SetupVerificationPolicies(t *testing.T) (signature.SignerVerifier, *ecdsa.P keyInSecretVp := getVerificationPolicy( "keyInSecretVp", namespace, - []v1alpha1.ResourcePattern{{ - Pattern: "gcr.io/tekton-releases/catalog/upstream/git-clone"}, + []v1alpha1.ResourcePattern{ + { + Pattern: "gcr.io/tekton-releases/catalog/upstream/git-clone", + }, }, []v1alpha1.Authority{ { @@ -151,8 +153,10 @@ func SetupVerificationPolicies(t *testing.T) (signature.SignerVerifier, *ecdsa.P warnModeVP := getVerificationPolicy( "warnModeVP", namespace, - []v1alpha1.ResourcePattern{{ - Pattern: "warnVP"}, + []v1alpha1.ResourcePattern{ + { + Pattern: "warnVP", + }, }, []v1alpha1.Authority{ { @@ -187,7 +191,9 @@ func SetupMatchAllVerificationPolicies(t *testing.T, namespace string) (signatur Data: map[string][]byte{"cosign.pub": pub}, ObjectMeta: metav1.ObjectMeta{ Name: "verification-secrets", - Namespace: namespace}} + Namespace: namespace, + }, + } matchAllVp := getVerificationPolicy( "matchAllVp", @@ -219,7 +225,7 @@ func GetSignerFromFile(ctx context.Context, t *testing.T) (signature.Signer, str } tmpDir := t.TempDir() pubKey := filepath.Join(tmpDir, "ecdsa.pub") - if err := os.WriteFile(pubKey, pub, 0600); err != nil { + if err := os.WriteFile(pubKey, pub, 0o600); err != nil { t.Fatal(err) } @@ -235,7 +241,7 @@ func GetKeysFromFile(ctx context.Context, t *testing.T) (*ecdsa.PrivateKey, stri } tmpDir := t.TempDir() pubKey := filepath.Join(tmpDir, "ecdsa.pub") - if err := os.WriteFile(pubKey, pub, 0600); err != nil { + if err := os.WriteFile(pubKey, pub, 0o600); err != nil { t.Fatal(err) } @@ -266,7 +272,7 @@ func GenerateKeys(c elliptic.Curve, hashFunc crypto.Hash) (signature.SignerVerif // signInterface returns the encoded signature for the given object. func signInterface(signer signature.Signer, i interface{}) ([]byte, error) { if signer == nil { - return nil, fmt.Errorf("signer is nil") + return nil, errors.New("signer is nil") } b, err := json.Marshal(i) if err != nil { @@ -347,6 +353,7 @@ func getPass(confirm bool) ([]byte, error) { read := read(confirm) return read() } + func readPasswordFn(confirm bool) func() ([]byte, error) { pw, ok := os.LookupEnv("PRIVATE_PASSWORD") if ok { @@ -355,7 +362,7 @@ func readPasswordFn(confirm bool) func() ([]byte, error) { } } return func() ([]byte, error) { - return nil, fmt.Errorf("fail to get password") + return nil, errors.New("fail to get password") } } diff --git a/test/util.go b/test/util.go index ad274c55801..99e005a86b4 100644 --- a/test/util.go +++ b/test/util.go @@ -103,14 +103,14 @@ func tearDown(ctx context.Context, t *testing.T, cs *clients, namespace string) return } if t.Failed() { - header(t, fmt.Sprintf("Dumping objects from %s", namespace)) + header(t, "Dumping objects from "+namespace) bs, err := getCRDYaml(ctx, cs, namespace) if err != nil { t.Error(err) } else { t.Log(string(bs)) } - header(t, fmt.Sprintf("Dumping logs from Pods in the %s", namespace)) + header(t, "Dumping logs from Pods in the "+namespace) taskRuns, err := cs.V1TaskRunClient.List(ctx, metav1.ListOptions{}) if err != nil { t.Errorf("Error listing TaskRuns: %s", err)