This is an automated email from the ASF dual-hosted git repository.

wmedvedeo pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-serverless-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new 5936beeb kie-kogito-serverless-operator-441: Make the SonataFlowBuild 
smarter to manage persistence related extensions/props based on configuration 
(#457)
5936beeb is described below

commit 5936beebd371f3bd9e847061be0c1b9d61acf33c
Author: Walter Medvedeo <[email protected]>
AuthorDate: Wed May 8 19:06:06 2024 +0200

    kie-kogito-serverless-operator-441: Make the SonataFlowBuild smarter to 
manage persistence related extensions/props based on configuration (#457)
    
    * kie-kogito-serverless-operator-441: Make the SonataFlowBuild smarter to 
manage persistence related extensions/props based on configuration
    
    * Tests added
    
    * Apply generate-all
    
    * Test fixes
    
    * Code review suggestions 2
    
    * Tests added 2
    
    * Code review suggestions 3
---
 ...w-operator-controllers-config_v1_configmap.yaml |  12 ++
 config/manager/controllers_cfg.yaml                |  12 ++
 controllers/builder/containerbuilder.go            |  18 +++
 .../builder/kogitoserverlessbuild_manager.go       |  54 ++++++-
 .../builder/kogitoserverlessbuild_manager_test.go  | 178 +++++++++++++++++++++
 controllers/builder/openshiftbuilder.go            |  11 +-
 controllers/builder/openshiftbuilder_test.go       |  10 +-
 controllers/cfg/controllers_cfg.go                 |  38 +++--
 controllers/cfg/controllers_cfg_test.go            |  19 +++
 controllers/cfg/testdata/controllers-cfg-test.yaml |  10 ++
 controllers/platform/services/services.go          |   1 +
 .../profiles/common/object_creators_test.go        |  32 ----
 .../common/persistence/persistence.go}             |  18 ++-
 .../common/persistence/persistence_test.go         |  84 ++++++++++
 .../profiles/common/persistence/postgresql.go      |  38 +++--
 controllers/profiles/common/properties/managed.go  |   7 +
 controllers/profiles/preview/profile_preview.go    |   2 +-
 controllers/profiles/preview/states_preview.go     |  23 ++-
 controllers/profiles/profile.go                    |   3 +
 controllers/profiles/profile_test.go               |  14 ++
 operator.yaml                                      |  12 ++
 controllers/workflows/constants.go => test/cfg.go  |  22 ++-
 test/e2e/workflow_test.go                          |  48 +++++-
 .../by_service/02-sonataflow_platform.yaml         |   4 -
 ... 03-configmap_callbackstatetimeouts-props.yaml} |  29 ++--
 ...=> 04-sonataflow_callbackstatetimeouts.sw.yaml} |   4 -
 .../persistence/by_service/kustomization.yaml      |   3 +-
 .../02-sonataflow_platform.yaml                    |   4 -
 .../03-sonataflow_callbackstatetimeouts.sw.yaml    |   1 +
 .../02-sonataflow_platform.yaml                    |   4 -
 .../03-configmap_callbackstatetimeouts-props.yaml} |  29 ++--
 ...=> 04-sonataflow_callbackstatetimeouts.sw.yaml} |   5 -
 .../kustomization.yaml                             |   3 +-
 .../02-sonataflow_platform.yaml                    |   4 -
 .../02-sonataflow_platform.yaml                    |   4 -
 .../03-sonataflow_callbackstatetimeouts.sw.yaml    |   1 +
 test/yaml.go                                       |   8 +
 workflowproj/operator.go                           |   2 +-
 workflowproj/workflowproj.go                       |  15 +-
 39 files changed, 638 insertions(+), 148 deletions(-)

diff --git 
a/bundle/manifests/sonataflow-operator-controllers-config_v1_configmap.yaml 
b/bundle/manifests/sonataflow-operator-controllers-config_v1_configmap.yaml
index a16e6be8..27e29749 100644
--- a/bundle/manifests/sonataflow-operator-controllers-config_v1_configmap.yaml
+++ b/bundle/manifests/sonataflow-operator-controllers-config_v1_configmap.yaml
@@ -29,6 +29,18 @@ data:
     sonataFlowDevModeImageTag: ""
     # The default name of the builder configMap in the operator's namespace
     builderConfigMapName: "sonataflow-operator-builder-config"
+    # Quarkus extensions required for workflows persistence. These extensions 
are used by the SonataFlow build system,
+    # in cases where the workflow being built has configured postgresql 
persistence.
+    postgreSQLPersistenceExtensions:
+      - groupId: io.quarkus
+        artifactId: quarkus-jdbc-postgresql
+        version: 3.2.10.Final
+      - groupId: io.quarkus
+        artifactId: quarkus-agroal
+        version: 3.2.10.Final
+      - groupId: org.kie
+        artifactId: kie-addons-quarkus-persistence-jdbc
+        version: 999-SNAPSHOT
 kind: ConfigMap
 metadata:
   name: sonataflow-operator-controllers-config
diff --git a/config/manager/controllers_cfg.yaml 
b/config/manager/controllers_cfg.yaml
index 41f2f860..08f2a406 100644
--- a/config/manager/controllers_cfg.yaml
+++ b/config/manager/controllers_cfg.yaml
@@ -26,3 +26,15 @@ sonataFlowBaseBuilderImageTag: ""
 sonataFlowDevModeImageTag: ""
 # The default name of the builder configMap in the operator's namespace
 builderConfigMapName: "sonataflow-operator-builder-config"
