diff --git a/controllers/component_build_controller.go b/controllers/component_build_controller.go index 3e2a1edc..efafba29 100644 --- a/controllers/component_build_controller.go +++ b/controllers/component_build_controller.go @@ -72,6 +72,7 @@ const ( buildPipelineSelectorResourceName = "build-pipeline-selector" defaultBuildPipelineAnnotation = "build.appstudio.openshift.io/pipeline" buildPipelineConfigMapResourceName = "build-pipeline-config" + buildPipelineConfigName = "config.yaml" ) type BuildStatus struct { @@ -252,7 +253,7 @@ func (r *ComponentBuildReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, nil } - pipelineRef, err := GetBuildPipelineFromComponentAnnotation(&component) + pipelineRef, err := r.GetBuildPipelineFromComponentAnnotation(ctx, &component) if err != nil { log.Error(err, fmt.Sprintf("Failed to read %s annotation on component %s", defaultBuildPipelineAnnotation, component.Name), l.Action, l.ActionView) diff --git a/controllers/component_build_controller_common.go b/controllers/component_build_controller_common.go index a40f9e6b..3de06fbe 100644 --- a/controllers/component_build_controller_common.go +++ b/controllers/component_build_controller_common.go @@ -33,6 +33,7 @@ import ( appstudiov1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" devfile "github.com/redhat-appstudio/application-service/cdq-analysis/pkg" tektonapi "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "gopkg.in/yaml.v2" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" @@ -46,6 +47,11 @@ type BuildPipeline struct { Bundle string `json:"bundle,omitempty"` } +type pipelineConfig struct { + DefaultPipelineName string `yaml:"default-pipeline-name"` + Pipelines []BuildPipeline `yaml:"pipelines"` +} + // That way it can be mocked in tests var DevfileSearchForDockerfile = devfile.SearchForDockerfile @@ -98,26 +104,59 @@ func getGitProvider(component appstudiov1alpha1.Component) (string, error) { } // GetBuildPipelineFromComponentAnnotation parses pipeline annotation on component and returns build pipeline -func GetBuildPipelineFromComponentAnnotation(component *appstudiov1alpha1.Component) (*tektonapi.PipelineRef, error) { +func (r *ComponentBuildReconciler) GetBuildPipelineFromComponentAnnotation(ctx context.Context, component *appstudiov1alpha1.Component) (*tektonapi.PipelineRef, error) { buildPipeline, err := readBuildPipelineAnnotation(component) if err != nil { return nil, err } + if buildPipeline == nil { + return nil, nil + } + if buildPipeline.Bundle == "" || buildPipeline.Name == "" { + err = fmt.Errorf("missing name or bundle in pipeline annotation: name=%s bundle=%s", buildPipeline.Name, buildPipeline.Bundle) + return nil, boerrors.NewBuildOpError(boerrors.EWrongPipelineAnnotation, err) + } + finalBundle := buildPipeline.Bundle - if buildPipeline.Bundle != "" { - // for now we will return PipelineRef format, because it is the same what methods which use build-selector are returning - pipelineRef := &tektonapi.PipelineRef{ - ResolverRef: tektonapi.ResolverRef{ - Resolver: "bundles", - Params: []tektonapi.Param{ - {Name: "name", Value: *tektonapi.NewStructuredValues(buildPipeline.Name)}, - {Name: "bundle", Value: *tektonapi.NewStructuredValues(buildPipeline.Bundle)}, - }, - }, + if buildPipeline.Bundle == "latest" { + pipelinesConfigMap := &corev1.ConfigMap{} + if err := r.Client.Get(ctx, types.NamespacedName{Name: buildPipelineConfigMapResourceName, Namespace: BuildServiceNamespaceName}, pipelinesConfigMap); err != nil { + if errors.IsNotFound(err) { + return nil, boerrors.NewBuildOpError(boerrors.EBuildPipelineConfigNotDefined, err) + } + return nil, err + } + + buildPipelineData := &pipelineConfig{} + if err := yaml.Unmarshal([]byte(pipelinesConfigMap.Data[buildPipelineConfigName]), buildPipelineData); err != nil { + return nil, boerrors.NewBuildOpError(boerrors.EBuildPipelineConfigNotValid, err) + } + + for _, pipeline := range buildPipelineData.Pipelines { + if pipeline.Name == buildPipeline.Name { + finalBundle = pipeline.Bundle + break + } + } + + // requested pipeline was not found in configMap + if finalBundle == "latest" { + err = fmt.Errorf("invalid pipeline name in pipeline annotation: name=%s", buildPipeline.Name) + return nil, boerrors.NewBuildOpError(boerrors.EBuildPipelineInvalid, err) } - return pipelineRef, nil } - return nil, nil + + // for now we will return PipelineRef format, because it is the same what methods which use build-selector are returning + pipelineRef := &tektonapi.PipelineRef{ + ResolverRef: tektonapi.ResolverRef{ + Resolver: "bundles", + Params: []tektonapi.Param{ + {Name: "name", Value: *tektonapi.NewStructuredValues(buildPipeline.Name)}, + {Name: "bundle", Value: *tektonapi.NewStructuredValues(finalBundle)}, + }, + }, + } + return pipelineRef, nil } // GetPipelineForComponent searches for the build pipeline to use on the component. @@ -416,7 +455,7 @@ func getPipelineNameAndBundle(pipelineRef *tektonapi.PipelineRef) (string, strin func readBuildPipelineAnnotation(component *appstudiov1alpha1.Component) (*BuildPipeline, error) { if component.Annotations == nil { - return &BuildPipeline{}, nil + return nil, nil } requestedPipeline, requestedPipelineExists := component.Annotations[defaultBuildPipelineAnnotation] @@ -429,5 +468,5 @@ func readBuildPipelineAnnotation(component *appstudiov1alpha1.Component) (*Build } return buildPipeline, nil } - return &BuildPipeline{}, nil + return nil, nil } diff --git a/controllers/component_build_controller_pac.go b/controllers/component_build_controller_pac.go index 9acdd0de..107618ef 100644 --- a/controllers/component_build_controller_pac.go +++ b/controllers/component_build_controller_pac.go @@ -900,8 +900,10 @@ func (r *ComponentBuildReconciler) generatePaCPipelineRunConfigs(ctx context.Con var err error // no need to check error because it would fail already in Reconcile - pipelineRef, _ = GetBuildPipelineFromComponentAnnotation(component) + pipelineRef, _ = r.GetBuildPipelineFromComponentAnnotation(ctx, component) + pipelineAnnotationUsed := true if pipelineRef == nil { + pipelineAnnotationUsed = false pipelineRef, additionalPipelineParams, err = r.GetPipelineForComponent(ctx, component) if err != nil { return nil, nil, err @@ -924,7 +926,7 @@ func (r *ComponentBuildReconciler) generatePaCPipelineRunConfigs(ctx context.Con } pipelineRunOnPush, err := generatePaCPipelineRunForComponent( - component, pipelineSpec, additionalPipelineParams, false, pacTargetBranch, gitClient) + component, pipelineSpec, additionalPipelineParams, false, pacTargetBranch, gitClient, pipelineAnnotationUsed) if err != nil { return nil, nil, err } @@ -934,7 +936,7 @@ func (r *ComponentBuildReconciler) generatePaCPipelineRunConfigs(ctx context.Con } pipelineRunOnPR, err := generatePaCPipelineRunForComponent( - component, pipelineSpec, additionalPipelineParams, true, pacTargetBranch, gitClient) + component, pipelineSpec, additionalPipelineParams, true, pacTargetBranch, gitClient, pipelineAnnotationUsed) if err != nil { return nil, nil, err } @@ -1135,7 +1137,8 @@ func generatePaCPipelineRunForComponent( additionalPipelineParams []tektonapi.Param, onPull bool, pacTargetBranch string, - gitClient gp.GitProviderClient) (*tektonapi.PipelineRun, error) { + gitClient gp.GitProviderClient, + pipelineAnnotationUsed bool) (*tektonapi.PipelineRun, error) { if pacTargetBranch == "" { return nil, fmt.Errorf("target branch can't be empty for generating PaC PipelineRun for: %v", component) @@ -1186,8 +1189,7 @@ func generatePaCPipelineRunForComponent( } // no need to check error because it would fail already in Reconcile - pipelineAnnotationUsed, _ := GetBuildPipelineFromComponentAnnotation(component) - if pipelineAnnotationUsed == nil { + if !pipelineAnnotationUsed { dockerFile, err := DevfileSearchForDockerfile([]byte(component.Status.Devfile)) if err != nil { return nil, boerrors.NewBuildOpError(boerrors.EInvalidDevfile, err) diff --git a/controllers/component_build_controller_simple_build.go b/controllers/component_build_controller_simple_build.go index f158944b..fe5aabac 100644 --- a/controllers/component_build_controller_simple_build.go +++ b/controllers/component_build_controller_simple_build.go @@ -57,8 +57,10 @@ func (r *ComponentBuildReconciler) SubmitNewBuild(ctx context.Context, component var err error // no need to check error because it would fail already in Reconcile - pipelineRef, _ = GetBuildPipelineFromComponentAnnotation(component) + pipelineRef, _ = r.GetBuildPipelineFromComponentAnnotation(ctx, component) + pipelineAnnotationUsed := true if pipelineRef == nil { + pipelineAnnotationUsed = false pipelineRef, additionalPipelineParams, err = r.GetPipelineForComponent(ctx, component) if err != nil { return err @@ -87,7 +89,7 @@ func (r *ComponentBuildReconciler) SubmitNewBuild(ctx context.Context, component return err } - buildPipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalPipelineParams, buildGitInfo) + buildPipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalPipelineParams, buildGitInfo, pipelineAnnotationUsed) if err != nil { log.Error(err, fmt.Sprintf("Failed to generate PipelineRun to build %s component in %s namespace", component.Name, component.Namespace)) return err @@ -199,7 +201,7 @@ func (r *ComponentBuildReconciler) getBuildGitInfo(ctx context.Context, componen }, nil } -func generatePipelineRunForComponent(component *appstudiov1alpha1.Component, pipelineRef *tektonapi.PipelineRef, additionalPipelineParams []tektonapi.Param, pRunGitInfo *buildGitInfo) (*tektonapi.PipelineRun, error) { +func generatePipelineRunForComponent(component *appstudiov1alpha1.Component, pipelineRef *tektonapi.PipelineRef, additionalPipelineParams []tektonapi.Param, pRunGitInfo *buildGitInfo, pipelineAnnotationUsed bool) (*tektonapi.PipelineRun, error) { timestamp := time.Now().Unix() pipelineGenerateName := fmt.Sprintf("%s-", component.Name) gitBranch := "" @@ -241,8 +243,7 @@ func generatePipelineRunForComponent(component *appstudiov1alpha1.Component, pip } // no need to check error because it would fail already in Reconcile - pipelineAnnotationUsed, _ := GetBuildPipelineFromComponentAnnotation(component) - if pipelineAnnotationUsed == nil { + if !pipelineAnnotationUsed { dockerFile, err := DevfileSearchForDockerfile([]byte(component.Status.Devfile)) if err != nil { return nil, boerrors.NewBuildOpError(boerrors.EInvalidDevfile, err) diff --git a/controllers/component_build_controller_test.go b/controllers/component_build_controller_test.go index 98acc0cc..c4bd454c 100644 --- a/controllers/component_build_controller_test.go +++ b/controllers/component_build_controller_test.go @@ -186,6 +186,59 @@ var _ = Describe("Component initial build controller", func() { expectPacBuildStatus(resourcePacPrepKey, "enabled", 0, "", mergeUrl) }) + It("should successfully submit PR with PaC definitions using GitHub application, using 'latest' bundle", func() { + mergeUrl := "merge-url" + + isCreatePaCPullRequestInvoked := false + EnsurePaCMergeRequestFunc = func(repoUrl string, d *gp.MergeRequestData) (string, error) { + isCreatePaCPullRequestInvoked = true + Expect(repoUrl).To(Equal(SampleRepoLink + "-" + resourcePacPrepKey.Name)) + Expect(len(d.Files)).To(Equal(2)) + for _, file := range d.Files { + Expect(strings.HasPrefix(file.FullPath, ".tekton/")).To(BeTrue()) + } + Expect(d.CommitMessage).ToNot(BeEmpty()) + Expect(d.BranchName).ToNot(BeEmpty()) + Expect(d.BaseBranchName).To(Equal("main")) + Expect(d.Title).ToNot(BeEmpty()) + Expect(d.Text).ToNot(BeEmpty()) + Expect(d.AuthorName).ToNot(BeEmpty()) + Expect(d.AuthorEmail).ToNot(BeEmpty()) + return mergeUrl, nil + } + SetupPaCWebhookFunc = func(string, string, string) error { + defer GinkgoRecover() + Fail("Should not create webhook if GitHub application is used") + return nil + } + + createDefaultBuildPipelineConfigMap(defaultPipelineConfigMapKey) + annotationValue := fmt.Sprintf("{\"name\":\"%s\",\"bundle\":\"%s\"}", defaultPipelineName, "latest") + annotations := map[string]string{defaultBuildPipelineAnnotation: annotationValue} + createCustomComponentWithBuildRequestWithoutDevfile(componentConfig{ + componentKey: resourcePacPrepKey, + annotations: annotations, + }, BuildRequestConfigurePaCAnnotationValue) + + pacRepo := waitPaCRepositoryCreated(resourcePacPrepKey) + Expect(pacRepo.Spec.Params).ShouldNot(BeNil()) + existingParams := map[string]string{} + for _, param := range *pacRepo.Spec.Params { + existingParams[param.Name] = param.Value + } + val, ok := existingParams[pacCustomParamAppstudioWorkspace] + Expect(ok).Should(BeTrue()) + Expect(val).Should(Equal("build")) + + waitPaCFinalizerOnComponent(resourcePacPrepKey) + Eventually(func() bool { + return isCreatePaCPullRequestInvoked + }, timeout, interval).Should(BeTrue()) + + expectPacBuildStatus(resourcePacPrepKey, "enabled", 0, "", mergeUrl) + deleteBuildPipelineConfigMap(defaultPipelineConfigMapKey) + }) + It("should fail to submit PR if build pipeline annotation isn't valid json", func() { annotations := map[string]string{defaultBuildPipelineAnnotation: "wrong"} createCustomComponentWithBuildRequestWithoutDevfile(componentConfig{ @@ -201,6 +254,44 @@ var _ = Describe("Component initial build controller", func() { errorMessage := fmt.Sprintf("%d: %s", expectError.GetErrorId(), expectError.ShortError()) Expect(buildStatus.Message).To(ContainSubstring(errorMessage)) }) + + It("should fail to submit PR if build pipeline annotation has non existing pipeline", func() { + createDefaultBuildPipelineConfigMap(defaultPipelineConfigMapKey) + annotationValue := fmt.Sprintf("{\"name\":\"%s\",\"bundle\":\"%s\"}", "wrong-pipeline", "latest") + annotations := map[string]string{defaultBuildPipelineAnnotation: annotationValue} + createCustomComponentWithBuildRequestWithoutDevfile(componentConfig{ + componentKey: resourcePacPrepKey, + annotations: annotations, + }, BuildRequestConfigurePaCAnnotationValue) + waitComponentAnnotationGone(resourcePacPrepKey, BuildRequestAnnotationName) + + expectError := boerrors.NewBuildOpError(boerrors.EBuildPipelineInvalid, nil) + + buildStatus := readBuildStatus(getComponent(resourcePacPrepKey)) + Expect(buildStatus).ToNot(BeNil()) + errorMessage := fmt.Sprintf("%d: %s", expectError.GetErrorId(), expectError.ShortError()) + Expect(buildStatus.Message).To(ContainSubstring(errorMessage)) + deleteBuildPipelineConfigMap(defaultPipelineConfigMapKey) + }) + + It("should fail to submit PR if build pipeline annotation is missing bundle and name", func() { + createDefaultBuildPipelineConfigMap(defaultPipelineConfigMapKey) + annotationValue := "{\"some\":\"wrong\"}" + annotations := map[string]string{defaultBuildPipelineAnnotation: annotationValue} + createCustomComponentWithBuildRequestWithoutDevfile(componentConfig{ + componentKey: resourcePacPrepKey, + annotations: annotations, + }, BuildRequestConfigurePaCAnnotationValue) + waitComponentAnnotationGone(resourcePacPrepKey, BuildRequestAnnotationName) + + expectError := boerrors.NewBuildOpError(boerrors.EWrongPipelineAnnotation, nil) + + buildStatus := readBuildStatus(getComponent(resourcePacPrepKey)) + Expect(buildStatus).ToNot(BeNil()) + errorMessage := fmt.Sprintf("%d: %s", expectError.GetErrorId(), expectError.ShortError()) + Expect(buildStatus.Message).To(ContainSubstring(errorMessage)) + deleteBuildPipelineConfigMap(defaultPipelineConfigMapKey) + }) }) // when build pipeline selector will be removed @@ -1444,6 +1535,46 @@ var _ = Describe("Component initial build controller", func() { Expect(pipelineRun.Annotations["build.appstudio.redhat.com/pipeline_name"]).To(Equal(defaultPipelineName)) Expect(pipelineRun.Annotations["build.appstudio.redhat.com/bundle"]).To(Equal(defaultPipelineBundle)) }) + + It("should submit initial build on component creation, using 'latest' bundle", func() { + gitSourceSHA := "d1a9e858489d1515621398fb02942da068f1c956" + isGetBranchShaInvoked := false + GetBranchShaFunc = func(repoUrl string, branchName string) (string, error) { + isGetBranchShaInvoked = true + Expect(repoUrl).To(Equal(SampleRepoLink + "-" + resouceSimpleBuildKey.Name)) + return gitSourceSHA, nil + } + GetBrowseRepositoryAtShaLinkFunc = func(repoUrl, sha string) string { + Expect(repoUrl).To(Equal(SampleRepoLink + "-" + resouceSimpleBuildKey.Name)) + Expect(sha).To(Equal(gitSourceSHA)) + return "https://github.com/devfile-samples/devfile-sample-java-springboot-basic?rev=" + gitSourceSHA + } + + createDefaultBuildPipelineConfigMap(defaultPipelineConfigMapKey) + annotationValue := fmt.Sprintf("{\"name\":\"%s\",\"bundle\":\"%s\"}", defaultPipelineName, "latest") + annotations := map[string]string{defaultBuildPipelineAnnotation: annotationValue} + createCustomComponentWithoutBuildRequestWithoutDevfile(componentConfig{ + componentKey: resouceSimpleBuildKey, + annotations: annotations}) + + Eventually(func() bool { + return isGetBranchShaInvoked + }, timeout, interval).Should(BeTrue()) + + waitOneInitialPipelineRunCreated(resouceSimpleBuildKey) + waitComponentAnnotationGone(resouceSimpleBuildKey, BuildRequestAnnotationName) + expectSimpleBuildStatus(resouceSimpleBuildKey, 0, "", false) + + // Check pipeline run labels and annotations + pipelineRun := listComponentPipelineRuns(resouceSimpleBuildKey)[0] + Expect(pipelineRun.Annotations[gitCommitShaAnnotationName]).To(Equal(gitSourceSHA)) + Expect(pipelineRun.Annotations[gitRepoAtShaAnnotationName]).To( + Equal("https://github.com/devfile-samples/devfile-sample-java-springboot-basic?rev=" + gitSourceSHA)) + Expect(pipelineRun.Annotations["build.appstudio.redhat.com/pipeline_name"]).To(Equal(defaultPipelineName)) + Expect(pipelineRun.Annotations["build.appstudio.redhat.com/bundle"]).To(Equal(defaultPipelineBundle)) + + deleteBuildPipelineConfigMap(defaultPipelineConfigMapKey) + }) }) // when build pipeline selector will be removed diff --git a/controllers/component_build_controller_unit_test.go b/controllers/component_build_controller_unit_test.go index b644fc11..e1ecc53e 100644 --- a/controllers/component_build_controller_unit_test.go +++ b/controllers/component_build_controller_unit_test.go @@ -245,7 +245,7 @@ func TestGenerateInitialPipelineRunForComponentDevfileError(t *testing.T) { browseRepositoryAtShaLink: "https://githost.com/user/repo?rev=" + commitSha, } - _, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, pRunGitInfo) + _, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, pRunGitInfo, false) if err == nil { t.Error("generateInitialPipelineRunForComponentDevfileError(): Didn't return error") } else { @@ -303,7 +303,7 @@ func TestGenerateInitialPipelineRunForComponentDockerfileContext(t *testing.T) { return &dockerfileImage, nil } - pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, &buildGitInfo{}) + pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, &buildGitInfo{}, false) if err != nil { t.Error("generateInitialPipelineRunForComponentDockerfileContext(): Failed to generate pipeline run") @@ -377,7 +377,7 @@ func TestGenerateInitialPipelineRunForComponentDockerfileContextPipelineFromAnno return &dockerfileImage, nil } - pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, &buildGitInfo{}) + pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, &buildGitInfo{}, true) if err != nil { t.Error("generateInitialPipelineRunForComponentDockerfileContext(): Failed to generate pipeline run") @@ -449,7 +449,7 @@ func TestGenerateInitialPipelineRunForComponent(t *testing.T) { } DevfileSearchForDockerfile = devfile.SearchForDockerfile - pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, pRunGitInfo) + pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, pRunGitInfo, false) if err != nil { t.Error("generateInitialPipelineRunForComponent(): Failed to genertate pipeline run") } @@ -580,7 +580,7 @@ func TestGenerateInitialPipelineRunForComponentPipelineFromAnnotation(t *testing browseRepositoryAtShaLink: "https://githost.com/user/repo?rev=" + commitSha, } - pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, pRunGitInfo) + pipelineRun, err := generatePipelineRunForComponent(component, pipelineRef, additionalParams, pRunGitInfo, true) if err != nil { t.Error("generateInitialPipelineRunForComponent(): Failed to genertate pipeline run") } @@ -727,7 +727,7 @@ func TestGeneratePaCPipelineRunForComponent(t *testing.T) { branchName := "custom-branch" ResetTestGitProviderClient() - pipelineRun, err := generatePaCPipelineRunForComponent(component, pipelineSpec, additionalParams, true, branchName, testGitProviderClient) + pipelineRun, err := generatePaCPipelineRunForComponent(component, pipelineSpec, additionalParams, true, branchName, testGitProviderClient, false) if err != nil { t.Error("generatePaCPipelineRunForComponent(): Failed to genertate pipeline run") } @@ -863,7 +863,7 @@ func TestGeneratePaCPipelineRunForComponentPipelineFromAnnotation(t *testing.T) branchName := "custom-branch" ResetTestGitProviderClient() - pipelineRun, err := generatePaCPipelineRunForComponent(component, pipelineSpec, additionalParams, true, branchName, testGitProviderClient) + pipelineRun, err := generatePaCPipelineRunForComponent(component, pipelineSpec, additionalParams, true, branchName, testGitProviderClient, true) if err != nil { t.Error("generatePaCPipelineRunForComponent(): Failed to genertate pipeline run") } @@ -984,7 +984,7 @@ func TestGeneratePaCPipelineRunForComponent_ShouldStopOnDevfileError(t *testing. } ResetTestGitProviderClient() - _, err := generatePaCPipelineRunForComponent(component, nil, nil, true, "main", testGitProviderClient) + _, err := generatePaCPipelineRunForComponent(component, nil, nil, true, "main", testGitProviderClient, false) DevfileSearchForDockerfile = devfile.SearchForDockerfile if err == nil { t.Errorf("generatePaCPipelineRunForComponent(): expected error") @@ -998,7 +998,7 @@ func TestGeneratePaCPipelineRunForComponent_ShouldStopOnDevfileError(t *testing. } func TestGeneratePaCPipelineRunForComponent_ShouldStopIfTargetBranchIsNotSet(t *testing.T) { - _, err := generatePaCPipelineRunForComponent(nil, nil, nil, true, "", nil) + _, err := generatePaCPipelineRunForComponent(nil, nil, nil, true, "", nil, false) if err == nil { t.Errorf("generatePaCPipelineRunForComponent(): expected error") } diff --git a/controllers/suite_util_test.go b/controllers/suite_util_test.go index e4d9decd..a7b21707 100644 --- a/controllers/suite_util_test.go +++ b/controllers/suite_util_test.go @@ -83,16 +83,6 @@ type componentConfig struct { annotations map[string]string } -type pipelineEntry struct { - Name string `yaml:"name"` - Bundle string `yaml:"bundle"` -} - -type pipelineConfig struct { - DefaultPipelineName string `yaml:"default-pipeline-name"` - Pipelines []pipelineEntry `yaml:"pipelines"` -} - func isOwnedBy(resource []metav1.OwnerReference, component appstudiov1alpha1.Component) bool { if len(resource) == 0 { return false @@ -742,10 +732,10 @@ func createBuildPipelineConfigMap(configMapKey types.NamespacedName, pipelineBun configMapData := map[string]string{} buildPipelineData := pipelineConfig{ DefaultPipelineName: pipelineName, - Pipelines: []pipelineEntry{{Name: pipelineName, Bundle: pipelineBundle}}, + Pipelines: []BuildPipeline{{Name: pipelineName, Bundle: pipelineBundle}}, } yamlData, _ := yaml.Marshal(&buildPipelineData) - configMapData["config.yaml"] = string(yamlData) + configMapData[buildPipelineConfigName] = string(yamlData) buildPipelineConfigMap := corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{Name: configMapKey.Name, Namespace: configMapKey.Namespace}, diff --git a/pkg/boerrors/perror.go b/pkg/boerrors/perror.go index c453cccf..abbc1aac 100644 --- a/pkg/boerrors/perror.go +++ b/pkg/boerrors/perror.go @@ -164,6 +164,14 @@ const ( EUnsupportedPipelineRef BOErrorId = 302 // EMissingParamsForBundleResolver The pipelineRef selected for a component is missing parameters required for the bundle resolver. EMissingParamsForBundleResolver BOErrorId = 303 + // EWrongPipelineAnnotation Value of 'build.appstudio.openshift.io/pipeline' component annotation has wrong or missing values + EWrongPipelineAnnotation BOErrorId = 304 + // EBuildPipelineConfigNotDefined build-pipeline-config configMap not found + EBuildPipelineConfigNotDefined BOErrorId = 305 + // EBuildPipelineConfigNotValid build-pipeline-config configMap is not valid yaml + EBuildPipelineConfigNotValid BOErrorId = 306 + // EBuildPipelineInvalid pipeline in 'build.appstudio.openshift.io/pipeline' doesn't exist in build-pipeline-config configMap + EBuildPipelineInvalid BOErrorId = 307 // EPipelineRetrievalFailed Failed to retrieve a Tekton Pipeline. EPipelineRetrievalFailed BOErrorId = 400 @@ -211,6 +219,10 @@ var boErrorMessages = map[BOErrorId]string{ EBuildPipelineSelectorNotDefined: "Build pipeline selector is not defined yet.", EUnsupportedPipelineRef: "The pipelineRef for this component (based on pipeline selectors) is not supported.", EMissingParamsForBundleResolver: "The pipelineRef for this component is missing required parameters ('name' and/or 'bundle').", + EWrongPipelineAnnotation: "'build.appstudio.openshift.io/pipeline' component annotation has wrong or missing values", + EBuildPipelineConfigNotDefined: "build-pipeline-config ConfigMap not found", + EBuildPipelineConfigNotValid: "build-pipeline-config ConfigMap data in config.yaml is not valid yaml", + EBuildPipelineInvalid: "pipeline referenced in 'build.appstudio.openshift.io/pipeline' annotation doesn't exist in build-pipeline-config ConfigMap", EPipelineRetrievalFailed: "Failed to retrieve the pipeline selected for this component.", EPipelineConversionFailed: "Failed to convert the selected pipeline to the supported Tekton API version.",