From 50c7c7bd732b917722843021f6939d4337fb8eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Moreno=20Garc=C3=ADa?= Date: Thu, 30 Nov 2023 13:53:35 +0100 Subject: [PATCH] feat(RHTAPREL-717): use new PipelineRun builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit uses the new builder to generate the managed PipelineRun. Signed-off-by: David Moreno GarcĂ­a --- .github/workflows/codecov.yml | 2 +- .github/workflows/pr.yml | 2 +- Makefile | 4 + api/v1alpha1/releaseserviceconfig_types.go | 5 + api/v1alpha1/zz_generated.deepcopy.go | 3 +- ...udio.redhat.com_releaseplanadmissions.yaml | 6 - ...udio.redhat.com_releaseserviceconfigs.yaml | 19 ++ config/manager/manager.properties | 1 + config/manager/manager.yaml | 6 + controllers/release/adapter.go | 49 +-- controllers/release/adapter_test.go | 29 +- go.mod | 2 +- go.sum | 12 + main.go | 9 + metadata/labels.go | 3 + tekton/pipeline_run.go | 216 ------------- tekton/pipeline_run_test.go | 295 ------------------ tekton/predicates_test.go | 104 ++---- tekton/utils.go | 2 +- tekton/utils/pipeline.go | 8 - tekton/utils/pipeline_run_builder.go | 32 +- tekton/utils/pipeline_run_builder_test.go | 37 ++- tekton/utils_test.go | 97 ++---- 23 files changed, 237 insertions(+), 706 deletions(-) delete mode 100644 tekton/pipeline_run.go delete mode 100644 tekton/pipeline_run_test.go diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 84840ee6..62223ee6 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v5 with: - go-version: 1.20 + go-version: 1.21 - name: Run tests run: make test - name: Codecov diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 89e9cac7..d9de5387 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "1.21" - name: Check out code into the Go module directory uses: actions/checkout@v4 with: diff --git a/Makefile b/Makefile index c078888f..4195acf9 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,9 @@ DEFAULT_RELEASE_PVC ?= release-pvc # DEFAULT_WORKSPACE_NAME defines the default name for the workspace that will be used in the managed Release Pipeline. DEFAULT_RELEASE_WORKSPACE_NAME ?= release-workspace +# DEFAULT_WORKSPACE_SIZE defines the default size for the workspace that will be used in the managed Release Pipeline. +DEFAULT_RELEASE_WORKSPACE_SIZE ?= 1Gi + # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") # To re-generate a bundle for other specific channels without changing the standard setup, you can: @@ -158,6 +161,7 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} DEFAULT_RELEASE_PVC=${DEFAULT_RELEASE_PVC} \ DEFAULT_RELEASE_WORKSPACE_NAME=${DEFAULT_RELEASE_WORKSPACE_NAME} \ + DEFAULT_RELEASE_WORKSPACE_SIZE=${DEFAULT_RELEASE_WORKSPACE_SIZE} \ $(KUSTOMIZE) build config/default | kubectl apply -f - .PHONY: undeploy diff --git a/api/v1alpha1/releaseserviceconfig_types.go b/api/v1alpha1/releaseserviceconfig_types.go index 9fc0b4f9..9e44aa09 100644 --- a/api/v1alpha1/releaseserviceconfig_types.go +++ b/api/v1alpha1/releaseserviceconfig_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -32,6 +33,10 @@ type ReleaseServiceConfigSpec struct { // AdvisoryRepo is the repo to create advisories in during the managed release PipelineRun // +optional AdvisoryRepo string `json:"advisoryRepo,omitempty"` + + // DefaultTimeouts contain the default Tekton timeouts to be used in case they are + // not specified in the ReleasePlanAdmission resource. + DefaultTimeouts tektonv1.TimeoutFields `json:"defaultTimeouts,omitempty"` } // ReleaseServiceConfigStatus defines the observed state of ReleaseServiceConfig. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 21152f7e..9aa55f8e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -428,7 +428,7 @@ func (in *ReleaseServiceConfig) DeepCopyInto(out *ReleaseServiceConfig) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status } @@ -485,6 +485,7 @@ func (in *ReleaseServiceConfigList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReleaseServiceConfigSpec) DeepCopyInto(out *ReleaseServiceConfigSpec) { *out = *in + in.DefaultTimeouts.DeepCopyInto(&out.DefaultTimeouts) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseServiceConfigSpec. diff --git a/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml b/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml index 7f166b41..842e93e3 100644 --- a/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml +++ b/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml @@ -103,12 +103,6 @@ spec: the execution of the Pipeline pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string - timeout: - default: "0" - description: "Timeout is a value to use to override the tekton - default Pipelinerun timeout \n This field is DEPRECATED and - will be replaced by Timeouts in a future change." - type: string timeouts: description: Timeouts defines the different Timeouts to use in the PipelineRun execution diff --git a/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml b/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml index 8f7e0611..c7cb89bc 100644 --- a/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml +++ b/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml @@ -46,6 +46,25 @@ spec: description: Debug is the boolean that specifies whether or not the Release Service should run in debug mode type: boolean + defaultTimeouts: + description: DefaultTimeouts contain the default Tekton timeouts to + be used in case they are not specified in the ReleasePlanAdmission + resource. + properties: + finally: + description: Finally sets the maximum allowed duration of this + pipeline's finally + type: string + pipeline: + description: Pipeline sets the maximum allowed duration for execution + of the entire pipeline. The sum of individual timeouts for tasks + and finally must not exceed this value. + type: string + tasks: + description: Tasks sets the maximum allowed duration of this pipeline's + tasks + type: string + type: object type: object status: description: ReleaseServiceConfigStatus defines the observed state of diff --git a/config/manager/manager.properties b/config/manager/manager.properties index 5a438162..649f93e4 100644 --- a/config/manager/manager.properties +++ b/config/manager/manager.properties @@ -1,2 +1,3 @@ DEFAULT_RELEASE_PVC DEFAULT_RELEASE_WORKSPACE_NAME +DEFAULT_RELEASE_WORKSPACE_SIZE diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 2d1eaf0b..fbc6493b 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -70,6 +70,12 @@ spec: key: DEFAULT_RELEASE_WORKSPACE_NAME name: manager-properties optional: true + - name: DEFAULT_RELEASE_WORKSPACE_SIZE + valueFrom: + configMapKeyRef: + key: DEFAULT_RELEASE_WORKSPACE_SIZE + name: manager-properties + optional: true - name: SERVICE_NAMESPACE valueFrom: fieldRef: diff --git a/controllers/release/adapter.go b/controllers/release/adapter.go index aca09a18..b231cf9b 100644 --- a/controllers/release/adapter.go +++ b/controllers/release/adapter.go @@ -22,19 +22,17 @@ import ( "os" "time" - "github.com/redhat-appstudio/operator-toolkit/controller" - "github.com/go-logr/logr" + libhandler "github.com/operator-framework/operator-lib/handler" + applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" + integrationgitops "github.com/redhat-appstudio/integration-service/gitops" + "github.com/redhat-appstudio/operator-toolkit/controller" "github.com/redhat-appstudio/release-service/api/v1alpha1" "github.com/redhat-appstudio/release-service/gitops" "github.com/redhat-appstudio/release-service/loader" "github.com/redhat-appstudio/release-service/metadata" "github.com/redhat-appstudio/release-service/syncer" - "github.com/redhat-appstudio/release-service/tekton" - - applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" - - libhandler "github.com/operator-framework/operator-lib/handler" + "github.com/redhat-appstudio/release-service/tekton/utils" tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" rbac "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -381,21 +379,34 @@ func (a *adapter) EnsureReleaseProcessingIsTracked() (controller.OperationResult // will be extracted from the given ReleaseStrategy. The Release's Snapshot will also be passed to the release // PipelineRun. func (a *adapter) createManagedPipelineRun(resources *loader.ProcessingResources) (*tektonv1.PipelineRun, error) { - pipelineRun := tekton.NewReleasePipelineRun("managed-release", resources.ReleasePlanAdmission.Namespace). - WithObjectReferences(a.release, resources.ReleasePlan, - resources.ReleasePlanAdmission, resources.Snapshot). + pipelineRun, err := utils.NewPipelineRunBuilder("managed", resources.ReleasePlanAdmission.Namespace). + WithAnnotations(metadata.GetAnnotationsWithPrefix(a.release, integrationgitops.PipelinesAsCodePrefix)). + WithFinalizer(metadata.ReleaseFinalizer). + WithLabels(map[string]string{ + metadata.ApplicationNameLabel: resources.ReleasePlan.Spec.Application, + metadata.PipelinesTypeLabel: metadata.ManagedPipelineType, + metadata.ReleaseNameLabel: a.release.Name, + metadata.ReleaseNamespaceLabel: a.release.Namespace, + metadata.ReleaseSnapshotLabel: a.release.Spec.Snapshot, + }). + WithObjectReferences(a.release, resources.ReleasePlan, resources.ReleasePlanAdmission, resources.Snapshot). + WithObjectSpecsAsJson(resources.EnterpriseContractPolicy). WithOwner(a.release). - WithReleaseAndApplicationMetadata(a.release, resources.Snapshot.Spec.Application). - WithWorkspace(os.Getenv("DEFAULT_RELEASE_WORKSPACE_NAME"), os.Getenv("DEFAULT_RELEASE_PVC")). - WithServiceAccount(resources.ReleasePlanAdmission.Spec.Pipeline.ServiceAccount). - WithTimeout(resources.ReleasePlanAdmission.Spec.Pipeline.Timeout). + WithParamsFromConfigMap(resources.EnterpriseContractConfigMap, []string{"verify_ec_task_bundle"}). WithPipelineRef(resources.ReleasePlanAdmission.Spec.Pipeline.PipelineRef.ToTektonPipelineRef()). - WithTaskGitPipelineParameters(&resources.ReleasePlanAdmission.Spec.Pipeline.PipelineRef). - WithEnterpriseContractConfigMap(resources.EnterpriseContractConfigMap). - WithEnterpriseContractPolicy(resources.EnterpriseContractPolicy). - AsPipelineRun() + WithServiceAccount(resources.ReleasePlanAdmission.Spec.Pipeline.ServiceAccount). + WithTimeouts(&resources.ReleasePlanAdmission.Spec.Pipeline.Timeouts, &a.releaseServiceConfig.Spec.DefaultTimeouts). + WithWorkspaceFromVolumeTemplate( + os.Getenv("DEFAULT_RELEASE_WORKSPACE_NAME"), + os.Getenv("DEFAULT_RELEASE_WORKSPACE_SIZE"), + ). + Build() + + if err != nil { + return nil, err + } - err := a.client.Create(a.ctx, pipelineRun) + err = a.client.Create(a.ctx, pipelineRun) if err != nil { return nil, err } diff --git a/controllers/release/adapter_test.go b/controllers/release/adapter_test.go index 0268a4e5..092d5588 100644 --- a/controllers/release/adapter_test.go +++ b/controllers/release/adapter_test.go @@ -24,6 +24,7 @@ import ( "reflect" "strings" "time" + "unicode" tektonutils "github.com/redhat-appstudio/release-service/tekton/utils" @@ -73,6 +74,9 @@ var _ = Describe("Release adapter", Ordered, func() { }) BeforeAll(func() { + Expect(os.Setenv("DEFAULT_RELEASE_WORKSPACE_NAME", "release-workspace")).To(Succeed()) + Expect(os.Setenv("DEFAULT_RELEASE_WORKSPACE_SIZE", "1Gi")).To(Succeed()) + createResources() }) @@ -564,6 +568,7 @@ var _ = Describe("Release adapter", Ordered, func() { BeforeEach(func() { adapter = createReleaseAndAdapter() + adapter.releaseServiceConfig = releaseServiceConfig }) It("should do nothing if the Release is already processed", func() { @@ -715,6 +720,8 @@ var _ = Describe("Release adapter", Ordered, func() { Policy: enterpriseContractPolicy.Name, }, } + newReleasePlanAdmission.Kind = "ReleasePlanAdmission" + adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ { ContextKey: loader.ProcessingResourcesContextKey, @@ -1085,7 +1092,7 @@ var _ = Describe("Release adapter", Ordered, func() { It("returns a PipelineRun with the right prefix", func() { Expect(reflect.TypeOf(pipelineRun)).To(Equal(reflect.TypeOf(&tektonv1.PipelineRun{}))) - Expect(pipelineRun.Name).To(HavePrefix("managed-release")) + Expect(pipelineRun.Name).To(HavePrefix("managed")) }) It("has the release reference", func() { @@ -1095,13 +1102,19 @@ var _ = Describe("Release adapter", Ordered, func() { }) It("has the releasePlan reference", func() { - Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", strings.ToLower(releasePlan.Kind)))) + name := []rune(releasePlan.Kind) + name[0] = unicode.ToLower(name[0]) + + Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", string(name)))) Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", fmt.Sprintf("%s%c%s", releasePlan.Namespace, types.Separator, releasePlan.Name)))) }) It("has the releasePlanAdmission reference", func() { - Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", strings.ToLower(releasePlanAdmission.Kind)))) + name := []rune(releasePlanAdmission.Kind) + name[0] = unicode.ToLower(name[0]) + + Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Name", string(name)))) Expect(pipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", fmt.Sprintf("%s%c%s", releasePlanAdmission.Namespace, types.Separator, releasePlanAdmission.Name)))) }) @@ -1118,7 +1131,7 @@ var _ = Describe("Release adapter", Ordered, func() { }) It("has release labels", func() { - Expect(pipelineRun.GetLabels()[metadata.PipelinesTypeLabel]).To(Equal("release")) + Expect(pipelineRun.GetLabels()[metadata.PipelinesTypeLabel]).To(Equal(metadata.ManagedPipelineType)) Expect(pipelineRun.GetLabels()[metadata.ReleaseNameLabel]).To(Equal(adapter.release.Name)) Expect(pipelineRun.GetLabels()[metadata.ReleaseNamespaceLabel]).To(Equal(testNamespace)) Expect(pipelineRun.GetLabels()[metadata.ReleaseSnapshotLabel]).To(Equal(adapter.release.Spec.Snapshot)) @@ -1160,8 +1173,7 @@ var _ = Describe("Release adapter", Ordered, func() { }) It("contains the proper timeout value", func() { - timeout := releasePlanAdmission.Spec.Pipeline.Timeout - Expect(pipelineRun.Spec.Timeouts.Pipeline.Duration.String()).To(Equal(string(timeout))) + Expect(pipelineRun.Spec.Timeouts.Pipeline).To(Equal(releasePlanAdmission.Spec.Pipeline.Timeouts.Pipeline)) }) It("contains a parameter with the verify ec task bundle", func() { @@ -2024,6 +2036,7 @@ var _ = Describe("Release adapter", Ordered, func() { }, } Expect(k8sClient.Create(ctx, releasePlan)).To(Succeed()) + releasePlan.Kind = "ReleasePlan" releaseServiceConfig = &v1alpha1.ReleaseServiceConfig{ ObjectMeta: metav1.ObjectMeta{ @@ -2054,8 +2067,10 @@ var _ = Describe("Release adapter", Ordered, func() { {Name: "pathInRepo", Value: "my-path"}, }, }, - Timeout: "2h0m0s", ServiceAccount: "service-account", + Timeouts: tektonv1.TimeoutFields{ + Pipeline: &metav1.Duration{Duration: 1 * time.Hour}, + }, }, Policy: enterpriseContractPolicy.Name, }, diff --git a/go.mod b/go.mod index e8a06e2e..e9907e39 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/redhat-appstudio/release-service -go 1.20 +go 1.21 require ( github.com/enterprise-contract/enterprise-contract-controller/api v0.1.35 diff --git a/go.sum b/go.sum index 40ec8dc9..2c368266 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudevents/sdk-go/v2 v2.14.0 h1:Nrob4FwVgi5L4tV9lhjzZcjYqFVyJzsA56CwPaPfv6s= +github.com/cloudevents/sdk-go/v2 v2.14.0/go.mod h1:xDmKfzNjM8gBvjaF8ijFjM1VYOVUEeUfapHMUX1T5To= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -78,6 +79,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -116,6 +118,7 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -199,6 +202,7 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= @@ -215,6 +219,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -223,6 +228,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -298,6 +304,7 @@ github.com/redhat-appstudio/operator-toolkit v0.0.0-20231201124606-2087182322ae/ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -320,10 +327,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/tektoncd/pipeline v0.56.1 h1:jAc5R+UYgNprSae8XdkIBemXpmUzQzdvrj6fXS4DlEo= github.com/tektoncd/pipeline v0.56.1/go.mod h1:npl5qTu+yU74zqKIkTVnFfu/1pMhJFZjvnCrH6DlfLM= github.com/tonglil/buflogr v1.0.1 h1:WXFZLKxLfqcVSmckwiMCF8jJwjIgmStJmg63YKRF1p0= +github.com/tonglil/buflogr v1.0.1/go.mod h1:yYWwvSpn/3uAaqjf6mJg/XMiAciaR0QcRJH2gJGDxNE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -339,6 +348,7 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -386,6 +396,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -620,6 +631,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe h1:USL2DhxfgRchafRvt/wYyyQNzwgL7ZiURcozOE/Pkvo= +google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 h1:x9PwdEgd11LgK+orcck69WVRo7DezSO4VUMPI4xpc8A= google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014 h1:FSL3lRCkhaPFxqi0s9o+V4UI2WTzAVOvkgbd4kVV4Wg= diff --git a/main.go b/main.go index dccbd998..1ec1caa8 100644 --- a/main.go +++ b/main.go @@ -127,6 +127,15 @@ func main() { } } + // Set a default value for the DEFAULT_RELEASE_WORKSPACE_SIZE environment variable + if os.Getenv("DEFAULT_RELEASE_WORKSPACE_SIZE") == "" { + err := os.Setenv("DEFAULT_RELEASE_WORKSPACE_SIZE", "1Gi") + if err != nil { + setupLog.Error(err, "unable to setup DEFAULT_RELEASE_WORKSPACE_SIZE environment variable") + os.Exit(1) + } + } + setUpControllers(mgr) setUpWebhooks(mgr) diff --git a/metadata/labels.go b/metadata/labels.go index 1b16903a..539547f8 100644 --- a/metadata/labels.go +++ b/metadata/labels.go @@ -59,6 +59,9 @@ var ( // ApplicationNameLabel is the label used to specify the application associated with the PipelineRun ApplicationNameLabel = fmt.Sprintf("%s/%s", rhtapDomain, "application") + // ManagedPipelineType is the value to be used in the PipelinesTypeLabel for managed Pipelines + ManagedPipelineType = "managed" + // PipelinesTypeLabel is the label used to describe the type of pipeline PipelinesTypeLabel = fmt.Sprintf("%s/%s", pipelinesLabelPrefix, "type") diff --git a/tekton/pipeline_run.go b/tekton/pipeline_run.go deleted file mode 100644 index d754c3ff..00000000 --- a/tekton/pipeline_run.go +++ /dev/null @@ -1,216 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package tekton - -import ( - "encoding/json" - "fmt" - "strings" - "time" - "unicode" - - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - ecapiv1alpha1 "github.com/enterprise-contract/enterprise-contract-controller/api/v1alpha1" - "github.com/redhat-appstudio/release-service/metadata" - "github.com/redhat-appstudio/release-service/tekton/utils" - - libhandler "github.com/operator-framework/operator-lib/handler" - integrationServiceGitopsPkg "github.com/redhat-appstudio/integration-service/gitops" - "github.com/redhat-appstudio/release-service/api/v1alpha1" - tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// PipelineType represents a PipelineRun type within AppStudio -type PipelineType string - -const ( - // PipelineTypeRelease is the type for PipelineRuns created to run a managed Release Pipeline - PipelineTypeRelease = "release" -) - -// ReleasePipelineRun is a PipelineRun alias, so we can add new methods to it in this file. -type ReleasePipelineRun struct { - tektonv1.PipelineRun -} - -// NewReleasePipelineRun creates an empty PipelineRun in the given namespace. The name will be autogenerated, -// using the prefix passed as an argument to the function. -func NewReleasePipelineRun(prefix, namespace string) *ReleasePipelineRun { - pipelineRun := tektonv1.PipelineRun{ - ObjectMeta: v1.ObjectMeta{ - GenerateName: prefix + "-", - Namespace: namespace, - }, - Spec: tektonv1.PipelineRunSpec{}, - } - - return &ReleasePipelineRun{pipelineRun} -} - -// AsPipelineRun casts the ReleasePipelineRun to PipelineRun, so it can be used in the Kubernetes client. -func (r *ReleasePipelineRun) AsPipelineRun() *tektonv1.PipelineRun { - return &r.PipelineRun -} - -// WithEnterpriseContractConfigMap adds a param providing the verify ec task bundle to the managed Release PipelineRun. -func (r *ReleasePipelineRun) WithEnterpriseContractConfigMap(ecConfig *corev1.ConfigMap) *ReleasePipelineRun { - enterpriseContractConfigMapBundleField := "verify_ec_task_bundle" - - ecTaskBundle := ecConfig.Data[enterpriseContractConfigMapBundleField] - - r.WithExtraParam(enterpriseContractConfigMapBundleField, tektonv1.ParamValue{ - Type: tektonv1.ParamTypeString, - StringVal: string(ecTaskBundle), - }) - - return r -} - -// WithEnterpriseContractPolicy adds a param containing the EnterpriseContractPolicy Spec as a json string to the managed Release PipelineRun. -func (r *ReleasePipelineRun) WithEnterpriseContractPolicy(enterpriseContractPolicy *ecapiv1alpha1.EnterpriseContractPolicy) *ReleasePipelineRun { - policyJson, _ := json.Marshal(enterpriseContractPolicy.Spec) - - policyKindRunes := []rune(enterpriseContractPolicy.Kind) - policyKindRunes[0] = unicode.ToLower(policyKindRunes[0]) - - r.WithExtraParam(string(policyKindRunes), tektonv1.ParamValue{ - Type: tektonv1.ParamTypeString, - StringVal: string(policyJson), - }) - - return r -} - -// WithExtraParam adds an extra param to the managed Release PipelineRun. If the parameter is not part of the Pipeline -// definition, it will be silently ignored. -func (r *ReleasePipelineRun) WithExtraParam(name string, value tektonv1.ParamValue) *ReleasePipelineRun { - r.Spec.Params = append(r.Spec.Params, tektonv1.Param{ - Name: name, - Value: value, - }) - - return r -} - -// WithObjectReferences adds new parameters to the PipelineRun for each object passed as an argument to the function. -// The new parameters will be named after the kind of the object and its values will be a reference to the object itself -// in the form of "namespace/name". -func (r *ReleasePipelineRun) WithObjectReferences(objects ...client.Object) *ReleasePipelineRun { - for _, object := range objects { - r.WithExtraParam(strings.ToLower(object.GetObjectKind().GroupVersionKind().Kind), tektonv1.ParamValue{ - Type: tektonv1.ParamTypeString, - StringVal: fmt.Sprintf("%s%c%s", object.GetNamespace(), types.Separator, object.GetName()), - }) - } - - return r -} - -// WithOwner sets owner annotations to the managed Release PipelineRun and a finalizer to prevent its deletion. -func (r *ReleasePipelineRun) WithOwner(release *v1alpha1.Release) *ReleasePipelineRun { - _ = libhandler.SetOwnerAnnotations(release, r) - controllerutil.AddFinalizer(r, metadata.ReleaseFinalizer) - - return r -} - -// WithPipelineRef sets the PipelineRef for the managed Release PipelineRun. -func (r *ReleasePipelineRun) WithPipelineRef(pipelineRef *tektonv1.PipelineRef) *ReleasePipelineRun { - r.Spec.PipelineRef = pipelineRef - - return r -} - -// WithReleaseAndApplicationMetadata adds Release and Application metadata to the managed Release PipelineRun. -func (r *ReleasePipelineRun) WithReleaseAndApplicationMetadata(release *v1alpha1.Release, applicationName string) *ReleasePipelineRun { - r.ObjectMeta.Labels = map[string]string{ - metadata.PipelinesTypeLabel: PipelineTypeRelease, - metadata.ReleaseNameLabel: release.Name, - metadata.ReleaseNamespaceLabel: release.Namespace, - metadata.ApplicationNameLabel: applicationName, - metadata.ReleaseSnapshotLabel: release.Spec.Snapshot, - } - metadata.AddAnnotations(r.AsPipelineRun(), metadata.GetAnnotationsWithPrefix(release, integrationServiceGitopsPkg.PipelinesAsCodePrefix)) - metadata.AddLabels(r.AsPipelineRun(), metadata.GetLabelsWithPrefix(release, integrationServiceGitopsPkg.PipelinesAsCodePrefix)) - - return r -} - -// WithServiceAccount adds a reference to the service account to be used to gain elevated privileges during the -// execution of the different Pipeline tasks. -func (r *ReleasePipelineRun) WithServiceAccount(serviceAccount string) *ReleasePipelineRun { - r.Spec.TaskRunTemplate.ServiceAccountName = serviceAccount - - return r -} - -// WithTaskGitPipelineParameters adds the taskGitUrl and taskGitRevision parameters to the managed Release PipelineRun with -// the value of the url and revision from the pipelineRef if the pipelineRef is for a git resolver. -func (r *ReleasePipelineRun) WithTaskGitPipelineParameters(pipelineRef *utils.PipelineRef) *ReleasePipelineRun { - if pipelineRef.Resolver == "git" { - for _, p := range pipelineRef.Params { - if p.Name == "url" { - r.WithExtraParam("taskGitUrl", tektonv1.ParamValue{ - Type: tektonv1.ParamTypeString, - StringVal: p.Value, - }) - } - if p.Name == "revision" { - r.WithExtraParam("taskGitRevision", tektonv1.ParamValue{ - Type: tektonv1.ParamTypeString, - StringVal: p.Value, - }) - } - } - } - - return r -} - -// WithTimeout overwrites the PipelineRun's default timeout value. -func (r *ReleasePipelineRun) WithTimeout(timeout string) *ReleasePipelineRun { - duration, err := time.ParseDuration(timeout) - if err == nil { - r.Spec.Timeouts = &tektonv1.TimeoutFields{} - r.Spec.Timeouts.Pipeline = &v1.Duration{Duration: duration} - } - - return r -} - -// WithWorkspace adds a workspace to the PipelineRun using the given name and PersistentVolumeClaim. -// If any of those values is empty, no workspace will be added. -func (r *ReleasePipelineRun) WithWorkspace(name, persistentVolumeClaim string) *ReleasePipelineRun { - if name == "" || persistentVolumeClaim == "" { - return r - } - - r.Spec.Workspaces = append(r.Spec.Workspaces, tektonv1.WorkspaceBinding{ - Name: name, - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: persistentVolumeClaim, - }, - }) - - return r -} diff --git a/tekton/pipeline_run_test.go b/tekton/pipeline_run_test.go deleted file mode 100644 index e942c8b1..00000000 --- a/tekton/pipeline_run_test.go +++ /dev/null @@ -1,295 +0,0 @@ -/* -Copyright 2022 Red Hat Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package tekton - -import ( - "context" - "encoding/json" - "fmt" - "reflect" - "strings" - - tektonutils "github.com/redhat-appstudio/release-service/tekton/utils" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - - ecapiv1alpha1 "github.com/enterprise-contract/enterprise-contract-controller/api/v1alpha1" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/redhat-appstudio/release-service/api/v1alpha1" - - tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type ExtraParams struct { - Name string - Value tektonv1.ParamValue -} - -var _ = Describe("PipelineRun", func() { - const ( - pipelineRunPrefixName = "test-pipeline" - namespace = "default" - workspace = "test-workspace" - persistentVolumeClaim = "test-pvc" - serviceAccountName = "test-service-account" - timeout = "1h0m0s" - apiVersion = "appstudio.redhat.com/v1alpha1" - applicationName = "test-application" - ) - var ( - release *v1alpha1.Release - extraParams *ExtraParams - releasePipelineRun *ReleasePipelineRun - releasePlanAdmission *v1alpha1.ReleasePlanAdmission - enterpriseContractConfigMap *corev1.ConfigMap - enterpriseContractPolicy *ecapiv1alpha1.EnterpriseContractPolicy - ) - BeforeEach(func() { - extraParams = &ExtraParams{ - Name: "extraConfigPath", - Value: tektonv1.ParamValue{ - Type: tektonv1.ParamTypeString, - StringVal: "path/to/extra/config.yaml", - }, - } - release = &v1alpha1.Release{ - TypeMeta: metav1.TypeMeta{ - APIVersion: apiVersion, - Kind: "Release", - }, - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "myrelease-", - Namespace: namespace, - }, - Spec: v1alpha1.ReleaseSpec{ - Snapshot: "testsnapshot", - ReleasePlan: "testreleaseplan", - }, - } - enterpriseContractConfigMap = &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-cm", - }, - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - }, - Data: map[string]string{ - "verify_ec_task_bundle": "test-bundle", - }, - } - enterpriseContractPolicy = &ecapiv1alpha1.EnterpriseContractPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testpolicy", - }, - TypeMeta: metav1.TypeMeta{ - Kind: "EnterpriseContractPolicy", - }, - Spec: ecapiv1alpha1.EnterpriseContractPolicySpec{ - Description: "test-policy-description", - Sources: []ecapiv1alpha1.Source{ - { - Name: "foo", - Policy: []string{"https://github.com/company/policy"}, - Data: []string{"https://github.com/company/data"}, - }, - }, - }, - } - releasePlanAdmission = &v1alpha1.ReleasePlanAdmission{ - Spec: v1alpha1.ReleasePlanAdmissionSpec{ - Applications: []string{"application"}, - Pipeline: &tektonutils.Pipeline{ - PipelineRef: tektonutils.PipelineRef{ - Resolver: "bundles", - Params: []tektonutils.Param{ - {Name: "bundle", Value: "testbundle"}, - {Name: "name", Value: "release-pipeline"}, - {Name: "kind", Value: "pipeline"}, - }, - }, - ServiceAccount: serviceAccountName, - }, - Policy: "testpolicy", - }, - } - - ctx := context.Background() - - // The code below sets the ownership for the Release Object - kind := reflect.TypeOf(v1alpha1.Release{}).Name() - gvk := v1alpha1.GroupVersion.WithKind(kind) - controllerRef := metav1.NewControllerRef(release, gvk) - - // Creating a release - Expect(k8sClient.Create(ctx, release)).Should(Succeed()) - release.SetOwnerReferences([]metav1.OwnerReference{*controllerRef}) - - // Need to set the Kind and APIVersion as it loses it due to: - // https://github.com/kubernetes-sigs/controller-runtime/issues/1870 - release.TypeMeta.APIVersion = apiVersion - release.TypeMeta.Kind = "Release" - - // Creates the PipelineRun Object - releasePipelineRun = NewReleasePipelineRun(pipelineRunPrefixName, namespace) - Expect(k8sClient.Create(ctx, releasePipelineRun.AsPipelineRun())).Should(Succeed()) - }) - - AfterEach(func() { - _ = k8sClient.Delete(ctx, release) - _ = k8sClient.Delete(ctx, releasePipelineRun.AsPipelineRun()) - }) - - When("managing a new PipelineRun", func() { - - It("can create a PipelineRun and the returned object name is prefixed with the provided GenerateName", func() { - Expect(releasePipelineRun.ObjectMeta.Name). - Should(HavePrefix(pipelineRunPrefixName)) - Expect(releasePipelineRun.ObjectMeta.Namespace).To(Equal(namespace)) - }) - - It("can append extra params to PipelineRun and these parameters are present in the object Specs", func() { - releasePipelineRun.WithExtraParam(extraParams.Name, extraParams.Value) - Expect(releasePipelineRun.Spec.Params[0].Name).To(Equal(extraParams.Name)) - Expect(releasePipelineRun.Spec.Params[0].Value.StringVal). - To(Equal(extraParams.Value.StringVal)) - }) - - It("can append owner release information to the object as annotations", func() { - releasePipelineRun.WithOwner(release) - Expect(releasePipelineRun.Annotations).NotTo(BeNil()) - Expect(releasePipelineRun.Finalizers).NotTo(BeEmpty()) - }) - - It("can append the release Name, Namespace, and Application to a PipelineRun object and that these label key names match the correct label format", func() { - releasePipelineRun.WithReleaseAndApplicationMetadata(release, applicationName) - Expect(releasePipelineRun.Labels["release.appstudio.openshift.io/name"]). - To(Equal(release.Name)) - Expect(releasePipelineRun.Labels["release.appstudio.openshift.io/namespace"]). - To(Equal(release.Namespace)) - Expect(releasePipelineRun.Labels["appstudio.openshift.io/application"]). - To(Equal(applicationName)) - Expect(releasePipelineRun.Labels["appstudio.openshift.io/snapshot"]). - To(Equal(release.Spec.Snapshot)) - }) - - It("can return a PipelineRun object from a PipelineRun object", func() { - Expect(reflect.TypeOf(releasePipelineRun.AsPipelineRun())). - To(Equal(reflect.TypeOf(&tektonv1.PipelineRun{}))) - }) - - It("can add the PipelineRef to a PipelineRun object ", func() { - releasePipelineRun.WithPipelineRef(releasePlanAdmission.Spec.Pipeline.PipelineRef.ToTektonPipelineRef()) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef).NotTo(Equal(tektonv1.ResolverRef{})) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Resolver).To(Equal(tektonv1.ResolverName("bundles"))) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params).To(HaveLen(3)) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params[0].Name).To(Equal("bundle")) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params[0].Value.StringVal).To(Equal(releasePlanAdmission.Spec.Pipeline.PipelineRef.Params[0].Value)) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params[1].Name).To(Equal("name")) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params[1].Value.StringVal).To(Equal(releasePlanAdmission.Spec.Pipeline.PipelineRef.Params[1].Value)) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params[2].Name).To(Equal("kind")) - Expect(releasePipelineRun.Spec.PipelineRef.ResolverRef.Params[2].Value.StringVal).To(Equal("pipeline")) - }) - - It("can add the reference to the service account that should be used", func() { - releasePipelineRun.WithServiceAccount(serviceAccountName) - Expect(releasePipelineRun.Spec.TaskRunTemplate.ServiceAccountName).To(Equal(serviceAccountName)) - }) - - It("can add the taskGit pipeline parameters to the PipelineRun object when using a git resolver", func() { - pipelineRef := &tektonutils.PipelineRef{ - Resolver: "git", - Params: []tektonutils.Param{ - { - Name: "url", - Value: "my-url", - }, - { - Name: "revision", - Value: "my-revision", - }, - }, - } - releasePipelineRun.WithTaskGitPipelineParameters(pipelineRef) - Expect(releasePipelineRun.Spec.Params[0].Name).To(Equal("taskGitUrl")) - Expect(releasePipelineRun.Spec.Params[0].Value.StringVal).To(Equal("my-url")) - Expect(releasePipelineRun.Spec.Params[1].Name).To(Equal("taskGitRevision")) - Expect(releasePipelineRun.Spec.Params[1].Value.StringVal).To(Equal("my-revision")) - }) - - It("does not add the taskGit pipeline parameters to the PipelineRun object when using a bundles resolver", func() { - pipelineRef := &tektonutils.PipelineRef{ - Resolver: "bundles", - Params: []tektonutils.Param{ - { - Name: "url", - Value: "my-url", - }, - { - Name: "revision", - Value: "my-revision", - }, - }, - } - releasePipelineRun.WithTaskGitPipelineParameters(pipelineRef) - Expect(len(releasePipelineRun.Spec.Params)).To(Equal(0)) - }) - - It("can add the timeout that should be used", func() { - releasePipelineRun.WithTimeout(timeout) - Expect(releasePipelineRun.Spec.Timeouts.Pipeline.Duration.String()).To(Equal(timeout)) - }) - - It("can add a workspace to the PipelineRun using the given name and PVC", func() { - releasePipelineRun.WithWorkspace(workspace, persistentVolumeClaim) - Expect(releasePipelineRun.Spec.Workspaces).Should(ContainElement(HaveField("Name", Equal(workspace)))) - Expect(releasePipelineRun.Spec.Workspaces).Should(ContainElement(HaveField("PersistentVolumeClaim.ClaimName", Equal(persistentVolumeClaim)))) - }) - - It("can add the EC task bundle parameter to the PipelineRun", func() { - releasePipelineRun.WithEnterpriseContractConfigMap(enterpriseContractConfigMap) - Expect(releasePipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", Equal(string("test-bundle"))))) - }) - - It("can add an EnterpriseContractPolicy to the PipelineRun", func() { - releasePipelineRun.WithEnterpriseContractPolicy(enterpriseContractPolicy) - jsonSpec, _ := json.Marshal(enterpriseContractPolicy.Spec) - Expect(releasePipelineRun.Spec.Params).Should(ContainElement(HaveField("Value.StringVal", Equal(string(jsonSpec))))) - }) - }) - - When("calling WithObjectReferences is called", func() { - It("does nothing if no objects are passed", func() { - releasePipelineRun.WithObjectReferences() - Expect(releasePipelineRun.Spec.Params).To(HaveLen(0)) - }) - - It("adds a new parameter to the Pipeline with a reference to the object", func() { - releasePipelineRun.WithObjectReferences(release) - - Expect(releasePipelineRun.Spec.Params).To(HaveLen(1)) - Expect(releasePipelineRun.Spec.Params[0].Name).To(Equal(strings.ToLower(release.Kind))) - Expect(releasePipelineRun.Spec.Params[0].Value.Type).To(Equal(tektonv1.ParamTypeString)) - Expect(releasePipelineRun.Spec.Params[0].Value.StringVal).To(Equal( - fmt.Sprintf("%s%c%s", release.Namespace, types.Separator, release.Name))) - }) - }) -}) diff --git a/tekton/predicates_test.go b/tekton/predicates_test.go index 76bfee34..c3ab826d 100644 --- a/tekton/predicates_test.go +++ b/tekton/predicates_test.go @@ -17,109 +17,61 @@ limitations under the License. package tekton import ( - "context" - "reflect" - - "k8s.io/utils/clock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/redhat-appstudio/release-service/metadata" + "github.com/redhat-appstudio/release-service/tekton/utils" + v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "github.com/redhat-appstudio/release-service/api/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/event" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -var _ = Describe("Predicates", func() { - - const ( - pipelineRunPrefixName = "test-pipeline" - applicationName = "test-application" - apiVersion = "appstudio.redhat.com/v1alpha1" - namespace = "default" - ) - - var release *v1alpha1.Release - var releasePipelineRun *ReleasePipelineRun - - BeforeEach(func() { - release = &v1alpha1.Release{ - TypeMeta: metav1.TypeMeta{ - APIVersion: apiVersion, - Kind: "Release", - }, - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "testrelease-", - Namespace: namespace, - }, - Spec: v1alpha1.ReleaseSpec{ - Snapshot: "testsnapshot", - ReleasePlan: "testreleaseplan", - }, - } - ctx := context.Background() - - // The code below sets the ownership for the Release Object - kind := reflect.TypeOf(v1alpha1.Release{}).Name() - gvk := v1alpha1.GroupVersion.WithKind(kind) - controllerRef := metav1.NewControllerRef(release, gvk) - - // Creating a release - Expect(k8sClient.Create(ctx, release)).Should(Succeed()) - release.SetOwnerReferences([]metav1.OwnerReference{*controllerRef}) - - // Need to set the Kind and APIVersion as it loses it due to: - // https://github.com/kubernetes-sigs/controller-runtime/issues/1870 - release.TypeMeta.APIVersion = apiVersion - release.TypeMeta.Kind = "Release" - - // Creates the PipelineRun Object - releasePipelineRun = NewReleasePipelineRun(pipelineRunPrefixName, namespace) - Expect(k8sClient.Create(ctx, releasePipelineRun.AsPipelineRun())).Should(Succeed()) - }) - - AfterEach(func() { - _ = k8sClient.Delete(ctx, release) - _ = k8sClient.Delete(ctx, releasePipelineRun.AsPipelineRun()) - }) - +var _ = Describe("Predicates", Ordered, func() { When("testing ReleasePipelineRunSucceededPredicate predicate", func() { - instance := ReleasePipelineRunSucceededPredicate() + var err error + var pipelineRun *v1.PipelineRun + + BeforeAll(func() { + pipelineRun, err = utils.NewPipelineRunBuilder("pipeline-run", "default").Build() + Expect(err).NotTo(HaveOccurred()) + }) It("should ignore creating events", func() { contextEvent := event.CreateEvent{ - Object: releasePipelineRun.AsPipelineRun(), + Object: pipelineRun, } - Expect(instance.Create(contextEvent)).To(BeFalse()) + Expect(ReleasePipelineRunSucceededPredicate().Create(contextEvent)).To(BeFalse()) }) It("should ignore deleting events", func() { contextEvent := event.DeleteEvent{ - Object: releasePipelineRun.AsPipelineRun(), + Object: pipelineRun, } - Expect(instance.Delete(contextEvent)).To(BeFalse()) + Expect(ReleasePipelineRunSucceededPredicate().Delete(contextEvent)).To(BeFalse()) }) It("should ignore generic events", func() { contextEvent := event.GenericEvent{ - Object: releasePipelineRun.AsPipelineRun(), + Object: pipelineRun, } - Expect(instance.Generic(contextEvent)).To(BeFalse()) + Expect(ReleasePipelineRunSucceededPredicate().Generic(contextEvent)).To(BeFalse()) }) - It("should return true when an updated event is received for a succeeded managed Release PipelineRun", func() { - releasePipelineRun.AsPipelineRun().Status.InitializeConditions(clock.RealClock{}) + It("should return true when an updated event is received for a succeeded managed PipelineRun", func() { + var releasePipelineRun *v1.PipelineRun + releasePipelineRun, err = utils.NewPipelineRunBuilder("pipeline-run", "default"). + WithLabels(map[string]string{metadata.PipelinesTypeLabel: metadata.ManagedPipelineType}). + Build() + Expect(err).NotTo(HaveOccurred()) contextEvent := event.UpdateEvent{ - ObjectOld: releasePipelineRun.AsPipelineRun(), - ObjectNew: releasePipelineRun.WithServiceAccount("test-service-account"). - WithReleaseAndApplicationMetadata(release, applicationName). - AsPipelineRun(), + ObjectOld: pipelineRun, + ObjectNew: releasePipelineRun, } releasePipelineRun.Status.MarkRunning("Predicate function tests", "Set it to Unknown") - Expect(instance.Update(contextEvent)).To(BeFalse()) + Expect(ReleasePipelineRunSucceededPredicate().Update(contextEvent)).To(BeFalse()) + releasePipelineRun.Status.MarkSucceeded("Predicate function tests", "Set it to Succeeded") - Expect(instance.Update(contextEvent)).To(BeTrue()) + Expect(ReleasePipelineRunSucceededPredicate().Update(contextEvent)).To(BeTrue()) }) }) }) diff --git a/tekton/utils.go b/tekton/utils.go index 27dce9aa..8079a886 100644 --- a/tekton/utils.go +++ b/tekton/utils.go @@ -32,7 +32,7 @@ func isReleasePipelineRun(object client.Object) bool { labelValue, found := object.GetLabels()[metadata.PipelinesTypeLabel] - return found && labelValue == PipelineTypeRelease + return found && labelValue == metadata.ManagedPipelineType } // hasPipelineSucceeded returns a boolean indicating whether the PipelineRun succeeded or not. diff --git a/tekton/utils/pipeline.go b/tekton/utils/pipeline.go index 0492fdee..962c5f18 100644 --- a/tekton/utils/pipeline.go +++ b/tekton/utils/pipeline.go @@ -48,14 +48,6 @@ type Pipeline struct { // +optional ServiceAccount string `json:"serviceAccountName,omitempty"` - // Timeout is a value to use to override the tekton default Pipelinerun timeout - // - // This field is DEPRECATED and will be replaced by Timeouts in a future change. - // - // +kubebuilder:default="0" - // +optional - Timeout string `json:"timeout,omitempty"` - // Timeouts defines the different Timeouts to use in the PipelineRun execution // +optional Timeouts tektonv1.TimeoutFields `json:"timeouts,omitempty"` diff --git a/tekton/utils/pipeline_run_builder.go b/tekton/utils/pipeline_run_builder.go index 5253ec81..bad94465 100644 --- a/tekton/utils/pipeline_run_builder.go +++ b/tekton/utils/pipeline_run_builder.go @@ -194,6 +194,30 @@ func (b *PipelineRunBuilder) WithParamsFromConfigMap(configMap *corev1.ConfigMap func (b *PipelineRunBuilder) WithPipelineRef(pipelineRef *tektonv1.PipelineRef) *PipelineRunBuilder { b.pipelineRun.Spec.PipelineRef = pipelineRef + if pipelineRef.Resolver == "git" { + for _, param := range pipelineRef.Params { + if param.Name == "revision" { + b.WithParams(tektonv1.Param{ + Name: "taskGitRevision", + Value: tektonv1.ParamValue{ + Type: tektonv1.ParamTypeString, + StringVal: param.Value.StringVal, + }, + }) + } + + if param.Name == "url" { + b.WithParams(tektonv1.Param{ + Name: "taskGitUrl", + Value: tektonv1.ParamValue{ + Type: tektonv1.ParamTypeString, + StringVal: param.Value.StringVal, + }, + }) + } + } + } + return b } @@ -205,8 +229,12 @@ func (b *PipelineRunBuilder) WithServiceAccount(serviceAccount string) *Pipeline } // WithTimeouts sets the Timeouts for the PipelineRun. -func (b *PipelineRunBuilder) WithTimeouts(timeouts *tektonv1.TimeoutFields) *PipelineRunBuilder { - b.pipelineRun.Spec.Timeouts = timeouts +func (b *PipelineRunBuilder) WithTimeouts(timeouts, defaultTimeouts *tektonv1.TimeoutFields) *PipelineRunBuilder { + if timeouts == nil || *timeouts == (tektonv1.TimeoutFields{}) { + b.pipelineRun.Spec.Timeouts = defaultTimeouts + } else { + b.pipelineRun.Spec.Timeouts = timeouts + } return b } diff --git a/tekton/utils/pipeline_run_builder_test.go b/tekton/utils/pipeline_run_builder_test.go index b1e39814..0e4f32e0 100644 --- a/tekton/utils/pipeline_run_builder_test.go +++ b/tekton/utils/pipeline_run_builder_test.go @@ -329,6 +329,30 @@ var _ = Describe("PipelineRun builder", func() { builder.WithPipelineRef(pipelineRef) Expect(builder.pipelineRun.Spec.PipelineRef).To(Equal(pipelineRef)) }) + + It("adds the taskGit pipeline parameters to the PipelineRun object when using a git resolver", func() { + builder := NewPipelineRunBuilder("testPrefix", "testNamespace") + + pipelineRef := &PipelineRef{ + Resolver: "git", + Params: []Param{ + { + Name: "url", + Value: "pipelineUrl", + }, + { + Name: "revision", + Value: "pipelineRevision", + }, + }, + } + + builder.WithPipelineRef(pipelineRef.ToTektonPipelineRef()) + Expect(builder.pipelineRun.Spec.Params[0].Name).To(Equal("taskGitUrl")) + Expect(builder.pipelineRun.Spec.Params[0].Value.StringVal).To(Equal("pipelineUrl")) + Expect(builder.pipelineRun.Spec.Params[1].Name).To(Equal("taskGitRevision")) + Expect(builder.pipelineRun.Spec.Params[1].Value.StringVal).To(Equal("pipelineRevision")) + }) }) When("WithServiceAccount method is called", func() { @@ -348,9 +372,20 @@ var _ = Describe("PipelineRun builder", func() { Tasks: &metav1.Duration{Duration: 1 * time.Hour}, Finally: &metav1.Duration{Duration: 1 * time.Hour}, } - builder.WithTimeouts(timeouts) + builder.WithTimeouts(timeouts, nil) Expect(builder.pipelineRun.Spec.Timeouts).To(Equal(timeouts)) }) + + It("should use the default timeouts if the given timeouts are empty", func() { + builder := NewPipelineRunBuilder("testPrefix", "testNamespace") + defaultTimeouts := &tektonv1.TimeoutFields{ + Pipeline: &metav1.Duration{Duration: 1 * time.Hour}, + Tasks: &metav1.Duration{Duration: 1 * time.Hour}, + Finally: &metav1.Duration{Duration: 1 * time.Hour}, + } + builder.WithTimeouts(nil, defaultTimeouts) + Expect(builder.pipelineRun.Spec.Timeouts).To(Equal(defaultTimeouts)) + }) }) When("WithWorkspaceFromVolumeTemplate method is called", func() { diff --git a/tekton/utils_test.go b/tekton/utils_test.go index c8c070e5..bf390492 100644 --- a/tekton/utils_test.go +++ b/tekton/utils_test.go @@ -17,86 +17,41 @@ limitations under the License. package tekton import ( - "context" - "reflect" - - "k8s.io/utils/clock" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - - "github.com/redhat-appstudio/release-service/api/v1alpha1" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/redhat-appstudio/release-service/metadata" + "github.com/redhat-appstudio/release-service/tekton/utils" ) -var _ = Describe("Utils", func() { - - const ( - pipelineRunPrefixName = "test-pipeline" - applicationName = "test-application" - apiVersion = "appstudio.redhat.com/v1alpha1" - namespace = "default" - ) - - var release *v1alpha1.Release - var releasePipelineRun *ReleasePipelineRun - - BeforeEach(func() { - release = &v1alpha1.Release{ - TypeMeta: metav1.TypeMeta{ - APIVersion: apiVersion, - Kind: "Release", - }, - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "testrelease-", - Namespace: namespace, - }, - Spec: v1alpha1.ReleaseSpec{ - Snapshot: "testsnapshot", - ReleasePlan: "testreleaseplan", - }, - } - ctx := context.Background() - - // The code below sets the ownership for the Release Object - kind := reflect.TypeOf(v1alpha1.Release{}).Name() - gvk := v1alpha1.GroupVersion.WithKind(kind) - controllerRef := metav1.NewControllerRef(release, gvk) - - // Creating a release - Expect(k8sClient.Create(ctx, release)).Should(Succeed()) - release.SetOwnerReferences([]metav1.OwnerReference{*controllerRef}) - - // Need to set the Kind and APIVersion as it loses it due to: - // https://github.com/kubernetes-sigs/controller-runtime/issues/1870 - release.TypeMeta.APIVersion = apiVersion - release.TypeMeta.Kind = "Release" - - // Creates the PipelineRun Object - releasePipelineRun = NewReleasePipelineRun(pipelineRunPrefixName, namespace) - Expect(k8sClient.Create(ctx, releasePipelineRun.AsPipelineRun())).Should(Succeed()) - }) +var _ = Describe("Utils", Ordered, func() { + When("isReleasePipelineRun is called", func() { + It("should return false when the PipelineRun is not of type 'managed'", func() { + pipelineRun, err := utils.NewPipelineRunBuilder("pipeline-run", "default").Build() + Expect(err).NotTo(HaveOccurred()) + Expect(isReleasePipelineRun(pipelineRun)).To(BeFalse()) + }) - AfterEach(func() { - _ = k8sClient.Delete(ctx, release) - _ = k8sClient.Delete(ctx, releasePipelineRun.AsPipelineRun()) + It("should return true when the PipelineRun is of type 'managed'", func() { + pipelineRun, err := utils.NewPipelineRunBuilder("pipeline-run", "default"). + WithLabels(map[string]string{metadata.PipelinesTypeLabel: metadata.ManagedPipelineType}). + Build() + Expect(err).NotTo(HaveOccurred()) + Expect(isReleasePipelineRun(pipelineRun)).To(BeTrue()) + }) }) - When("using utility functions on PipelineRun objects", func() { - It("is a PipelineRun object and contains the required labels that identifies it as one", func() { - Expect(isReleasePipelineRun(releasePipelineRun. - WithReleaseAndApplicationMetadata(release, applicationName). - AsPipelineRun())).To(Equal(true)) + When("hasPipelineSucceeded is called", func() { + It("should return false when the PipelineRun has not succeeded", func() { + pipelineRun, err := utils.NewPipelineRunBuilder("pipeline-run", "default").Build() + Expect(err).NotTo(HaveOccurred()) + Expect(hasPipelineSucceeded(pipelineRun)).To(BeFalse()) }) - It("returns true when PipelineRun.Status is `Succeeded` or false otherwise", func() { - releasePipelineRun.AsPipelineRun().Status.InitializeConditions(clock.RealClock{}) - // MarkRunning sets Status to Unknown - releasePipelineRun.Status.MarkRunning("PipelineRun Tests", "sets it to Unknown") - Expect(hasPipelineSucceeded(releasePipelineRun.AsPipelineRun())).Should(BeFalse()) - releasePipelineRun.Status.MarkSucceeded("PipelineRun Tests", "sets it to Succeeded") - Expect(hasPipelineSucceeded(releasePipelineRun.AsPipelineRun())).Should(BeTrue()) + It("should return true when the PipelineRun is of type 'managed'", func() { + pipelineRun, err := utils.NewPipelineRunBuilder("pipeline-run", "default").Build() + Expect(err).NotTo(HaveOccurred()) + pipelineRun.Status.MarkSucceeded("", "") + Expect(hasPipelineSucceeded(pipelineRun)).To(BeTrue()) }) }) })