+# Quarkus extensions required for workflows persistence. These extensions are 
used by the SonataFlow build system,
+# in cases where the workflow being built has configured postgresql 
persistence.
+postgreSQLPersistenceExtensions:
+  - groupId: io.quarkus
+    artifactId: quarkus-jdbc-postgresql
+    version: 3.2.10.Final
+  - groupId: io.quarkus
+    artifactId: quarkus-agroal
+    version: 3.2.10.Final
+  - groupId: org.kie
+    artifactId: kie-addons-quarkus-persistence-jdbc
+    version: 999-SNAPSHOT
diff --git a/controllers/builder/containerbuilder.go 
b/controllers/builder/containerbuilder.go
index c945f02d..d23c8388 100644
--- a/controllers/builder/containerbuilder.go
+++ b/controllers/builder/containerbuilder.go
@@ -22,6 +22,10 @@ package builder
 import (
        "time"
 
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/workflowproj"
+
+       corev1 "k8s.io/api/core/v1"
+
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/cfg"
        "k8s.io/klog/v2"
 
@@ -52,6 +56,7 @@ type kanikoBuildInput struct {
        task               *api.KanikoTask
        workflowDefinition []byte
        workflow           *operatorapi.SonataFlow
+       workflowProperties []operatorapi.ConfigMapWorkflowResource
        dockerfile         string
        imageTag           string
 }
@@ -139,6 +144,7 @@ func (c *containerBuilderManager) 
scheduleNewKanikoBuildWithContainerFile(build
                task:               task,
                workflowDefinition: workflowDef,
                workflow:           workflow,
+               workflowProperties: buildWorkflowPropertyResources(workflow),
                dockerfile:         
platform.GetCustomizedBuilderDockerfile(c.builderConfigMap.Data[defaultBuilderResourceName],
 *c.platform),
                imageTag:           buildNamespacedImageTag(workflow),
        }
@@ -200,6 +206,11 @@ func newBuild(buildInput kanikoBuildInput, platform 
api.PlatformContainerBuild,
                newBuilder.AddConfigMapResource(res.ConfigMap, res.WorkflowPath)
        }
 
+       //make the workflow properties available to the kaniko build.
+       for _, props := range buildInput.workflowProperties {
+               newBuilder.AddConfigMapResource(props.ConfigMap, 
props.WorkflowPath)
+       }
+
        return newBuilder.Scheduler().
                WithAdditionalArgs(buildInput.task.AdditionalFlags).
                WithResourceRequirements(buildInput.task.Resources).
@@ -213,3 +224,10 @@ func newBuild(buildInput kanikoBuildInput, platform 
api.PlatformContainerBuild,
 func buildNamespacedImageTag(workflow *operatorapi.SonataFlow) string {
        return workflow.Namespace + "/" + 
workflowdef.GetWorkflowAppImageNameTag(workflow)
 }
+
+func buildWorkflowPropertyResources(workflow *operatorapi.SonataFlow) 
[]operatorapi.ConfigMapWorkflowResource {
+       return []operatorapi.ConfigMapWorkflowResource{
+               {ConfigMap: corev1.LocalObjectReference{Name: 
workflowproj.GetWorkflowUserPropertiesConfigMapName(workflow)}, WorkflowPath: 
""},
+               {ConfigMap: corev1.LocalObjectReference{Name: 
workflowproj.GetWorkflowManagedPropertiesConfigMapName(workflow)}, 
WorkflowPath: ""},
+       }
+}
diff --git a/controllers/builder/kogitoserverlessbuild_manager.go 
b/controllers/builder/kogitoserverlessbuild_manager.go
index b6dfa7ba..044710d4 100644
--- a/controllers/builder/kogitoserverlessbuild_manager.go
+++ b/controllers/builder/kogitoserverlessbuild_manager.go
@@ -21,7 +21,12 @@ package builder
 
 import (
        "context"
+       "strings"
 
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/cfg"
+
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/persistence"
+       v1 "k8s.io/api/core/v1"
        "k8s.io/apimachinery/pkg/api/errors"
        "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -31,6 +36,8 @@ import (
        operatorapi 
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
 )
 
+const QuarkusExtensionsBuildArg = "QUARKUS_EXTENSIONS"
+
 var _ SonataFlowBuildManager = &sonataFlowBuildManager{}
 
 type sonataFlowBuildManager struct {
@@ -54,7 +61,11 @@ func (k *sonataFlowBuildManager) GetOrCreateBuild(workflow 
*operatorapi.SonataFl
                        if plat, err = platform.GetActivePlatform(k.ctx, 
k.client, workflow.Namespace); err != nil {
                                return nil, err
                        }
-                       buildInstance.Spec.BuildTemplate = 
plat.Spec.Build.Template
+                       workflowBuildTemplate := 
plat.Spec.Build.Template.DeepCopy()
+                       if persistence.UsesPostgreSQLPersistence(workflow, 
plat) {
+                               addPersistenceExtensions(workflowBuildTemplate)
+                       }
+                       buildInstance.Spec.BuildTemplate = 
*workflowBuildTemplate
                        if err = 
controllerutil.SetControllerReference(workflow, buildInstance, 
k.client.Scheme()); err != nil {
                                return nil, err
                        }
@@ -86,3 +97,44 @@ func NewSonataFlowBuildManager(ctx context.Context, client 
client.Client) Sonata
                ctx:    ctx,
        }
 }
+
+// addPersistenceExtensions Adds the persistence related extensions to the 
current BuildTemplate if none of them is
+// already provided. If any of them is detected, its assumed that users might 
already have provided them in the
+// SonataFlowPlatform, so we just let the provided configuration.
+func addPersistenceExtensions(template *operatorapi.BuildTemplate) {
+       quarkusExtensions := getBuildArg(template.BuildArgs, 
QuarkusExtensionsBuildArg)
+       if quarkusExtensions == nil {
+               template.BuildArgs = append(template.BuildArgs, v1.EnvVar{Name: 
QuarkusExtensionsBuildArg})
+               quarkusExtensions = 
&template.BuildArgs[len(template.BuildArgs)-1]
+       }
+       if !hasAnyExtensionPresent(quarkusExtensions, 
persistence.GetPostgreSQLExtensions()) {
+               for _, extension := range persistence.GetPostgreSQLExtensions() 
{
+                       if len(quarkusExtensions.Value) > 0 {
+                               quarkusExtensions.Value = 
quarkusExtensions.Value + ","
+                       }
+                       quarkusExtensions.Value = quarkusExtensions.Value + 
extension.String()
+               }
+       }
+}
+
+func getBuildArg(buildArgs []v1.EnvVar, name string) *v1.EnvVar {
+       for i := 0; i < len(buildArgs); i++ {
+               if buildArgs[i].Name == name {
+                       return &buildArgs[i]
+               }
+       }
+       return nil
+}
+
+func hasAnyExtensionPresent(buildArg *v1.EnvVar, extensions []cfg.GAV) bool {
+       for _, extension := range extensions {
+               if isExtensionPresent(buildArg, extension) {
+                       return true
+               }
+       }
+       return false
+}
+
+func isExtensionPresent(buildArg *v1.EnvVar, extension cfg.GAV) bool {
+       return strings.Contains(buildArg.Value, extension.GroupAndArtifact())
+}
diff --git a/controllers/builder/kogitoserverlessbuild_manager_test.go 
b/controllers/builder/kogitoserverlessbuild_manager_test.go
new file mode 100644
index 00000000..ac865e63
--- /dev/null
+++ b/controllers/builder/kogitoserverlessbuild_manager_test.go
@@ -0,0 +1,178 @@
+// Copyright 2024 Apache Software Foundation (ASF)
+//
+// 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 builder
+
+import (
+       "testing"
+
+       operatorapi 
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/cfg"
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/persistence"
+       "github.com/apache/incubator-kie-kogito-serverless-operator/test"
+       "github.com/stretchr/testify/assert"
+       v1 "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func TestSonataFlowBuildManager_GetOrCreateBuildWithWorkflowPersistence(t 
*testing.T) {
+       // Current platform with no persistence
+       currentPlatform := operatorapi.SonataFlowPlatform{
+               ObjectMeta: metav1.ObjectMeta{Name: "current-platform"},
+               Spec:       operatorapi.SonataFlowPlatformSpec{},
+               Status:     operatorapi.SonataFlowPlatformStatus{},
+       }
+       // Persistence is configured in the workflow
+       workflow := operatorapi.SonataFlow{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name: "my-workflow",
+               },
+               Spec: operatorapi.SonataFlowSpec{
+                       Persistence: &operatorapi.PersistenceOptionsSpec{
+                               PostgreSQL: 
&operatorapi.PersistencePostgreSQL{},
+                       },
+               },
+               Status: operatorapi.SonataFlowStatus{},
+       }
+       testGetOrCreateBuildWithPersistence(t, &currentPlatform, &workflow)
+}
+
+func TestSonataFlowBuildManager_GetOrCreateBuildWithPlatformPersistence(t 
*testing.T) {
+       // Persistence is configured in the platform
+       currentPlatform := operatorapi.SonataFlowPlatform{
+               ObjectMeta: metav1.ObjectMeta{Name: "current-platform"},
+               Spec: operatorapi.SonataFlowPlatformSpec{
+                       Persistence: 
&operatorapi.PlatformPersistenceOptionsSpec{
+                               PostgreSQL: 
&operatorapi.PlatformPersistencePostgreSQL{},
+                       },
+               },
+               Status: operatorapi.SonataFlowPlatformStatus{},
+       }
+       // Workflow with no persistence
+       workflow := operatorapi.SonataFlow{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name: "my-workflow",
+               },
+               Status: operatorapi.SonataFlowStatus{},
+       }
+       testGetOrCreateBuildWithPersistence(t, &currentPlatform, &workflow)
+}
+
+func TestSonataFlowBuildManager_GetOrCreateBuildWithNoPersistence(t 
*testing.T) {
+       // Platform has no persistence
+       currentPlatform := operatorapi.SonataFlowPlatform{
+               ObjectMeta: metav1.ObjectMeta{Name: "current-platform"},
+               Spec:       operatorapi.SonataFlowPlatformSpec{},
+               Status:     operatorapi.SonataFlowPlatformStatus{},
+       }
+       // Workflow has no persistence
+       workflow := operatorapi.SonataFlow{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name: "my-workflow",
+               },
+               Status: operatorapi.SonataFlowStatus{},
+       }
+       buildManager := prepareGetOrCreateBuildTest(t, &currentPlatform)
+       build, _ := buildManager.GetOrCreateBuild(&workflow)
+       assert.Equal(t, 0, len(build.Spec.BuildArgs))
+       test.RestoreControllersConfig(t)
+}
+
+func testGetOrCreateBuildWithPersistence(t *testing.T, currentPlatform 
*operatorapi.SonataFlowPlatform, workflow *operatorapi.SonataFlow) {
+       buildManager := prepareGetOrCreateBuildTest(t, currentPlatform)
+       build, _ := buildManager.GetOrCreateBuild(workflow)
+       assert.NotNil(t, build)
+       assert.Equal(t, 1, len(build.Spec.BuildArgs))
+       assertContainsPersistence(t, build.Spec.BuildArgs, 0)
+       test.RestoreControllersConfig(t)
+}
+
+func prepareGetOrCreateBuildTest(t *testing.T, currentPlatform 
*operatorapi.SonataFlowPlatform) sonataFlowBuildManager {
+       initializeControllersConfig(t)
+       platforms := operatorapi.NewSonataFlowPlatformList()
+       platforms.Items = []operatorapi.SonataFlowPlatform{*currentPlatform}
+       cli := 
test.NewSonataFlowClientBuilder().WithRuntimeObjects(&platforms).Build()
+       buildManager := sonataFlowBuildManager{
+               client: cli,
+       }
+       return buildManager
+}
+
+func Test_addPersistenceExtensionsWithEmptyArgs(t *testing.T) {
+       initializeControllersConfig(t)
+       buildTemplate := &operatorapi.BuildTemplate{}
+       addPersistenceExtensions(buildTemplate)
+       assert.Equal(t, 1, len(buildTemplate.BuildArgs))
+       assertContainsPersistence(t, buildTemplate.BuildArgs, 0)
+       test.RestoreControllersConfig(t)
+}
+
+func Test_addPersistenceExtensionsWithNoQuarkusExtensionsArg(t *testing.T) {
+       initializeControllersConfig(t)
+       buildTemplate := &operatorapi.BuildTemplate{
+               BuildArgs: []v1.EnvVar{
+                       {Name: "VAR1"},
+               },
+       }
+       addPersistenceExtensions(buildTemplate)
+       assert.Equal(t, 2, len(buildTemplate.BuildArgs))
+       assertContainsPersistence(t, buildTemplate.BuildArgs, 1)
+       test.RestoreControllersConfig(t)
+}
+
+func 
Test_addPersistenceExtensionsWithQuarkusExtensionsArgAndNoPersistenceExtensions(t
 *testing.T) {
+       initializeControllersConfig(t)
+       buildTemplate := &operatorapi.BuildTemplate{
+               BuildArgs: []v1.EnvVar{
+                       {Name: "VAR1"},
+                       {Name: "QUARKUS_EXTENSIONS", Value: 
"org.acme:org.acme.library:1.0.0"},
+               },
+       }
+       addPersistenceExtensions(buildTemplate)
+       assert.Equal(t, 2, len(buildTemplate.BuildArgs))
+       assertContainsPersistence(t, buildTemplate.BuildArgs, 1)
+       test.RestoreControllersConfig(t)
+}
+
+func 
Test_addPersistenceExtensionsWithQuarkusExtensionsArgAndPersistenceExtensions(t 
*testing.T) {
+       initializeControllersConfig(t)
+       buildTemplate := &operatorapi.BuildTemplate{
+               BuildArgs: []v1.EnvVar{
+                       {Name: "VAR1", Value: "VALUE1"},
+                       {Name: "QUARKUS_EXTENSIONS", Value: 
"org.acme:org.acme.library:1.0.0,io.quarkus:quarkus-jdbc-postgresql:8.8.0.Final"},
+               },
+       }
+       addPersistenceExtensions(buildTemplate)
+       assert.Equal(t, 2, len(buildTemplate.BuildArgs))
+       assert.Equal(t, v1.EnvVar{Name: "VAR1", Value: "VALUE1"}, 
buildTemplate.BuildArgs[0])
+       assert.Equal(t, v1.EnvVar{Name: "QUARKUS_EXTENSIONS", Value: 
"org.acme:org.acme.library:1.0.0,io.quarkus:quarkus-jdbc-postgresql:8.8.0.Final"},
 buildTemplate.BuildArgs[1])
+       test.RestoreControllersConfig(t)
+}
+
+func initializeControllersConfig(t *testing.T) {
+       // emulate the controllers config initialization
+       cfg, err := 
cfg.InitializeControllersCfgAt("../cfg/testdata/controllers-cfg-test.yaml")
+       assert.NoError(t, err)
+       assert.NotNil(t, cfg)
+       assert.Equal(t, 3, len(cfg.PostgreSQLPersistenceExtensions))
+}
+
+func assertContainsPersistence(t *testing.T, buildArgs []v1.EnvVar, position 
int) {
+       assert.GreaterOrEqual(t, len(buildArgs), position)
+       envVar := buildArgs[position]
+       assert.Equal(t, QuarkusExtensionsBuildArg, envVar.Name)
+       for _, extension := range persistence.GetPostgreSQLExtensions() {
+               assert.Contains(t, envVar.Value, extension.String())
+       }
+}
diff --git a/controllers/builder/openshiftbuilder.go 
b/controllers/builder/openshiftbuilder.go
index bb84b2c5..09ab8f98 100644
--- a/controllers/builder/openshiftbuilder.go
+++ b/controllers/builder/openshiftbuilder.go
@@ -186,9 +186,6 @@ func (o *openshiftBuilderManager) 
newDefaultBuildConfig(build *operatorapi.Sonat
 }
 
 func (o *openshiftBuilderManager) addExternalResources(config 
*buildv1.BuildConfig, workflow *operatorapi.SonataFlow) error {
-       if len(workflow.Spec.Resources.ConfigMaps) == 0 {
-               return nil
-       }
        var configMapSources []buildv1.ConfigMapBuildSource
        for _, workflowRes := range workflow.Spec.Resources.ConfigMaps {
                configMapSources = append(configMapSources, 
buildv1.ConfigMapBuildSource{
@@ -196,6 +193,14 @@ func (o *openshiftBuilderManager) 
addExternalResources(config *buildv1.BuildConf
                        DestinationDir: workflowRes.WorkflowPath,
                })
        }
+       //make the workflow properties available to the OpenShift build config.
+       configMapSources = append(configMapSources, 
buildv1.ConfigMapBuildSource{
+               ConfigMap:      corev1.LocalObjectReference{Name: 
workflowproj.GetWorkflowUserPropertiesConfigMapName(workflow)},
+               DestinationDir: ""})
+       configMapSources = append(configMapSources, 
buildv1.ConfigMapBuildSource{
+               ConfigMap:      corev1.LocalObjectReference{Name: 
workflowproj.GetWorkflowManagedPropertiesConfigMapName(workflow)},
+               DestinationDir: ""})
+
        config.Spec.Source.ConfigMaps = configMapSources
        return nil
 }
diff --git a/controllers/builder/openshiftbuilder_test.go 
b/controllers/builder/openshiftbuilder_test.go
index ea8c8b74..48b6ef3e 100644
--- a/controllers/builder/openshiftbuilder_test.go
+++ b/controllers/builder/openshiftbuilder_test.go
@@ -103,7 +103,7 @@ func Test_openshiftbuilder_externalCMs(t *testing.T) {
                },
        }
        workflow.Spec.Resources.ConfigMaps = 
append(workflow.Spec.Resources.ConfigMaps,
-               operatorapi.ConfigMapWorkflowResource{ConfigMap: 
v1.LocalObjectReference{Name: externalCm.Name}})
+               operatorapi.ConfigMapWorkflowResource{ConfigMap: 
v1.LocalObjectReference{Name: externalCm.Name}, WorkflowPath: "specs"})
 
        namespacedName := types.NamespacedName{Namespace: workflow.Namespace, 
Name: workflow.Name}
        client := 
test.NewKogitoClientBuilderWithOpenShift().WithRuntimeObjects(workflow, 
platform, config, externalCm).Build()
@@ -129,7 +129,13 @@ func Test_openshiftbuilder_externalCMs(t *testing.T) {
        bc := &buildv1.BuildConfig{}
        assert.NoError(t, client.Get(context.TODO(), namespacedName, bc))
 
-       assert.Len(t, bc.Spec.Source.ConfigMaps, 1)
+       assert.Len(t, bc.Spec.Source.ConfigMaps, 3)
+       assert.Equal(t, "myopenapis", 
bc.Spec.Source.ConfigMaps[0].ConfigMap.Name)
+       assert.Equal(t, "specs", bc.Spec.Source.ConfigMaps[0].DestinationDir)
+       assert.Equal(t, "greeting-props", 
bc.Spec.Source.ConfigMaps[1].ConfigMap.Name)
+       assert.Equal(t, "", bc.Spec.Source.ConfigMaps[1].DestinationDir)
+       assert.Equal(t, "greeting-managed-props", 
bc.Spec.Source.ConfigMaps[2].ConfigMap.Name)
+       assert.Equal(t, "", bc.Spec.Source.ConfigMaps[2].DestinationDir)
 }
 
 func Test_openshiftbuilder_forcePull(t *testing.T) {
diff --git a/controllers/cfg/controllers_cfg.go 
b/controllers/cfg/controllers_cfg.go
index 4f299092..965737e4 100644
--- a/controllers/cfg/controllers_cfg.go
+++ b/controllers/cfg/controllers_cfg.go
@@ -18,6 +18,7 @@ package cfg
 
 import (
        "bytes"
+       "fmt"
        "os"
 
        "github.com/apache/incubator-kie-kogito-serverless-operator/log"
@@ -40,18 +41,33 @@ var defaultControllersCfg = &ControllersCfg{
        BuilderConfigMapName:          "sonataflow-operator-builder-config",
 }
 
+type GAV struct {
+       GroupId    string `yaml:"groupId,omitempty"`
+       ArtifactId string `yaml:"artifactId,omitempty"`
+       Version    string `yaml:"version,omitempty"`
+}
+
+func (g *GAV) GroupAndArtifact() string {
+       return fmt.Sprintf("%s:%s", g.GroupId, g.ArtifactId)
+}
+
+func (g *GAV) String() string {
+       return fmt.Sprintf("%s:%s:%s", g.GroupId, g.ArtifactId, g.Version)
+}
+
 type ControllersCfg struct {
-       DefaultPvcKanikoSize          string 
`yaml:"defaultPvcKanikoSize,omitempty"`
-       HealthFailureThresholdDevMode int32  
`yaml:"healthFailureThresholdDevMode,omitempty"`
-       KanikoDefaultWarmerImageTag   string 
`yaml:"kanikoDefaultWarmerImageTag,omitempty"`
-       KanikoExecutorImageTag        string 
`yaml:"kanikoExecutorImageTag,omitempty"`
-       JobsServicePostgreSQLImageTag string 
`yaml:"jobsServicePostgreSQLImageTag,omitempty"`
-       JobsServiceEphemeralImageTag  string 
`yaml:"jobsServiceEphemeralImageTag,omitempty"`
-       DataIndexPostgreSQLImageTag   string 
`yaml:"dataIndexPostgreSQLImageTag,omitempty"`
-       DataIndexEphemeralImageTag    string 
`yaml:"dataIndexEphemeralImageTag,omitempty"`
-       SonataFlowBaseBuilderImageTag string 
`yaml:"sonataFlowBaseBuilderImageTag,omitempty"`
-       SonataFlowDevModeImageTag     string 
`yaml:"sonataFlowDevModeImageTag,omitempty"`
-       BuilderConfigMapName          string 
`yaml:"builderConfigMapName,omitempty"`
+       DefaultPvcKanikoSize            string 
`yaml:"defaultPvcKanikoSize,omitempty"`
+       HealthFailureThresholdDevMode   int32  
`yaml:"healthFailureThresholdDevMode,omitempty"`
+       KanikoDefaultWarmerImageTag     string 
`yaml:"kanikoDefaultWarmerImageTag,omitempty"`
+       KanikoExecutorImageTag          string 
`yaml:"kanikoExecutorImageTag,omitempty"`
+       JobsServicePostgreSQLImageTag   string 
`yaml:"jobsServicePostgreSQLImageTag,omitempty"`
+       JobsServiceEphemeralImageTag    string 
`yaml:"jobsServiceEphemeralImageTag,omitempty"`
+       DataIndexPostgreSQLImageTag     string 
`yaml:"dataIndexPostgreSQLImageTag,omitempty"`
+       DataIndexEphemeralImageTag      string 
`yaml:"dataIndexEphemeralImageTag,omitempty"`
+       SonataFlowBaseBuilderImageTag   string 
`yaml:"sonataFlowBaseBuilderImageTag,omitempty"`
+       SonataFlowDevModeImageTag       string 
`yaml:"sonataFlowDevModeImageTag,omitempty"`
+       BuilderConfigMapName            string 
`yaml:"builderConfigMapName,omitempty"`
+       PostgreSQLPersistenceExtensions []GAV  
`yaml:"postgreSQLPersistenceExtensions,omitempty"`
 }
 
 // InitializeControllersCfg initializes the platform configuration for this 
instance.
diff --git a/controllers/cfg/controllers_cfg_test.go 
b/controllers/cfg/controllers_cfg_test.go
index d2d092dc..51c25ae4 100644
--- a/controllers/cfg/controllers_cfg_test.go
+++ b/controllers/cfg/controllers_cfg_test.go
@@ -32,6 +32,25 @@ func TestInitializeControllersCfgAt_ValidFile(t *testing.T) {
        assert.Equal(t, "local/data-index:1.0.0", 
cfg.DataIndexPostgreSQLImageTag)
        assert.Equal(t, "local/sonataflow-builder:1.0.0", 
cfg.SonataFlowBaseBuilderImageTag)
        assert.Equal(t, "local/sonataflow-devmode:1.0.0", 
cfg.SonataFlowDevModeImageTag)
+       assert.Equal(t, 3, len(cfg.PostgreSQLPersistenceExtensions))
+       postgresExtensions := cfg.PostgreSQLPersistenceExtensions
+       assert.Equal(t, GAV{
+               GroupId:    "io.quarkus",
+               ArtifactId: "quarkus-jdbc-postgresql",
+               Version:    "3.2.10.Final",
+       }, postgresExtensions[0])
+
+       assert.Equal(t, GAV{
+               GroupId:    "io.quarkus",
+               ArtifactId: "quarkus-agroal",
+               Version:    "3.2.10.Final",
+       }, postgresExtensions[1])
+
+       assert.Equal(t, GAV{
+               GroupId:    "org.kie",
+               ArtifactId: "kie-addons-quarkus-persistence-jdbc",
+               Version:    "999-SNAPSHOT",
+       }, postgresExtensions[2])
 }
 
 func TestInitializeControllersCfgAt_FileNotFound(t *testing.T) {
diff --git a/controllers/cfg/testdata/controllers-cfg-test.yaml 
b/controllers/cfg/testdata/controllers-cfg-test.yaml
index 66ec30d8..0903f51a 100644
--- a/controllers/cfg/testdata/controllers-cfg-test.yaml
+++ b/controllers/cfg/testdata/controllers-cfg-test.yaml
@@ -21,3 +21,13 @@ jobsServicePostgreSQLImageTag: "local/jobs-service:1.0.0"
 dataIndexPostgreSQLImageTag: "local/data-index:1.0.0"
 sonataFlowBaseBuilderImageTag: "local/sonataflow-builder:1.0.0"
 sonataFlowDevModeImageTag: "local/sonataflow-devmode:1.0.0"
+postgreSQLPersistenceExtensions:
+  - groupId: io.quarkus
+    artifactId: quarkus-jdbc-postgresql
+    version: 3.2.10.Final
+  - groupId: io.quarkus
+    artifactId: quarkus-agroal
+    version: 3.2.10.Final
+  - groupId: org.kie
+    artifactId: kie-addons-quarkus-persistence-jdbc
+    version: 999-SNAPSHOT
\ No newline at end of file
diff --git a/controllers/platform/services/services.go 
b/controllers/platform/services/services.go
index 856ad90a..4cd9c02b 100644
--- a/controllers/platform/services/services.go
+++ b/controllers/platform/services/services.go
@@ -405,6 +405,7 @@ func (j JobServiceHandler) 
ConfigurePersistence(containerSpec *corev1.Container)
                c.Env = append(c.Env, 
persistence.ConfigurePostgreSQLEnv(p.PostgreSQL, j.GetServiceName(), 
j.platform.Namespace)...)
                // Specific to Job Service
                c.Env = append(c.Env, corev1.EnvVar{Name: 
"QUARKUS_FLYWAY_MIGRATE_AT_START", Value: "true"})
+               c.Env = append(c.Env, corev1.EnvVar{Name: 
"KOGITO_JOBS_SERVICE_LOADJOBERRORSTRATEGY", Value: "FAIL_SERVICE"})
                return c
        }
        return containerSpec
diff --git a/controllers/profiles/common/object_creators_test.go 
b/controllers/profiles/common/object_creators_test.go
index 8b42e5fc..5057b218 100644
--- a/controllers/profiles/common/object_creators_test.go
+++ b/controllers/profiles/common/object_creators_test.go
@@ -295,14 +295,6 @@ func TestMergePodSpec_WithPostgreSQL_and_JDBC_URL_field(t 
*testing.T) {
                        Name:  "KOGITO_PERSISTENCE_TYPE",
                        Value: "jdbc",
                },
-               {
-                       Name:  "KOGITO_PERSISTENCE_PROTO_MARSHALLER",
-                       Value: "false",
-               },
-               {
-                       Name:  "KOGITO_PERSISTENCE_QUERY_TIMEOUT_MILLIS",
-                       Value: "10000",
-               },
        }
        assert.Len(t, deployment.Spec.Template.Spec.Containers, 2)
        assert.Equal(t, "superuser", 
deployment.Spec.Template.Spec.ServiceAccountName)
@@ -387,14 +379,6 @@ func 
TestMergePodSpec_OverrideContainers_WithPostgreSQL_In_Workflow_CR(t *testin
                        Name:  "KOGITO_PERSISTENCE_TYPE",
                        Value: "jdbc",
                },
-               {
-                       Name:  "KOGITO_PERSISTENCE_PROTO_MARSHALLER",
-                       Value: "false",
-               },
-               {
-                       Name:  "KOGITO_PERSISTENCE_QUERY_TIMEOUT_MILLIS",
-                       Value: "10000",
-               },
        }
        assert.Len(t, deployment.Spec.Template.Spec.Containers, 1)
        flowContainer, _ := 
kubeutil.GetContainerByName(v1alpha08.DefaultContainerName, 
&deployment.Spec.Template.Spec)
@@ -467,14 +451,6 @@ func 
TestMergePodSpec_WithServicedPostgreSQL_In_Platform_CR_And_Worflow_Requesti
                        Name:  "KOGITO_PERSISTENCE_TYPE",
                        Value: "jdbc",
                },
-               {
-                       Name:  "KOGITO_PERSISTENCE_PROTO_MARSHALLER",
-                       Value: "false",
-               },
-               {
-                       Name:  "KOGITO_PERSISTENCE_QUERY_TIMEOUT_MILLIS",
-                       Value: "10000",
-               },
        }
        assert.Len(t, deployment.Spec.Template.Spec.Containers, 1)
        flowContainer, _ := 
kubeutil.GetContainerByName(v1alpha08.DefaultContainerName, 
&deployment.Spec.Template.Spec)
@@ -575,14 +551,6 @@ func 
TestMergePodSpec_WithServicedPostgreSQL_In_Platform_And_In_Workflow_CR(t *t
                        Name:  "KOGITO_PERSISTENCE_TYPE",
                        Value: "jdbc",
                },
-               {
-                       Name:  "KOGITO_PERSISTENCE_PROTO_MARSHALLER",
-                       Value: "false",
-               },
-               {
-                       Name:  "KOGITO_PERSISTENCE_QUERY_TIMEOUT_MILLIS",
-                       Value: "10000",
-               },
        }
        assert.Len(t, deployment.Spec.Template.Spec.Containers, 1)
        flowContainer, _ := 
kubeutil.GetContainerByName(v1alpha08.DefaultContainerName, 
&deployment.Spec.Template.Spec)
diff --git a/controllers/workflows/constants.go 
b/controllers/profiles/common/persistence/persistence.go
similarity index 59%
copy from controllers/workflows/constants.go
copy to controllers/profiles/common/persistence/persistence.go
index afcf157a..22671405 100644
--- a/controllers/workflows/constants.go
+++ b/controllers/profiles/common/persistence/persistence.go
@@ -12,13 +12,29 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package workflows
+package persistence
+
+import (
+       operatorapi 
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
+       "github.com/magiconair/properties"
+)
 
 const (
        QuarkusFlywayMigrateAtStart         string = 
"quarkus.flyway.migrate-at-start"
+       QuarkusDatasourceDBKind             string = 
"quarkus.datasource.db-kind"
        QuarkusDatasourceJDBCURL            string = 
"quarkus.datasource.jdbc.url"
        KogitoPersistenceType               string = "kogito.persistence.type"
        JDBCPersistenceType                 string = "jdbc"
        KogitoPersistenceQueryTimeoutMillis string = 
"kogito.persistence.query.timeout.millis"
        KogitoPersistenceProtoMarshaller    string = 
"kogito.persistence.proto.marshaller"
+       PostgreSQLDBKind                    string = "postgresql"
 )
+
+// ResolveWorkflowPersistenceProperties returns the set of application 
properties required for the workflow persistence.
+// Never nil.
+func ResolveWorkflowPersistenceProperties(workflow *operatorapi.SonataFlow, 
platform *operatorapi.SonataFlowPlatform) (*properties.Properties, error) {
+       if UsesPostgreSQLPersistence(workflow, platform) {
+               return GetPostgreSQLWorkflowProperties(workflow), nil
+       }
+       return properties.NewProperties(), nil
+}
diff --git a/controllers/profiles/common/persistence/persistence_test.go 
b/controllers/profiles/common/persistence/persistence_test.go
new file mode 100644
index 00000000..6af8bb13
--- /dev/null
+++ b/controllers/profiles/common/persistence/persistence_test.go
@@ -0,0 +1,84 @@
+// Copyright 2024 Apache Software Foundation (ASF)
+//
+// 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 persistence
+
+import (
+       "testing"
+
+       operatorapi 
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestResolveWorkflowPersistenceProperties_WithWorkflowPersistence(t 
*testing.T) {
+       workflow := operatorapi.SonataFlow{
+               Spec: operatorapi.SonataFlowSpec{
+                       Persistence: &operatorapi.PersistenceOptionsSpec{
+                               PostgreSQL: 
&operatorapi.PersistencePostgreSQL{},
+                       },
+               },
+       }
+       platform := operatorapi.SonataFlowPlatform{}
+       testResolveWorkflowPersistencePropertiesWithPersistence(t, &workflow, 
&platform)
+}
+
+func TestResolveWorkflowPersistenceProperties_WithPlatformPersistence(t 
*testing.T) {
+       workflow := operatorapi.SonataFlow{}
+       platform := operatorapi.SonataFlowPlatform{
+               Spec: operatorapi.SonataFlowPlatformSpec{
+                       Persistence: 
&operatorapi.PlatformPersistenceOptionsSpec{
+                               PostgreSQL: 
&operatorapi.PlatformPersistencePostgreSQL{},
+                       },
+               },
+       }
+       testResolveWorkflowPersistencePropertiesWithPersistence(t, &workflow, 
&platform)
+}
+
+func 
TestResolveWorkflowPersistenceProperties_WithPlatformPersistenceButBannedInWorkflow(t
 *testing.T) {
+       workflow := operatorapi.SonataFlow{}
+       workflow.Spec.Persistence = &operatorapi.PersistenceOptionsSpec{}
+       platform := operatorapi.SonataFlowPlatform{
+               Spec: operatorapi.SonataFlowPlatformSpec{
+                       Persistence: 
&operatorapi.PlatformPersistenceOptionsSpec{
+                               PostgreSQL: 
&operatorapi.PlatformPersistencePostgreSQL{},
+                       },
+               },
+       }
+       props, err := ResolveWorkflowPersistenceProperties(&workflow, &platform)
+       assert.NotNil(t, props)
+       assert.Nil(t, err)
+       assert.Equal(t, 0, props.Len())
+}
+
+func TestResolveWorkflowPersistenceProperties_WithNoPersistence(t *testing.T) {
+       workflow := operatorapi.SonataFlow{}
+       platform := operatorapi.SonataFlowPlatform{}
+       props, err := ResolveWorkflowPersistenceProperties(&workflow, &platform)
+       assert.NotNil(t, props)
+       assert.Nil(t, err)
+       assert.Equal(t, 0, props.Len())
+}
+
+func testResolveWorkflowPersistencePropertiesWithPersistence(t *testing.T, 
workflow *operatorapi.SonataFlow, platform *operatorapi.SonataFlowPlatform) {
+       props, err := ResolveWorkflowPersistenceProperties(workflow, platform)
+       assert.Nil(t, err)
+       assert.NotNil(t, props)
+       assert.Equal(t, 3, props.Len())
+       value, _ := props.Get("kogito.persistence.type")
+       assert.Equal(t, "jdbc", value)
+       value, _ = props.Get("quarkus.datasource.db-kind")
+       assert.Equal(t, "postgresql", value)
+       value, _ = props.Get("kogito.persistence.proto.marshaller")
+       assert.Equal(t, "false", value)
+}
diff --git a/controllers/profiles/common/persistence/postgresql.go 
b/controllers/profiles/common/persistence/postgresql.go
index e88a3425..068d85ca 100644
--- a/controllers/profiles/common/persistence/postgresql.go
+++ b/controllers/profiles/common/persistence/postgresql.go
@@ -17,17 +17,21 @@ package persistence
 import (
        "fmt"
 
-       corev1 "k8s.io/api/core/v1"
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/cfg"
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles"
+       "github.com/magiconair/properties"
 
        
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
        operatorapi 
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants"
+       corev1 "k8s.io/api/core/v1"
 )
 
 const (
        defaultDatabaseName = "sonataflow"
 )
 
+// ConfigurePostgreSQLEnv returns the common env variables required for the 
DataIndex or JobsService when postresql persistence is used.
 func ConfigurePostgreSQLEnv(postgresql *operatorapi.PersistencePostgreSQL, 
databaseSchema, databaseNamespace string) []corev1.EnvVar {
        dataSourcePort := constants.DefaultPostgreSQLPort
        databaseName := defaultDatabaseName
@@ -89,14 +93,6 @@ func ConfigurePostgreSQLEnv(postgresql 
*operatorapi.PersistencePostgreSQL, datab
                        Name:  "KOGITO_PERSISTENCE_TYPE",
                        Value: "jdbc",
                },
-               {
-                       Name:  "KOGITO_PERSISTENCE_PROTO_MARSHALLER",
-                       Value: "false",
-               },
-               {
-                       Name:  "KOGITO_PERSISTENCE_QUERY_TIMEOUT_MILLIS",
-                       Value: "10000",
-               },
        }
 }
 
@@ -132,3 +128,27 @@ func RetrieveConfiguration(primary 
*v1alpha08.PersistenceOptionsSpec, platformPe
        }
        return c
 }
+
+func UsesPostgreSQLPersistence(workflow *operatorapi.SonataFlow, platform 
*operatorapi.SonataFlowPlatform) bool {
+       return (workflow.Spec.Persistence != nil && 
workflow.Spec.Persistence.PostgreSQL != nil) ||
+               (workflow.Spec.Persistence == nil && platform.Spec.Persistence 
!= nil && platform.Spec.Persistence.PostgreSQL != nil)
+}
+
+// GetPostgreSQLExtensions returns the Quarkus extensions required for 
postgresql persistence.
+func GetPostgreSQLExtensions() []cfg.GAV {
+       return cfg.GetCfg().PostgreSQLPersistenceExtensions
+}
+
+// GetPostgreSQLWorkflowProperties returns the set of application properties 
required for postgresql persistence.
+// Never nil.
+func GetPostgreSQLWorkflowProperties(workflow *operatorapi.SonataFlow) 
*properties.Properties {
+       props := properties.NewProperties()
+       if !profiles.IsDevProfile(workflow) && 
!profiles.IsGitOpsProfile(workflow) {
+               // build-time property required by kogito-runtimes to feed 
flyway build-time settings and package the necessary .sql files.
+               props.Set(QuarkusDatasourceDBKind, PostgreSQLDBKind)
+               // build-time properties for kogito-runtimes to use jdbc
+               props.Set(KogitoPersistenceType, JDBCPersistenceType)
+               props.Set(KogitoPersistenceProtoMarshaller, "false")
+       }
+       return props
+}
diff --git a/controllers/profiles/common/properties/managed.go 
b/controllers/profiles/common/properties/managed.go
index a9da9edf..98a73ad3 100644
--- a/controllers/profiles/common/properties/managed.go
+++ b/controllers/profiles/common/properties/managed.go
@@ -23,6 +23,8 @@ import (
        "context"
        "fmt"
 
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/persistence"
+
        "github.com/apache/incubator-kie-kogito-serverless-operator/utils"
 
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/discovery"
@@ -153,6 +155,11 @@ func NewManagedPropertyHandler(workflow 
*operatorapi.SonataFlow, platform *opera
                        return nil, err
                }
                props.Merge(p)
+               p, err = 
persistence.ResolveWorkflowPersistenceProperties(workflow, platform)
+               if err != nil {
+                       return nil, err
+               }
+               props.Merge(p)
                p, err = services.GenerateDataIndexWorkflowProperties(workflow, 
platform)
                if err != nil {
                        return nil, err
diff --git a/controllers/profiles/preview/profile_preview.go 
b/controllers/profiles/preview/profile_preview.go
index 1a0dda49..d891da34 100644
--- a/controllers/profiles/preview/profile_preview.go
+++ b/controllers/profiles/preview/profile_preview.go
@@ -102,7 +102,7 @@ func NewProfileReconciler(client client.Client, cfg 
*rest.Config, recorder recor
        }
        // the reconciliation state machine
        stateMachine := common.NewReconciliationStateMachine(
-               &newBuilderState{StateSupport: support},
+               &newBuilderState{StateSupport: support, ensurers: 
NewObjectEnsurers(support)},
                &followBuildStatusState{StateSupport: support},
                &deployWithBuildWorkflowState{StateSupport: support, ensurers: 
NewObjectEnsurers(support)},
        )
diff --git a/controllers/profiles/preview/states_preview.go 
b/controllers/profiles/preview/states_preview.go
index 4612c84d..333c3397 100644
--- a/controllers/profiles/preview/states_preview.go
+++ b/controllers/profiles/preview/states_preview.go
@@ -40,6 +40,7 @@ import (
 
 type newBuilderState struct {
        *common.StateSupport
+       ensurers *ObjectEnsurers
 }
 
 func (h *newBuilderState) CanReconcile(workflow *operatorapi.SonataFlow) bool {
@@ -49,7 +50,7 @@ func (h *newBuilderState) CanReconcile(workflow 
*operatorapi.SonataFlow) bool {
 }
 
 func (h *newBuilderState) Do(ctx context.Context, workflow 
*operatorapi.SonataFlow) (ctrl.Result, []client.Object, error) {
-       _, err := platform.GetActivePlatform(ctx, h.C, workflow.Namespace)
+       pl, err := platform.GetActivePlatform(ctx, h.C, workflow.Namespace)
        if err != nil {
                if errors.IsNotFound(err) {
                        
workflow.Status.Manager().MarkFalse(api.BuiltConditionType, 
api.WaitingForPlatformReason,
@@ -62,6 +63,26 @@ func (h *newBuilderState) Do(ctx context.Context, workflow 
*operatorapi.SonataFl
                klog.V(log.E).ErrorS(err, "Failed to get active platform")
                return ctrl.Result{RequeueAfter: requeueWhileWaitForPlatform}, 
nil, err
        }
+
+       // Perform status updated to ensure workflow.Status.Services references 
are set before properties calculation.
+       _, err = h.PerformStatusUpdate(ctx, workflow)
+       // Ensure the user and managed properties are prepared before starting 
the build process, and thus, we make them
+       // available at build time.
+       userPropsCM, _, err := h.ensurers.userPropsConfigMap.Ensure(ctx, 
workflow)
+       if err != nil {
+               workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.ExternalResourcesNotFoundReason, "Unable to retrieve the user properties 
config map")
+               _, err = h.PerformStatusUpdate(ctx, workflow)
+               return ctrl.Result{}, nil, err
+       }
+
+       _, _, err = h.ensurers.managedPropsConfigMap.Ensure(ctx, workflow, pl,
+               common.ManagedPropertiesMutateVisitor(ctx, 
h.StateSupport.Catalog, workflow, pl, userPropsCM.(*corev1.ConfigMap)))
+       if err != nil {
+               workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.ExternalResourcesNotFoundReason, "Unable to retrieve the managed properties 
config map")
+               _, err = h.PerformStatusUpdate(ctx, workflow)
+               return ctrl.Result{}, nil, err
+       }
+
        // If there is an active platform we have got all the information to 
build but...
        // ...let's check before if we have got already a build!
        buildManager := builder.NewSonataFlowBuildManager(ctx, h.C)
diff --git a/controllers/profiles/profile.go b/controllers/profiles/profile.go
index 794ca7a7..7e05b4f1 100644
--- a/controllers/profiles/profile.go
+++ b/controllers/profiles/profile.go
@@ -76,3 +76,6 @@ type ReconciliationState interface {
 
 // IsDevProfile is an alias for workflowproj.IsDevProfile
 var IsDevProfile = workflowproj.IsDevProfile
+
+// IsGitOpsProfile is an alias for workflowproj.IsGitOpsProfile
+var IsGitOpsProfile = workflowproj.IsGitOpsProfile
diff --git a/controllers/profiles/profile_test.go 
b/controllers/profiles/profile_test.go
index f2bc0139..63a35cf0 100644
--- a/controllers/profiles/profile_test.go
+++ b/controllers/profiles/profile_test.go
@@ -37,3 +37,17 @@ func Test_workflowIsDevProfile(t *testing.T) {
        workflowWithProdProfile := 
test.GetBaseSonataFlowWithProdProfile(t.Name())
        assert.False(t, IsDevProfile(workflowWithProdProfile))
 }
+
+func Test_workflowGitOpsProfile(t *testing.T) {
+       workflowWithDevProfile := test.GetBaseSonataFlowWithDevProfile(t.Name())
+       assert.False(t, IsGitOpsProfile(workflowWithDevProfile))
+
+       workflowWithNoProfile := test.GetBaseSonataFlow(t.Name())
+       assert.False(t, IsGitOpsProfile(workflowWithNoProfile))
+
+       workflowWithProdProfile := 
test.GetBaseSonataFlowWithProdProfile(t.Name())
+       assert.False(t, IsGitOpsProfile(workflowWithProdProfile))
+
+       workflowWithGitopsProfile := 
test.GetBaseSonataFlowWithGitopsProfile(t.Name())
+       assert.True(t, IsGitOpsProfile(workflowWithGitopsProfile))
+}
diff --git a/operator.yaml b/operator.yaml
index f2ef7178..1575b9eb 100644
--- a/operator.yaml
+++ b/operator.yaml
@@ -27025,6 +27025,18 @@ data:
     sonataFlowDevModeImageTag: ""
     # The default name of the builder configMap in the operator's namespace
     builderConfigMapName: "sonataflow-operator-builder-config"
+    # Quarkus extensions required for workflows persistence. These extensions 
are used by the SonataFlow build system,
+    # in cases where the workflow being built has configured postgresql 
persistence.
+    postgreSQLPersistenceExtensions:
+      - groupId: io.quarkus
+        artifactId: quarkus-jdbc-postgresql
+        version: 3.2.10.Final
+      - groupId: io.quarkus
+        artifactId: quarkus-agroal
+        version: 3.2.10.Final
+      - groupId: org.kie
+        artifactId: kie-addons-quarkus-persistence-jdbc
+        version: 999-SNAPSHOT
 kind: ConfigMap
 metadata:
   name: sonataflow-operator-controllers-config
diff --git a/controllers/workflows/constants.go b/test/cfg.go
similarity index 50%
rename from controllers/workflows/constants.go
rename to test/cfg.go
index afcf157a..c581ed8b 100644
--- a/controllers/workflows/constants.go
+++ b/test/cfg.go
@@ -12,13 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package workflows
+package test
 
-const (
-       QuarkusFlywayMigrateAtStart         string = 
"quarkus.flyway.migrate-at-start"
-       QuarkusDatasourceJDBCURL            string = 
"quarkus.datasource.jdbc.url"
-       KogitoPersistenceType               string = "kogito.persistence.type"
-       JDBCPersistenceType                 string = "jdbc"
-       KogitoPersistenceQueryTimeoutMillis string = 
"kogito.persistence.query.timeout.millis"
-       KogitoPersistenceProtoMarshaller    string = 
"kogito.persistence.proto.marshaller"
+import (
+       "testing"
+
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/cfg"
+       "github.com/stretchr/testify/assert"
 )
+
+// RestoreControllersConfig Utility function to restore the controllers global 
configuration in situations where
+// a particular test must populate it with values form a given file. As part 
of the given test finalization we can
+// invoke this function to restore the global configuration.
+func RestoreControllersConfig(t *testing.T) {
+       _, err := cfg.InitializeControllersCfgAt(getProjectDir() + 
"/config/manager/controllers_cfg.yaml")
+       assert.NoError(t, err)
+}
diff --git a/test/e2e/workflow_test.go b/test/e2e/workflow_test.go
index 0750cd99..ed8f95c4 100644
--- a/test/e2e/workflow_test.go
+++ b/test/e2e/workflow_test.go
@@ -201,21 +201,53 @@ var _ = Describe("Validate the persistence ", Ordered, 
func() {
                                        continue
                                }
                                Expect(h.Status).To(Equal(upStatus), "Pod 
health is not UP")
-                               for _, c := range h.Checks {
-                                       if c.Name == dbConnectionName {
-                                               
Expect(c.Status).To(Equal(upStatus), "Pod's database connection is not UP")
-                                               if withPersistence {
+                               if withPersistence {
+                                       connectionCheckFound := false
+                                       for _, c := range h.Checks {
+                                               if c.Name == dbConnectionName {
+                                                       
Expect(c.Status).To(Equal(upStatus), "Pod's database connection is not UP")
                                                        
Expect(c.Data[defaultDataCheck]).To(Equal(upStatus), "Pod's 'default' database 
data is not UP")
-                                                       return true
-                                               } else {
-                                                       
Expect(defaultDataCheck).NotTo(BeElementOf(c.Data), "Pod's 'default' database 
data check exists in health manifest")
-                                                       return true
+                                                       connectionCheckFound = 
true
                                                }
                                        }
+                                       
Expect(connectionCheckFound).To(Equal(true), "Connection health check not 
found, but the wofkflow has persistence")
+                                       return true
+                               } else {
+                                       connectionCheckFound := false
+                                       for _, c := range h.Checks {
+                                               if c.Name == dbConnectionName {
+                                                       connectionCheckFound = 
true
+                                               }
+                                       }
+                                       
Expect(connectionCheckFound).To(Equal(false), "Connection health check was 
found, but the workflow don't have persistence")
+                                       return true
                                }
                        }
                        return false
                }, 1*time.Minute).Should(BeTrue())
+               // Persistence initialization checks
+               cmd = exec.Command("kubectl", "get", "pod", "-l", 
"sonataflow.org/workflow-app", "-n", ns, "-ojsonpath={.items[*].metadata.name}")
+               output, err = utils.Run(cmd)
+               Expect(err).NotTo(HaveOccurred())
+               podName := string(output)
+               cmd = exec.Command("kubectl", "logs", podName, "-n", ns)
+               output, err = utils.Run(cmd)
+               Expect(err).NotTo(HaveOccurred())
+               logs := string(output)
+               if withPersistence {
+                       By("Validate that the workflow persistence was properly 
initialized")
+                       Expect(logs).Should(ContainSubstring("Flyway Community 
Edition"))
+                       Expect(logs).Should(ContainSubstring("Database: 
jdbc:postgresql://postgres.%s:5432", ns))
+                       Expect(logs).Should(ContainSubstring("Creating schema 
\"callbackstatetimeouts\""))
+                       Expect(logs).Should(ContainSubstring("Migrating schema 
\"callbackstatetimeouts\" to version"))
+                       Expect(logs).Should(MatchRegexp("Successfully applied 
\\d migrations to schema \"callbackstatetimeouts\""))
+                       Expect(logs).Should(ContainSubstring("Profile prod 
activated"))
+               } else {
+                       By("Validate that the workflow has no persistence")
+                       Expect(logs).ShouldNot(ContainSubstring("Flyway 
Community Edition"))
+                       Expect(logs).ShouldNot(ContainSubstring("Creating 
schema \"callbackstatetimeouts\""))
+                       Expect(logs).Should(ContainSubstring("Profile prod 
activated"))
+               }
        },
                Entry("defined in the workflow from an existing kubernetes 
service as a reference", 
test.GetSonataFlowE2EWorkflowPersistenceSampleDataDirectory("by_service"), 
true),
                Entry("defined in the workflow and from the sonataflow 
platform", 
test.GetSonataFlowE2EWorkflowPersistenceSampleDataDirectory("from_platform_overwritten_by_service"),
 true),
diff --git 
a/test/testdata/workflow/persistence/by_service/02-sonataflow_platform.yaml 
b/test/testdata/workflow/persistence/by_service/02-sonataflow_platform.yaml
index f61974cb..082b2ef9 100644
--- a/test/testdata/workflow/persistence/by_service/02-sonataflow_platform.yaml
+++ b/test/testdata/workflow/persistence/by_service/02-sonataflow_platform.yaml
@@ -18,10 +18,6 @@ metadata:
   name: sonataflow-platform
 spec:
   build:
-    template:
-      buildArgs:
-      - name: QUARKUS_EXTENSIONS
-        value: 
org.kie:kie-addons-quarkus-persistence-jdbc:999-SNAPSHOT,io.quarkus:quarkus-jdbc-postgresql:3.2.9.Final,io.quarkus:quarkus-agroal:3.2.9.Final
     config:
       strategyOptions:
         KanikoBuildCacheEnabled: "true"
diff --git a/test/testdata/workflow/persistence/by_service/kustomization.yaml 
b/test/testdata/workflow/persistence/by_service/03-configmap_callbackstatetimeouts-props.yaml
similarity index 60%
copy from test/testdata/workflow/persistence/by_service/kustomization.yaml
copy to 
test/testdata/workflow/persistence/by_service/03-configmap_callbackstatetimeouts-props.yaml
index b7f587bc..85d3ac6a 100644
--- a/test/testdata/workflow/persistence/by_service/kustomization.yaml
+++ 
b/test/testdata/workflow/persistence/by_service/03-configmap_callbackstatetimeouts-props.yaml
@@ -12,22 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-resources:
-- 01-postgres.yaml
-- 02-sonataflow_platform.yaml
-- 03-sonataflow_callbackstatetimeouts.sw.yaml
-
-generatorOptions:
-  disableNameSuffixHash: true
-
-secretGenerator:
-  - name: postgres-secrets
-    literals:
-      - POSTGRES_USER=sonataflow
-      - POSTGRES_PASSWORD=sonataflow
-      - POSTGRES_DATABASE=sonataflow
-      - PGDATA=/var/lib/pgsql/data/userdata
-
-sortOptions:
-  order: fifo
-
+apiVersion: v1
+data:
+  application.properties: |
+    # set the flyway initialization in the WF ConfigMap
+    quarkus.flyway.migrate-at-start=true
+kind: ConfigMap
+metadata:
+  labels:
+    app: callbackstatetimeouts
+  name: callbackstatetimeouts-props
diff --git 
a/test/testdata/workflow/persistence/by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
 
b/test/testdata/workflow/persistence/by_service/04-sonataflow_callbackstatetimeouts.sw.yaml
similarity index 97%
rename from 
test/testdata/workflow/persistence/by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
rename to 
test/testdata/workflow/persistence/by_service/04-sonataflow_callbackstatetimeouts.sw.yaml
index bb64d275..ec738e94 100644
--- 
a/test/testdata/workflow/persistence/by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
+++ 
b/test/testdata/workflow/persistence/by_service/04-sonataflow_callbackstatetimeouts.sw.yaml
@@ -32,10 +32,6 @@ spec:
         databaseName: sonataflow
         databaseSchema: callbackstatetimeouts
   podTemplate:
-    container:
-      env:
-      - name: QUARKUS_FLYWAY_MIGRATE_AT_START
-        value: "true"
     initContainers:
       - name: init-postgres
         image: registry.access.redhat.com/ubi9/ubi-micro:latest
diff --git a/test/testdata/workflow/persistence/by_service/kustomization.yaml 
b/test/testdata/workflow/persistence/by_service/kustomization.yaml
index b7f587bc..2aaac5b1 100644
--- a/test/testdata/workflow/persistence/by_service/kustomization.yaml
+++ b/test/testdata/workflow/persistence/by_service/kustomization.yaml
@@ -15,7 +15,8 @@
 resources:
 - 01-postgres.yaml
 - 02-sonataflow_platform.yaml
-- 03-sonataflow_callbackstatetimeouts.sw.yaml
+- 03-configmap_callbackstatetimeouts-props.yaml
+- 04-sonataflow_callbackstatetimeouts.sw.yaml
 
 generatorOptions:
   disableNameSuffixHash: true
diff --git 
a/test/testdata/workflow/persistence/from_platform_overwritten_by_service/02-sonataflow_platform.yaml
 
b/test/testdata/workflow/persistence/from_platform_overwritten_by_service/02-sonataflow_platform.yaml
index ddae61a8..733b0b95 100644
--- 
a/test/testdata/workflow/persistence/from_platform_overwritten_by_service/02-sonataflow_platform.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_overwritten_by_service/02-sonataflow_platform.yaml
@@ -28,10 +28,6 @@ spec:
         port: 3456
         databaseName: db_name
   build:
-    template:
-      buildArgs:
-      - name: QUARKUS_EXTENSIONS
-        value: 
org.kie:kie-addons-quarkus-persistence-jdbc:999-SNAPSHOT,io.quarkus:quarkus-jdbc-postgresql:3.2.9.Final,io.quarkus:quarkus-agroal:3.2.9.Final
     config:
       strategyOptions:
         KanikoBuildCacheEnabled: "true"  
diff --git 
a/test/testdata/workflow/persistence/from_platform_overwritten_by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
 
b/test/testdata/workflow/persistence/from_platform_overwritten_by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
index bb64d275..fb696bff 100644
--- 
a/test/testdata/workflow/persistence/from_platform_overwritten_by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_overwritten_by_service/03-sonataflow_callbackstatetimeouts.sw.yaml
@@ -34,6 +34,7 @@ spec:
   podTemplate:
     container:
       env:
+      # set the flyway initialization in the WF container env
       - name: QUARKUS_FLYWAY_MIGRATE_AT_START
         value: "true"
     initContainers:
diff --git 
a/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/02-sonataflow_platform.yaml
 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/02-sonataflow_platform.yaml
index 0d1088fd..2a7db22a 100644
--- 
a/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/02-sonataflow_platform.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/02-sonataflow_platform.yaml
@@ -28,10 +28,6 @@ spec:
         port: 5432
         databaseName: sonataflow
   build:
-    template:
-      buildArgs:
-      - name: QUARKUS_EXTENSIONS
-        value: 
org.kie:kie-addons-quarkus-persistence-jdbc:999-SNAPSHOT,io.quarkus:quarkus-jdbc-postgresql:3.2.9.Final,io.quarkus:quarkus-agroal:3.2.9.Final
     config:
       strategyOptions:
         KanikoBuildCacheEnabled: "true"
diff --git a/test/testdata/workflow/persistence/by_service/kustomization.yaml 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/03-configmap_callbackstatetimeouts-props.yaml
similarity index 60%
copy from test/testdata/workflow/persistence/by_service/kustomization.yaml
copy to 
test/testdata/workflow/persistence/from_platform_with_di_and_js_services/03-configmap_callbackstatetimeouts-props.yaml
index b7f587bc..d866ff7c 100644
--- a/test/testdata/workflow/persistence/by_service/kustomization.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/03-configmap_callbackstatetimeouts-props.yaml
@@ -12,22 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-resources:
-- 01-postgres.yaml
-- 02-sonataflow_platform.yaml
-- 03-sonataflow_callbackstatetimeouts.sw.yaml
-
-generatorOptions:
-  disableNameSuffixHash: true
-
-secretGenerator:
-  - name: postgres-secrets
-    literals:
-      - POSTGRES_USER=sonataflow
-      - POSTGRES_PASSWORD=sonataflow
-      - POSTGRES_DATABASE=sonataflow
-      - PGDATA=/var/lib/pgsql/data/userdata
-
-sortOptions:
-  order: fifo
-
+apiVersion: v1
+data:
+  application.properties: |
+    # set the flyway initialization in the WF ConfigMap 
+    quarkus.flyway.migrate-at-start=true
+kind: ConfigMap
+metadata:
+  labels:
+    app: callbackstatetimeouts
+  name: callbackstatetimeouts-props
diff --git 
a/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/04-sonataflow_callbackstatetimeouts.sw.yaml
similarity index 96%
rename from 
test/testdata/workflow/persistence/from_platform_with_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
rename to 
test/testdata/workflow/persistence/from_platform_with_di_and_js_services/04-sonataflow_callbackstatetimeouts.sw.yaml
index 1d4bdbb9..b1d3f5ef 100644
--- 
a/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/04-sonataflow_callbackstatetimeouts.sw.yaml
@@ -20,11 +20,6 @@ metadata:
     sonataflow.org/description: Callback State Timeouts Example k8s
     sonataflow.org/version: 0.0.1
 spec:
-  podTemplate:
-    container:
-      env:
-      - name: QUARKUS_FLYWAY_MIGRATE_AT_START
-        value: "true"
   flow:
     start: PrintStartMessage
     events:
diff --git 
a/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/kustomization.yaml
 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/kustomization.yaml
index b7f587bc..2aaac5b1 100644
--- 
a/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/kustomization.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_with_di_and_js_services/kustomization.yaml
@@ -15,7 +15,8 @@
 resources:
 - 01-postgres.yaml
 - 02-sonataflow_platform.yaml
-- 03-sonataflow_callbackstatetimeouts.sw.yaml
+- 03-configmap_callbackstatetimeouts-props.yaml
+- 04-sonataflow_callbackstatetimeouts.sw.yaml
 
 generatorOptions:
   disableNameSuffixHash: true
diff --git 
a/test/testdata/workflow/persistence/from_platform_with_no_persistence_required/02-sonataflow_platform.yaml
 
b/test/testdata/workflow/persistence/from_platform_with_no_persistence_required/02-sonataflow_platform.yaml
index 0b076a86..817ce0c3 100644
--- 
a/test/testdata/workflow/persistence/from_platform_with_no_persistence_required/02-sonataflow_platform.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_with_no_persistence_required/02-sonataflow_platform.yaml
@@ -28,10 +28,6 @@ spec:
         port: 5432
         databaseName: sonataflow
   build:
-    template:
-      buildArgs:
-      - name: QUARKUS_EXTENSIONS
-        value: 
org.kie:kie-addons-quarkus-persistence-jdbc:999-SNAPSHOT,io.quarkus:quarkus-jdbc-postgresql:3.2.9.Final,io.quarkus:quarkus-agroal:3.2.9.Final
     config:
       strategyOptions:
         KanikoBuildCacheEnabled: "true"
diff --git 
a/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/02-sonataflow_platform.yaml
 
b/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/02-sonataflow_platform.yaml
index 3e24fe66..b5ac4e16 100644
--- 
a/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/02-sonataflow_platform.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/02-sonataflow_platform.yaml
@@ -28,10 +28,6 @@ spec:
         port: 5432
         databaseName: sonataflow
   build:
-    template:
-      buildArgs:
-      - name: QUARKUS_EXTENSIONS
-        value: 
org.kie:kie-addons-quarkus-persistence-jdbc:999-SNAPSHOT,io.quarkus:quarkus-jdbc-postgresql:3.2.9.Final,io.quarkus:quarkus-agroal:3.2.9.Final
     config:
       strategyOptions:
         KanikoBuildCacheEnabled: "true"  
diff --git 
a/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
 
b/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
index 1d4bdbb9..307f85b6 100644
--- 
a/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
+++ 
b/test/testdata/workflow/persistence/from_platform_without_di_and_js_services/03-sonataflow_callbackstatetimeouts.sw.yaml
@@ -23,6 +23,7 @@ spec:
   podTemplate:
     container:
       env:
+      # set the flyway initialization in the WF container env
       - name: QUARKUS_FLYWAY_MIGRATE_AT_START
         value: "true"
   flow:
diff --git a/test/yaml.go b/test/yaml.go
index fd96943b..368ac6b7 100644
--- a/test/yaml.go
+++ b/test/yaml.go
@@ -199,6 +199,10 @@ func SetPreviewProfile(workflow *operatorapi.SonataFlow) {
        workflow.Annotations["sonataflow.org/profile"] = "preview"
 }
 
+func SetGitopsProfile(workflow *operatorapi.SonataFlow) {
+       workflow.Annotations["sonataflow.org/profile"] = "gitops"
+}
+
 func GetBaseSonataFlow(namespace string) *operatorapi.SonataFlow {
        return NewSonataFlow(sonataFlowSampleYamlCR, namespace)
 }
@@ -220,6 +224,10 @@ func GetBaseSonataFlowWithPreviewProfile(namespace string) 
*operatorapi.SonataFl
        return NewSonataFlow(SonataFlowSimpleOpsYamlCR, namespace)
 }
 
+func GetBaseSonataFlowWithGitopsProfile(namespace string) 
*operatorapi.SonataFlow {
+       return NewSonataFlow(sonataFlowSampleYamlCR, namespace, 
SetGitopsProfile)
+}
+
 func GetBaseClusterPlatformInReadyPhase(namespace string) 
*operatorapi.SonataFlowClusterPlatform {
        return 
GetSonataFlowClusterPlatformInReadyPhase(sonataFlowClusterPlatformYamlCR, 
namespace)
 }
diff --git a/workflowproj/operator.go b/workflowproj/operator.go
index 2a5c3e3f..2383f34f 100644
--- a/workflowproj/operator.go
+++ b/workflowproj/operator.go
@@ -121,7 +121,7 @@ func CreateNewUserPropsConfigMap(workflow 
*operatorapi.SonataFlow) *corev1.Confi
        }
 }
 
-// CreateNewManagedPropsConfigMap creates a new ConfigMap object to hold the 
managed application properties of the workflos.
+// CreateNewManagedPropsConfigMap creates a new ConfigMap object to hold the 
managed application properties of the workflows.
 func CreateNewManagedPropsConfigMap(workflow *operatorapi.SonataFlow, 
properties string) *corev1.ConfigMap {
        return &corev1.ConfigMap{
                ObjectMeta: metav1.ObjectMeta{
diff --git a/workflowproj/workflowproj.go b/workflowproj/workflowproj.go
index 2bf1deba..3845da81 100644
--- a/workflowproj/workflowproj.go
+++ b/workflowproj/workflowproj.go
@@ -304,5 +304,18 @@ func (w *workflowProjectHandler) 
addResourceConfigMapToProject(cm *corev1.Config
 
 // IsDevProfile detects if the workflow is using the Dev profile or not
 func IsDevProfile(workflow *operatorapi.SonataFlow) bool {
-       return metadata.IsDevProfile(workflow.Annotations)
+       return isProfile(workflow, metadata.DevProfile)
+}
+
+// IsGitOpsProfile detects if the workflow is using the GitOps profile or not
+func IsGitOpsProfile(workflow *operatorapi.SonataFlow) bool {
+       return isProfile(workflow, metadata.GitOpsProfile)
+}
+
+func isProfile(workflow *operatorapi.SonataFlow, profileType 
metadata.ProfileType) bool {
+       profile := workflow.Annotations[metadata.Profile]
+       if len(profile) == 0 {
+               return false
+       }
+       return metadata.ProfileType(profile) == profileType
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to