Repository: devtron-labs/devtron
Pull request #3565 (2023-06-26 11:44:25)

Fix: Exclude/Include feature not available in cloned apps
<!--
Type of change: Title of the PR should clearly mention which type of PR is this, you can select any of the below mentioned types:

- docs - The PR contains Documentation ONLY changes. 
- feat - The PR contains new feature/enhancements.
- fix - The PR contains a bug fix.
- chore - Development changes related to the build system (involving scripts, configurations or tools) and package dependencies.
- test - Development changes related to tests.
- perf - Changes related to performance improvements.

Example Title: 
docs: Webhook CI documentation changes
-->

# Description
<!--
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
-->
Previously whenever we were cloning an app which is containing the exclude/include filter ,the cloned app was not containing the exclude/include filter.

Fixes #

## How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
<!--test-cases
1. After adding the Filter pattern filed to the cloned app request ,I have deployed the code on my cluster and tested it.
2.I have cloned an app from an app which was containing the exclude/include filter, and I was able to find the filter in the cloned app as well.
-->
1. After adding the Filter pattern filed to the cloned app request ,I have deployed the code on my cluster and tested it.
2.I have cloned an app from an app which was containing the exclude/include filter, and I was able to find the filter in the cloned app as well.

## Checklist:

* [x] The title of the PR states what changed and the related issues number (used for the release note).
* [ ] Does this PR requires documentation updates?
* [x] I've updated documentation as required by this PR.
* [x] I have performed a self-review of my own code.
* [x] I have commented my code, particularly in hard-to-understand areas.
* [x] I have tested it for all user roles.
* [x] I have added all the required unit/api test cases.

## Does this PR introduce a user-facing change?
<!--
If NO, leave the release-note block blank.
If YES, a release note is required:
Enter your extended release note in the block below. If the PR requires additional manual action from users switching to the new version, include the string "action-required".

-->
```release-note

```



sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=devtron-labs_devtron&pullRequest=3565)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3565&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3565) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3565&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3565&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
diff --git a/api/cluster/EnvironmentRestHandler.go b/api/cluster/EnvironmentRestHandler.go
index 8458fea9c..b7603b1d5 100644
--- a/api/cluster/EnvironmentRestHandler.go
+++ b/api/cluster/EnvironmentRestHandler.go
@@ -310,7 +310,12 @@ func (impl EnvironmentRestHandlerImpl) GetEnvironmentListForAutocomplete(w http.
 		return
 	}
 	start := time.Now()
-	environments, err := impl.environmentClusterMappingsService.GetEnvironmentListForAutocomplete()
+	showDeploymentOptionsParam := false
+	param := r.URL.Query().Get("showDeploymentOptions")
+	if param != "" {
+		showDeploymentOptionsParam, _ = strconv.ParseBool(param)
+	}
+	environments, err := impl.environmentClusterMappingsService.GetEnvironmentListForAutocomplete(showDeploymentOptionsParam)
 	if err != nil {
 		impl.logger.Errorw("service err, GetEnvironmentListForAutocomplete", "err", err)
 		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
diff --git a/api/restHandler/app/AutoCompleteRestHandler.go b/api/restHandler/app/AutoCompleteRestHandler.go
index 71ae6e4c4..2e6d7c9df 100644
--- a/api/restHandler/app/AutoCompleteRestHandler.go
+++ b/api/restHandler/app/AutoCompleteRestHandler.go
@@ -126,7 +126,12 @@ func (handler PipelineConfigRestHandlerImpl) EnvironmentListAutocomplete(w http.
 		return
 	}
 	//RBAC
-	result, err := handler.envService.GetEnvironmentListForAutocomplete()
+	showDeploymentOptionsParam := false
+	param := r.URL.Query().Get("showDeploymentOptions")
+	if param != "" {
+		showDeploymentOptionsParam, _ = strconv.ParseBool(param)
+	}
+	result, err := handler.envService.GetEnvironmentListForAutocomplete(showDeploymentOptionsParam)
 	if err != nil {
 		handler.Logger.Errorw("service err, EnvironmentListAutocomplete", "err", err, "appId", appId)
 		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
diff --git a/cmd/external-app/wire_gen.go b/cmd/external-app/wire_gen.go
index bf776ef98..e736fa0b5 100644
--- a/cmd/external-app/wire_gen.go
+++ b/cmd/external-app/wire_gen.go
@@ -33,7 +33,7 @@ import (
 	"github.com/devtron-labs/devtron/client/k8s/application"
 	"github.com/devtron-labs/devtron/client/k8s/informer"
 	"github.com/devtron-labs/devtron/client/telemetry"
-	repository4 "github.com/devtron-labs/devtron/internal/sql/repository"
+	repository3 "github.com/devtron-labs/devtron/internal/sql/repository"
 	"github.com/devtron-labs/devtron/internal/sql/repository/app"
 	"github.com/devtron-labs/devtron/internal/sql/repository/appStatus"
 	"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
@@ -43,7 +43,7 @@ import (
 	app2 "github.com/devtron-labs/devtron/pkg/app"
 	"github.com/devtron-labs/devtron/pkg/appStore/bean"
 	"github.com/devtron-labs/devtron/pkg/appStore/deployment/common"
-	repository3 "github.com/devtron-labs/devtron/pkg/appStore/deployment/repository"
+	repository4 "github.com/devtron-labs/devtron/pkg/appStore/deployment/repository"
 	service3 "github.com/devtron-labs/devtron/pkg/appStore/deployment/service"
 	"github.com/devtron-labs/devtron/pkg/appStore/deployment/tool"
 	"github.com/devtron-labs/devtron/pkg/appStore/discover/repository"
@@ -158,7 +158,8 @@ func InitializeApp() (*App, error) {
 	clusterServiceImpl := cluster.NewClusterServiceImpl(clusterRepositoryImpl, sugaredLogger, k8sUtil, k8sInformerFactoryImpl, userAuthRepositoryImpl, userRepositoryImpl, roleGroupRepositoryImpl)
 	appStatusRepositoryImpl := appStatus.NewAppStatusRepositoryImpl(db, sugaredLogger)
 	environmentRepositoryImpl := repository2.NewEnvironmentRepositoryImpl(db, sugaredLogger, appStatusRepositoryImpl)
-	environmentServiceImpl := cluster.NewEnvironmentServiceImpl(environmentRepositoryImpl, clusterServiceImpl, sugaredLogger, k8sUtil, k8sInformerFactoryImpl, userAuthServiceImpl)
+	attributesRepositoryImpl := repository3.NewAttributesRepositoryImpl(db)
+	environmentServiceImpl := cluster.NewEnvironmentServiceImpl(environmentRepositoryImpl, clusterServiceImpl, sugaredLogger, k8sUtil, k8sInformerFactoryImpl, userAuthServiceImpl, attributesRepositoryImpl)
 	chartRepoRepositoryImpl := chartRepoRepository.NewChartRepoRepositoryImpl(db)
 	acdAuthConfig, err := util3.GetACDAuthConfig()
 	if err != nil {
@@ -170,7 +171,7 @@ func InitializeApp() (*App, error) {
 		return nil, err
 	}
 	chartRepositoryServiceImpl := chartRepo.NewChartRepositoryServiceImpl(sugaredLogger, chartRepoRepositoryImpl, k8sUtil, clusterServiceImpl, acdAuthConfig, httpClient, serverEnvConfigServerEnvConfig)
-	installedAppRepositoryImpl := repository3.NewInstalledAppRepositoryImpl(sugaredLogger, db)
+	installedAppRepositoryImpl := repository4.NewInstalledAppRepositoryImpl(sugaredLogger, db)
 	deleteServiceImpl := delete2.NewDeleteServiceImpl(sugaredLogger, teamServiceImpl, clusterServiceImpl, environmentServiceImpl, chartRepositoryServiceImpl, installedAppRepositoryImpl)
 	teamRestHandlerImpl := team2.NewTeamRestHandlerImpl(sugaredLogger, teamServiceImpl, userServiceImpl, enforcerImpl, validate, userAuthServiceImpl, deleteServiceImpl)
 	teamRouterImpl := team2.NewTeamRouterImpl(teamRestHandlerImpl)
@@ -213,7 +214,7 @@ func InitializeApp() (*App, error) {
 	}
 	helmAppServiceImpl := client2.NewHelmAppServiceImpl(sugaredLogger, clusterServiceImpl, helmAppClientImpl, pumpImpl, enforcerUtilHelmImpl, serverDataStoreServerDataStore, serverEnvConfigServerEnvConfig, appStoreApplicationVersionRepositoryImpl, environmentServiceImpl, pipelineRepositoryImpl, installedAppRepositoryImpl, appRepositoryImpl, clusterRepositoryImpl, k8sUtil, helmReleaseConfig)
 	chartWorkingDir := _wireChartWorkingDirValue
-	gitOpsConfigRepositoryImpl := repository4.NewGitOpsConfigRepositoryImpl(sugaredLogger, db)
+	gitOpsConfigRepositoryImpl := repository3.NewGitOpsConfigRepositoryImpl(sugaredLogger, db)
 	gitCliUtil := util.NewGitCliUtil(sugaredLogger)
 	gitFactory, err := util.NewGitFactory(sugaredLogger, gitOpsConfigRepositoryImpl, gitCliUtil)
 	if err != nil {
@@ -227,7 +228,6 @@ func InitializeApp() (*App, error) {
 	chartTemplateServiceImpl := util.NewChartTemplateServiceImpl(sugaredLogger, chartWorkingDir, httpClient, gitFactory, globalEnvVariables, gitOpsConfigRepositoryImpl, userRepositoryImpl, chartRepositoryImpl)
 	refChartProxyDir := _wireRefChartProxyDirValue
 	appStoreDeploymentCommonServiceImpl := appStoreDeploymentCommon.NewAppStoreDeploymentCommonServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, chartTemplateServiceImpl, refChartProxyDir, gitFactory, gitOpsConfigRepositoryImpl)
-	attributesRepositoryImpl := repository4.NewAttributesRepositoryImpl(db)
 	attributesServiceImpl := attributes.NewAttributesServiceImpl(sugaredLogger, attributesRepositoryImpl)
 	helmAppRestHandlerImpl := client2.NewHelmAppRestHandlerImpl(sugaredLogger, helmAppServiceImpl, enforcerImpl, clusterServiceImpl, enforcerUtilHelmImpl, appStoreDeploymentCommonServiceImpl, userServiceImpl, attributesServiceImpl, serverEnvConfigServerEnvConfig)
 	helmAppRouterImpl := client2.NewHelmAppRouterImpl(helmAppRestHandlerImpl)
@@ -253,9 +253,9 @@ func InitializeApp() (*App, error) {
 	appStoreValuesServiceImpl := service2.NewAppStoreValuesServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl, installedAppRepositoryImpl, appStoreVersionValuesRepositoryImpl, userServiceImpl)
 	appStoreValuesRestHandlerImpl := appStoreValues.NewAppStoreValuesRestHandlerImpl(sugaredLogger, userServiceImpl, appStoreValuesServiceImpl)
 	appStoreValuesRouterImpl := appStoreValues.NewAppStoreValuesRouterImpl(appStoreValuesRestHandlerImpl)
-	clusterInstalledAppsRepositoryImpl := repository3.NewClusterInstalledAppsRepositoryImpl(db, sugaredLogger)
+	clusterInstalledAppsRepositoryImpl := repository4.NewClusterInstalledAppsRepositoryImpl(db, sugaredLogger)
 	appStoreDeploymentHelmServiceImpl := appStoreDeploymentTool.NewAppStoreDeploymentHelmServiceImpl(sugaredLogger, helmAppServiceImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, helmAppClientImpl, installedAppRepositoryImpl, appStoreDeploymentCommonServiceImpl)
-	installedAppVersionHistoryRepositoryImpl := repository3.NewInstalledAppVersionHistoryRepositoryImpl(sugaredLogger, db)
+	installedAppVersionHistoryRepositoryImpl := repository4.NewInstalledAppVersionHistoryRepositoryImpl(sugaredLogger, db)
 	deploymentServiceTypeConfig, err := service3.GetDeploymentServiceTypeConfig()
 	if err != nil {
 		return nil, err
@@ -322,13 +322,13 @@ func InitializeApp() (*App, error) {
 	webhookHelmServiceImpl := webhookHelm.NewWebhookHelmServiceImpl(sugaredLogger, helmAppServiceImpl, clusterServiceImpl, chartRepositoryServiceImpl, attributesServiceImpl)
 	webhookHelmRestHandlerImpl := webhookHelm2.NewWebhookHelmRestHandlerImpl(sugaredLogger, webhookHelmServiceImpl, userServiceImpl, enforcerImpl, validate)
 	webhookHelmRouterImpl := webhookHelm2.NewWebhookHelmRouterImpl(webhookHelmRestHandlerImpl)
-	userAttributesRepositoryImpl := repository4.NewUserAttributesRepositoryImpl(db)
+	userAttributesRepositoryImpl := repository3.NewUserAttributesRepositoryImpl(db)
 	userAttributesServiceImpl := attributes.NewUserAttributesServiceImpl(sugaredLogger, userAttributesRepositoryImpl)
 	userAttributesRestHandlerImpl := restHandler.NewUserAttributesRestHandlerImpl(sugaredLogger, enforcerImpl, userServiceImpl, userAttributesServiceImpl)
 	userAttributesRouterImpl := router.NewUserAttributesRouterImpl(userAttributesRestHandlerImpl)
 	telemetryRestHandlerImpl := restHandler.NewTelemetryRestHandlerImpl(sugaredLogger, telemetryEventClientImpl, enforcerImpl, userServiceImpl)
 	telemetryRouterImpl := router.NewTelemetryRouterImpl(sugaredLogger, telemetryRestHandlerImpl)
-	terminalAccessRepositoryImpl := repository4.NewTerminalAccessRepositoryImpl(db, sugaredLogger)
+	terminalAccessRepositoryImpl := repository3.NewTerminalAccessRepositoryImpl(db, sugaredLogger)
 	userTerminalSessionConfig, err := clusterTerminalAccess.GetTerminalAccessConfig()
 	if err != nil {
 		return nil, err
diff --git a/internal/sql/repository/mocks/AttributesRepository.go b/internal/sql/repository/mocks/AttributesRepository.go
new file mode 100644
index 000000000..46d3031a0
--- /dev/null
+++ b/internal/sql/repository/mocks/AttributesRepository.go
@@ -0,0 +1,163 @@
+// Code generated by mockery v2.30.1. DO NOT EDIT.
+
+package mocks
+
+import (
+	pg "github.com/go-pg/pg"
+	mock "github.com/stretchr/testify/mock"
+
+	repository "github.com/devtron-labs/devtron/internal/sql/repository"
+)
+
+// AttributesRepository is an autogenerated mock type for the AttributesRepository type
+type AttributesRepository struct {
+	mock.Mock
+}
+
+// FindActiveList provides a mock function with given fields:
+func (_m *AttributesRepository) FindActiveList() ([]*repository.Attributes, error) {
+	ret := _m.Called()
+
+	var r0 []*repository.Attributes
+	var r1 error
+	if rf, ok := ret.Get(0).(func() ([]*repository.Attributes, error)); ok {
+		return rf()
+	}
+	if rf, ok := ret.Get(0).(func() []*repository.Attributes); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*repository.Attributes)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func() error); ok {
+		r1 = rf()
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// FindById provides a mock function with given fields: id
+func (_m *AttributesRepository) FindById(id int) (*repository.Attributes, error) {
+	ret := _m.Called(id)
+
+	var r0 *repository.Attributes
+	var r1 error
+	if rf, ok := ret.Get(0).(func(int) (*repository.Attributes, error)); ok {
+		return rf(id)
+	}
+	if rf, ok := ret.Get(0).(func(int) *repository.Attributes); ok {
+		r0 = rf(id)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*repository.Attributes)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(int) error); ok {
+		r1 = rf(id)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// FindByKey provides a mock function with given fields: key
+func (_m *AttributesRepository) FindByKey(key string) (*repository.Attributes, error) {
+	ret := _m.Called(key)
+
+	var r0 *repository.Attributes
+	var r1 error
+	if rf, ok := ret.Get(0).(func(string) (*repository.Attributes, error)); ok {
+		return rf(key)
+	}
+	if rf, ok := ret.Get(0).(func(string) *repository.Attributes); ok {
+		r0 = rf(key)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*repository.Attributes)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(string) error); ok {
+		r1 = rf(key)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// GetConnection provides a mock function with given fields:
+func (_m *AttributesRepository) GetConnection() *pg.DB {
+	ret := _m.Called()
+
+	var r0 *pg.DB
+	if rf, ok := ret.Get(0).(func() *pg.DB); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*pg.DB)
+		}
+	}
+
+	return r0
+}
+
+// Save provides a mock function with given fields: model, tx
+func (_m *AttributesRepository) Save(model *repository.Attributes, tx *pg.Tx) (*repository.Attributes, error) {
+	ret := _m.Called(model, tx)
+
+	var r0 *repository.Attributes
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*repository.Attributes, *pg.Tx) (*repository.Attributes, error)); ok {
+		return rf(model, tx)
+	}
+	if rf, ok := ret.Get(0).(func(*repository.Attributes, *pg.Tx) *repository.Attributes); ok {
+		r0 = rf(model, tx)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*repository.Attributes)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*repository.Attributes, *pg.Tx) error); ok {
+		r1 = rf(model, tx)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Update provides a mock function with given fields: model, tx
+func (_m *AttributesRepository) Update(model *repository.Attributes, tx *pg.Tx) error {
+	ret := _m.Called(model, tx)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*repository.Attributes, *pg.Tx) error); ok {
+		r0 = rf(model, tx)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// NewAttributesRepository creates a new instance of AttributesRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewAttributesRepository(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *AttributesRepository {
+	mock := &AttributesRepository{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/appClone/AppCloneService.go b/pkg/appClone/AppCloneService.go
index b98c0c397..2c2bdae75 100644
--- a/pkg/appClone/AppCloneService.go
+++ b/pkg/appClone/AppCloneService.go
@@ -250,6 +250,7 @@ func (impl *AppCloneServiceImpl) CloneGitRepo(oldAppId, newAppId int, userId int
 			Id:            0,
 			GitProviderId: material.GitProviderId,
 			CheckoutPath:  material.CheckoutPath,
+			FilterPattern: material.FilterPattern,
 		}
 		createMaterial.Material = []*bean.GitMaterial{gitMaterial} // append(createMaterial.Material, gitMaterial)
 		createMaterialres, err := impl.pipelineBuilder.CreateMaterialsForApp(createMaterial)
diff --git a/pkg/cluster/EnvironmentService.go b/pkg/cluster/EnvironmentService.go
index e3db5e6ad..40db732bc 100644
--- a/pkg/cluster/EnvironmentService.go
+++ b/pkg/cluster/EnvironmentService.go
@@ -18,7 +18,9 @@
 package cluster
 
 import (
+	"encoding/json"
 	"fmt"
+	repository2 "github.com/devtron-labs/devtron/internal/sql/repository"
 	"github.com/devtron-labs/devtron/pkg/user/bean"
 	"strconv"
 	"strings"
@@ -34,19 +36,20 @@ import (
 )
 
 type EnvironmentBean struct {
-	Id                    int    `json:"id,omitempty" validate:"number"`
-	Environment           string `json:"environment_name,omitempty" validate:"required,max=50"`
-	ClusterId             int    `json:"cluster_id,omitempty" validate:"number,required"`
-	ClusterName           string `json:"cluster_name,omitempty"`
-	Active                bool   `json:"active"`
-	Default               bool   `json:"default"`
-	PrometheusEndpoint    string `json:"prometheus_endpoint,omitempty"`
-	Namespace             string `json:"namespace,omitempty" validate:"name-space-component,max=50"`
-	CdArgoSetup           bool   `json:"isClusterCdActive"`
-	EnvironmentIdentifier string `json:"environmentIdentifier"`
-	Description           string `json:"description" validate:"max=40"`
-	AppCount              int    `json:"appCount"`
-	IsVirtualEnvironment  bool   `json:"isVirtualEnvironment"`
+	Id                     int      `json:"id,omitempty" validate:"number"`
+	Environment            string   `json:"environment_name,omitempty" validate:"required,max=50"`
+	ClusterId              int      `json:"cluster_id,omitempty" validate:"number,required"`
+	ClusterName            string   `json:"cluster_name,omitempty"`
+	Active                 bool     `json:"active"`
+	Default                bool     `json:"default"`
+	PrometheusEndpoint     string   `json:"prometheus_endpoint,omitempty"`
+	Namespace              string   `json:"namespace,omitempty" validate:"name-space-component,max=50"`
+	CdArgoSetup            bool     `json:"isClusterCdActive"`
+	EnvironmentIdentifier  string   `json:"environmentIdentifier"`
+	Description            string   `json:"description" validate:"max=40"`
+	AppCount               int      `json:"appCount"`
+	IsVirtualEnvironment   bool     `json:"isVirtualEnvironment"`
+	AllowedDeploymentTypes []string `json:"allowedDeploymentTypes"`
 }
 
 type EnvDto struct {
@@ -80,7 +83,7 @@ type EnvironmentService interface {
 	FindById(id int) (*EnvironmentBean, error)
 	Update(mappings *EnvironmentBean, userId int32) (*EnvironmentBean, error)
 	FindClusterByEnvId(id int) (*ClusterBean, error)
-	GetEnvironmentListForAutocomplete() ([]EnvironmentBean, error)
+	GetEnvironmentListForAutocomplete(isDeploymentTypeParam bool) ([]EnvironmentBean, error)
 	GetEnvironmentOnlyListForAutocomplete() ([]EnvironmentBean, error)
 	FindByIds(ids []*int) ([]*EnvironmentBean, error)
 	FindByNamespaceAndClusterName(namespaces string, clusterName string) (*repository.Environment, error)
@@ -97,14 +100,15 @@ type EnvironmentServiceImpl struct {
 	K8sUtil               *util.K8sUtil
 	k8sInformerFactory    informer.K8sInformerFactory
 	//propertiesConfigService pipeline.PropertiesConfigService
-	userAuthService user.UserAuthService
+	userAuthService      user.UserAuthService
+	attributesRepository repository2.AttributesRepository
 }
 
 func NewEnvironmentServiceImpl(environmentRepository repository.EnvironmentRepository,
 	clusterService ClusterService, logger *zap.SugaredLogger,
 	K8sUtil *util.K8sUtil, k8sInformerFactory informer.K8sInformerFactory,
 	//  propertiesConfigService pipeline.PropertiesConfigService,
-	userAuthService user.UserAuthService) *EnvironmentServiceImpl {
+	userAuthService user.UserAuthService, attributesRepository repository2.AttributesRepository) *EnvironmentServiceImpl {
 	return &EnvironmentServiceImpl{
 		environmentRepository: environmentRepository,
 		logger:                logger,
@@ -112,7 +116,8 @@ func NewEnvironmentServiceImpl(environmentRepository repository.EnvironmentRepos
 		K8sUtil:               K8sUtil,
 		k8sInformerFactory:    k8sInformerFactory,
 		//propertiesConfigService: propertiesConfigService,
-		userAuthService: userAuthService,
+		userAuthService:      userAuthService,
+		attributesRepository: attributesRepository,
 	}
 }
 
@@ -366,27 +371,90 @@ func (impl EnvironmentServiceImpl) FindClusterByEnvId(id int) (*ClusterBean, err
 	return clusterBean, nil
 }
 
-func (impl EnvironmentServiceImpl) GetEnvironmentListForAutocomplete() ([]EnvironmentBean, error) {
+const (
+	PIPELINE_DEPLOYMENT_TYPE_HELM = "helm"
+	PIPELINE_DEPLOYMENT_TYPE_ACD  = "argo_cd"
+)
+
+var permittedDeploymentConfigString = []string{PIPELINE_DEPLOYMENT_TYPE_HELM, PIPELINE_DEPLOYMENT_TYPE_ACD}
+
+func (impl EnvironmentServiceImpl) GetEnvironmentListForAutocomplete(isDeploymentTypeParam bool) ([]EnvironmentBean, error) {
 	models, err := impl.environmentRepository.FindAllActive()
 	if err != nil {
 		impl.logger.Errorw("error in fetching environment", "err", err)
 	}
 	var beans []EnvironmentBean
-	for _, model := range models {
-		beans = append(beans, EnvironmentBean{
-			Id:                    model.Id,
-			Environment:           model.Name,
-			Namespace:             model.Namespace,
-			CdArgoSetup:           model.Cluster.CdArgoSetup,
-			EnvironmentIdentifier: model.EnvironmentIdentifier,
-			ClusterName:           model.Cluster.ClusterName,
-			Description:           model.Description,
-			IsVirtualEnvironment:  model.IsVirtualEnvironment,
-		})
+	//Fetching deployment app type config values along with autocomplete api while creating CD pipeline
+	if isDeploymentTypeParam {
+		for _, model := range models {
+			var (
+				deploymentConfig              map[string]bool
+				allowedDeploymentConfigString []string
+			)
+			deploymentConfigValues, _ := impl.attributesRepository.FindByKey(fmt.Sprintf("%d", model.Id))
+			if err = json.Unmarshal([]byte(deploymentConfigValues.Value), &deploymentConfig); err != nil {
+				return nil, err
+			}
+
+			// if real config along with absurd values exist in table {"argo_cd": true, "helm": false, "absurd": false}",
+			if ok, filteredDeploymentConfig := impl.IsReceivedDeploymentTypeValid(deploymentConfig); ok {
+				allowedDeploymentConfigString = filteredDeploymentConfig
+			} else {
+				allowedDeploymentConfigString = permittedDeploymentConfigString
+			}
+			beans = append(beans, EnvironmentBean{
+				Id:                     model.Id,
+				Environment:            model.Name,
+				Namespace:              model.Namespace,
+				CdArgoSetup:            model.Cluster.CdArgoSetup,
+				EnvironmentIdentifier:  model.EnvironmentIdentifier,
+				ClusterName:            model.Cluster.ClusterName,
+				Description:            model.Description,
+				IsVirtualEnvironment:   model.IsVirtualEnvironment,
+				AllowedDeploymentTypes: allowedDeploymentConfigString,
+			})
+		}
+	} else {
+		for _, model := range models {
+			beans = append(beans, EnvironmentBean{
+				Id:                    model.Id,
+				Environment:           model.Name,
+				Namespace:             model.Namespace,
+				CdArgoSetup:           model.Cluster.CdArgoSetup,
+				EnvironmentIdentifier: model.EnvironmentIdentifier,
+				ClusterName:           model.Cluster.ClusterName,
+				Description:           model.Description,
+				IsVirtualEnvironment:  model.IsVirtualEnvironment,
+			})
+		}
 	}
 	return beans, nil
 }
 
+func (impl EnvironmentServiceImpl) IsReceivedDeploymentTypeValid(deploymentConfig map[string]bool) (bool, []string) {
+	var (
+		filteredDeploymentConfig []string
+		flag                     bool
+	)
+
+	for key, value := range deploymentConfig {
+		for _, permitted := range permittedDeploymentConfigString {
+			if key == permitted {
+				//filtering only those deployment app types which are in permitted zone and are marked true
+				if value {
+					flag = true
+					filteredDeploymentConfig = append(filteredDeploymentConfig, key)
+				}
+				break
+			}
+		}
+	}
+	if !flag {
+		return false, nil
+	}
+	return true, filteredDeploymentConfig
+}
+
 func (impl EnvironmentServiceImpl) GetEnvironmentOnlyListForAutocomplete() ([]EnvironmentBean, error) {
 	models, err := impl.environmentRepository.FindAllActiveEnvOnlyDetails()
 	if err != nil {
diff --git a/pkg/pipeline/PipelineBuilder.go b/pkg/pipeline/PipelineBuilder.go
index 1eb294f8c..7ee0e7c11 100644
--- a/pkg/pipeline/PipelineBuilder.go
+++ b/pkg/pipeline/PipelineBuilder.go
@@ -223,6 +223,7 @@ type PipelineBuilderImpl struct {
 	appGroupService                                 appGroup2.AppGroupService
 	chartDeploymentService                          util.ChartDeploymentService
 	K8sUtil                                         *util.K8sUtil
+	attributesRepository                            repository.AttributesRepository
 	securityConfig                                  *SecurityConfig
 }
 
@@ -276,8 +277,8 @@ func NewPipelineBuilderImpl(logger *zap.SugaredLogger,
 	ciWorkflowRepository pipelineConfig.CiWorkflowRepository,
 	appGroupService appGroup2.AppGroupService,
 	chartDeploymentService util.ChartDeploymentService,
-	K8sUtil *util.K8sUtil) *PipelineBuilderImpl {
-
+	K8sUtil *util.K8sUtil,
+	attributesRepository repository.AttributesRepository) *PipelineBuilderImpl {
 	securityConfig := &SecurityConfig{}
 	err := env.Parse(securityConfig)
 	if err != nil {
@@ -343,6 +344,7 @@ func NewPipelineBuilderImpl(logger *zap.SugaredLogger,
 		appGroupService:                                 appGroupService,
 		chartDeploymentService:                          chartDeploymentService,
 		K8sUtil:                                         K8sUtil,
+		attributesRepository:                            attributesRepository,
 		securityConfig:                                  securityConfig,
 	}
 }
@@ -1791,6 +1793,18 @@ func (impl PipelineBuilderImpl) SetPipelineDeploymentAppType(pipelineCreateReque
 
 func (impl PipelineBuilderImpl) CreateCdPipelines(pipelineCreateRequest *bean.CdPipelines, ctx context.Context) (*bean.CdPipelines, error) {
 
+	//Validation for checking deployment App type
+	for _, pipeline := range pipelineCreateRequest.Pipelines {
+		// if no deployment app type sent from user then we'll not validate
+		if pipeline.DeploymentAppType != "" {
+			if err := impl.validateDeploymentAppType(pipeline); err != nil {
+				impl.logger.Errorw("validation error in creating pipeline", "name", pipeline.Name, "err", err)
+				return nil, err
+			}
+		}
+		continue
+	}
+
 	isGitOpsConfigured, err := impl.IsGitopsConfigured()
 	impl.SetPipelineDeploymentAppType(pipelineCreateRequest, isGitOpsConfigured)
 	isGitOpsRequiredForCD := impl.IsGitOpsRequiredForCD(pipelineCreateRequest)
@@ -1839,6 +1853,57 @@ func (impl PipelineBuilderImpl) CreateCdPipelines(pipelineCreateRequest *bean.Cd
 	return pipelineCreateRequest, nil
 }
 
+func (impl PipelineBuilderImpl) validateDeploymentAppType(pipeline *bean.CDPipelineConfigObject) error {
+	var deploymentConfig map[string]bool
+	deploymentConfigValues, _ := impl.attributesRepository.FindByKey(fmt.Sprintf("%d", pipeline.EnvironmentId))
+	if err := json.Unmarshal([]byte(deploymentConfigValues.Value), &deploymentConfig); err != nil {
+		rerr := &util.ApiError{
+			HttpStatusCode:  http.StatusInternalServerError,
+			InternalMessage: err.Error(),
+			UserMessage:     "Failed to fetch deployment config values from the attributes table",
+		}
+		return rerr
+	}
+
+	// Config value doesn't exist in attribute table
+	if deploymentConfig == nil {
+		return nil
+	}
+	//Config value found to be true for ArgoCD and Helm both
+	if allDeploymentConfigTrue(deploymentConfig) {
+		return nil
+	}
+	//Case : {ArgoCD : false, Helm: true, HGF : true}
+	if validDeploymentConfigReceived(deploymentConfig, pipeline.DeploymentAppType) {
+		return nil
+	}
+
+	err := &util.ApiError{
+		HttpStatusCode:  http.StatusBadRequest,
+		InternalMessage: "Received deployment app type doesn't match with the allowed deployment app type for this environment.",
+		UserMessage:     "Received deployment app type doesn't match with the allowed deployment app type for this environment.",
+	}
+	return err
+}
+
+func allDeploymentConfigTrue(deploymentConfig map[string]bool) bool {
+	for _, value := range deploymentConfig {
+		if !value {
+			return false
+		}
+	}
+	return true
+}
+
+func validDeploymentConfigReceived(deploymentConfig map[string]bool, deploymentTypeSent string) bool {
+	for key, value := range deploymentConfig {
+		if value && key == deploymentTypeSent {
+			return true
+		}
+	}
+	return false
+}
+
 func (impl PipelineBuilderImpl) PatchCdPipelines(cdPipelines *bean.CDPatchRequest, ctx context.Context) (*bean.CdPipelines, error) {
 	pipelineRequest := &bean.CdPipelines{
 		UserId:    cdPipelines.UserId,
diff --git a/wire_gen.go b/wire_gen.go
index 03617afbb..e2ba75acf 100644
--- a/wire_gen.go
+++ b/wire_gen.go
@@ -244,7 +244,7 @@ func InitializeApp() (*App, error) {
 	userAuditServiceImpl := user.NewUserAuditServiceImpl(sugaredLogger, userAuditRepositoryImpl)
 	userServiceImpl := user.NewUserServiceImpl(userAuthRepositoryImpl, sugaredLogger, userRepositoryImpl, roleGroupRepositoryImpl, sessionManager, userCommonServiceImpl, userAuditServiceImpl)
 	userAuthServiceImpl := user.NewUserAuthServiceImpl(userAuthRepositoryImpl, sessionManager, loginService, sugaredLogger, userRepositoryImpl, roleGroupRepositoryImpl, userServiceImpl)
-	environmentServiceImpl := cluster2.NewEnvironmentServiceImpl(environmentRepositoryImpl, clusterServiceImplExtended, sugaredLogger, k8sUtil, k8sInformerFactoryImpl, userAuthServiceImpl)
+	environmentServiceImpl := cluster2.NewEnvironmentServiceImpl(environmentRepositoryImpl, clusterServiceImplExtended, sugaredLogger, k8sUtil, k8sInformerFactoryImpl, userAuthServiceImpl, attributesRepositoryImpl)
 	helmReleaseConfig, err := client3.GetHelmReleaseConfig()
 	if err != nil {
 		return nil, err
@@ -431,7 +431,7 @@ func InitializeApp() (*App, error) {
 	appGroupMappingRepositoryImpl := appGroup.NewAppGroupMappingRepositoryImpl(db)
 	appGroupServiceImpl := appGroup2.NewAppGroupServiceImpl(sugaredLogger, appGroupRepositoryImpl, appGroupMappingRepositoryImpl, enforcerUtilImpl)
 	chartDeploymentServiceImpl := util.NewChartDeploymentServiceImpl(sugaredLogger, repositoryServiceClientImpl)
-	pipelineBuilderImpl := pipeline.NewPipelineBuilderImpl(sugaredLogger, ciCdPipelineOrchestratorImpl, dockerArtifactStoreRepositoryImpl, materialRepositoryImpl, appRepositoryImpl, pipelineRepositoryImpl, propertiesConfigServiceImpl, ciTemplateRepositoryImpl, ciPipelineRepositoryImpl, applicationServiceClientImpl, chartRepositoryImpl, ciArtifactRepositoryImpl, ecrConfig, envConfigOverrideRepositoryImpl, environmentRepositoryImpl, pipelineConfigRepositoryImpl, utilMergeUtil, appWorkflowRepositoryImpl, ciConfig, cdWorkflowRepositoryImpl, appServiceImpl, imageScanResultRepositoryImpl, argoK8sClientImpl, gitFactory, attributesServiceImpl, acdAuthConfig, gitOpsConfigRepositoryImpl, pipelineStrategyHistoryServiceImpl, prePostCiScriptHistoryServiceImpl, prePostCdScriptHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, appLevelMetricsRepositoryImpl, pipelineStageServiceImpl, chartRefRepositoryImpl, chartTemplateServiceImpl, chartServiceImpl, helmAppServiceImpl, deploymentGroupRepositoryImpl, ciPipelineMaterialRepositoryImpl, userServiceImpl, ciTemplateServiceImpl, ciTemplateOverrideRepositoryImpl, gitMaterialHistoryServiceImpl, ciTemplateHistoryServiceImpl, ciPipelineHistoryServiceImpl, globalStrategyMetadataRepositoryImpl, globalStrategyMetadataChartRefMappingRepositoryImpl, pipelineDeploymentServiceTypeConfig, appStatusRepositoryImpl, workflowDagExecutorImpl, enforcerUtilImpl, argoUserServiceImpl, ciWorkflowRepositoryImpl, appGroupServiceImpl, chartDeploymentServiceImpl, k8sUtil)
+	pipelineBuilderImpl := pipeline.NewPipelineBuilderImpl(sugaredLogger, ciCdPipelineOrchestratorImpl, dockerArtifactStoreRepositoryImpl, materialRepositoryImpl, appRepositoryImpl, pipelineRepositoryImpl, propertiesConfigServiceImpl, ciTemplateRepositoryImpl, ciPipelineRepositoryImpl, applicationServiceClientImpl, chartRepositoryImpl, ciArtifactRepositoryImpl, ecrConfig, envConfigOverrideRepositoryImpl, environmentRepositoryImpl, clusterRepositoryImpl, pipelineConfigRepositoryImpl, utilMergeUtil, appWorkflowRepositoryImpl, ciConfig, cdWorkflowRepositoryImpl, appServiceImpl, imageScanResultRepositoryImpl, argoK8sClientImpl, gitFactory, attributesServiceImpl, acdAuthConfig, gitOpsConfigRepositoryImpl, pipelineStrategyHistoryServiceImpl, prePostCiScriptHistoryServiceImpl, prePostCdScriptHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, appLevelMetricsRepositoryImpl, pipelineStageServiceImpl, chartRefRepositoryImpl, chartTemplateServiceImpl, chartServiceImpl, helmAppServiceImpl, deploymentGroupRepositoryImpl, ciPipelineMaterialRepositoryImpl, userServiceImpl, ciTemplateServiceImpl, ciTemplateOverrideRepositoryImpl, gitMaterialHistoryServiceImpl, ciTemplateHistoryServiceImpl, ciPipelineHistoryServiceImpl, globalStrategyMetadataRepositoryImpl, globalStrategyMetadataChartRefMappingRepositoryImpl, pipelineDeploymentServiceTypeConfig, appStatusRepositoryImpl, workflowDagExecutorImpl, enforcerUtilImpl, argoUserServiceImpl, ciWorkflowRepositoryImpl, appGroupServiceImpl, chartDeploymentServiceImpl, k8sUtil, attributesRepositoryImpl)
 	dbMigrationServiceImpl := pipeline.NewDbMogrationService(sugaredLogger, dbMigrationConfigRepositoryImpl)
 	workflowServiceImpl := pipeline.NewWorkflowServiceImpl(sugaredLogger, ciConfig, globalCMCSServiceImpl)
 	ciServiceImpl := pipeline.NewCiServiceImpl(sugaredLogger, workflowServiceImpl, ciPipelineMaterialRepositoryImpl, ciWorkflowRepositoryImpl, ciConfig, eventRESTClientImpl, eventSimpleFactoryImpl, mergeUtil, ciPipelineRepositoryImpl, prePostCiScriptHistoryServiceImpl, pipelineStageServiceImpl, userServiceImpl, ciTemplateServiceImpl, appCrudOperationServiceImpl)
@@ -474,7 +474,7 @@ func InitializeApp() (*App, error) {
 	appListingRouterImpl := router.NewAppListingRouterImpl(appListingRestHandlerImpl)
 	chartRepositoryServiceImpl := chartRepo.NewChartRepositoryServiceImpl(sugaredLogger, chartRepoRepositoryImpl, k8sUtil, clusterServiceImplExtended, acdAuthConfig, httpClient, serverEnvConfigServerEnvConfig)
 	deleteServiceExtendedImpl := delete2.NewDeleteServiceExtendedImpl(sugaredLogger, teamServiceImpl, clusterServiceImplExtended, environmentServiceImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineRepositoryImpl, chartRepositoryServiceImpl, installedAppRepositoryImpl)
-	environmentRestHandlerImpl := cluster3.NewEnvironmentRestHandlerImpl(environmentServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl)
+	environmentRestHandlerImpl := cluster3.NewEnvironmentRestHandlerImpl(environmentServiceImpl, k8sApplicationServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl)
 	environmentRouterImpl := cluster3.NewEnvironmentRouterImpl(environmentRestHandlerImpl)
 	clusterNoteRepositoryImpl := repository2.NewClusterNoteRepositoryImpl(db, sugaredLogger)
 	clusterNoteHistoryRepositoryImpl := repository2.NewClusterNoteHistoryRepositoryImpl(db, sugaredLogger)
@@ -559,7 +559,7 @@ func InitializeApp() (*App, error) {
 	chartRefRouterImpl := router.NewChartRefRouterImpl(chartRefRestHandlerImpl)
 	configMapRestHandlerImpl := restHandler.NewConfigMapRestHandlerImpl(pipelineBuilderImpl, sugaredLogger, chartServiceImpl, userServiceImpl, teamServiceImpl, enforcerImpl, pipelineRepositoryImpl, enforcerUtilImpl, configMapServiceImpl)
 	configMapRouterImpl := router.NewConfigMapRouterImpl(configMapRestHandlerImpl)
-	installedAppRestHandlerImpl := appStore.NewInstalledAppRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, enforcerUtilImpl, installedAppServiceImpl, validate, clusterServiceImplExtended, applicationServiceClientImpl, appStoreDeploymentServiceImpl, helmAppClientImpl, helmAppServiceImpl, argoUserServiceImpl, cdApplicationStatusUpdateHandlerImpl, installedAppRepositoryImpl)
+	installedAppRestHandlerImpl := appStore.NewInstalledAppRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, enforcerUtilImpl, enforcerUtilHelmImpl, installedAppServiceImpl, validate, clusterServiceImplExtended, applicationServiceClientImpl, appStoreDeploymentServiceImpl, helmAppClientImpl, helmAppServiceImpl, argoUserServiceImpl, cdApplicationStatusUpdateHandlerImpl, installedAppRepositoryImpl)
 	appStoreValuesRestHandlerImpl := appStoreValues.NewAppStoreValuesRestHandlerImpl(sugaredLogger, userServiceImpl, appStoreValuesServiceImpl)
 	appStoreValuesRouterImpl := appStoreValues.NewAppStoreValuesRouterImpl(appStoreValuesRestHandlerImpl)
 	appStoreServiceImpl := service3.NewAppStoreServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl)


Test patch:
diff --git a/pkg/cluster/EnvironmentService_test.go b/pkg/cluster/EnvironmentService_test.go
new file mode 100644
index 000000000..c8cdfb812
--- /dev/null
+++ b/pkg/cluster/EnvironmentService_test.go
@@ -0,0 +1,137 @@
+package cluster
+
+import (
+	repository2 "github.com/devtron-labs/devtron/internal/sql/repository"
+	mocks2 "github.com/devtron-labs/devtron/internal/sql/repository/mocks"
+	"github.com/devtron-labs/devtron/pkg/cluster/repository"
+	"github.com/devtron-labs/devtron/pkg/cluster/repository/mocks"
+	"github.com/devtron-labs/devtron/pkg/sql"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+	"testing"
+)
+
+func TestGetEnvironmentListForAutocomplete(t *testing.T) {
+
+	t.Run("FilteredAppDeploymentConfigReturned", func(t *testing.T) {
+		environmentRepoMock := mocks.NewEnvironmentRepository(t)
+		attributesRepoMock := mocks2.NewAttributesRepository(t)
+		impl := EnvironmentServiceImpl{
+			environmentRepository: environmentRepoMock,
+			attributesRepository:  attributesRepoMock,
+		}
+
+		mockError := error(nil)
+		mockModels := []*repository.Environment{}
+		mockModel := repository.Environment{
+			Id: 1,
+			Cluster: &repository.Cluster{
+				ClusterName: "demo",
+				CdArgoSetup: true,
+			},
+		}
+		mockModels = append(mockModels, &mockModel)
+		environmentRepoMock.On("FindAllActive").Return(mockModels, mockError)
+
+		mockDeploymentConfigConfig := &repository2.Attributes{
+			Id:       1,
+			Key:      "1",
+			Value:    "{\"argo_cd\": false, \"helm\": true}",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+		mockError = error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfigConfig, mockError)
+		environmentList, _ := impl.GetEnvironmentListForAutocomplete(true)
+		assert.Equal(t, []string{"helm"}, environmentList[0].AllowedDeploymentTypes)
+	})
+
+	t.Run("InvalidDeploymentConfigPresentInAttributesTable", func(t *testing.T) {
+		environmentRepoMock := mocks.NewEnvironmentRepository(t)
+		attributesRepoMock := mocks2.NewAttributesRepository(t)
+		impl := EnvironmentServiceImpl{
+			environmentRepository: environmentRepoMock,
+			attributesRepository:  attributesRepoMock,
+		}
+
+		mockError := error(nil)
+		mockModels := []*repository.Environment{}
+		mockModel := repository.Environment{
+			Id: 1,
+			Cluster: &repository.Cluster{
+				ClusterName: "demo",
+				CdArgoSetup: true,
+			},
+		}
+		mockModels = append(mockModels, &mockModel)
+		environmentRepoMock.On("FindAllActive").Return(mockModels, mockError)
+
+		mockDeploymentConfigConfig := &repository2.Attributes{
+			Id:       1,
+			Key:      "1",
+			Value:    "{\"bdsjd\": false, \"dnjsds\": true}",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+		mockError = error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfigConfig, mockError)
+		environmentList, _ := impl.GetEnvironmentListForAutocomplete(true)
+		assert.Equal(t, []string{"helm", "argo_cd"}, environmentList[0].AllowedDeploymentTypes)
+	})
+
+	t.Run("BothValidDeploymentConfigIsFalse", func(t *testing.T) {
+		environmentRepoMock := mocks.NewEnvironmentRepository(t)
+		attributesRepoMock := mocks2.NewAttributesRepository(t)
+		impl := EnvironmentServiceImpl{
+			environmentRepository: environmentRepoMock,
+			attributesRepository:  attributesRepoMock,
+		}
+
+		mockError := error(nil)
+		mockModels := []*repository.Environment{}
+		mockModel := repository.Environment{
+			Id: 1,
+			Cluster: &repository.Cluster{
+				ClusterName: "demo",
+				CdArgoSetup: true,
+			},
+		}
+		mockModels = append(mockModels, &mockModel)
+		environmentRepoMock.On("FindAllActive").Return(mockModels, mockError)
+
+		mockDeploymentConfigConfig := &repository2.Attributes{
+			Id:       1,
+			Key:      "1",
+			Value:    "{\"helm\": false, \"argo_cd\": false}",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+		mockError = error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfigConfig, mockError)
+		environmentList, _ := impl.GetEnvironmentListForAutocomplete(true)
+		assert.Equal(t, []string{"helm", "argo_cd"}, environmentList[0].AllowedDeploymentTypes)
+	})
+
+	t.Run("IsDeploymentParamSetToFalse", func(t *testing.T) {
+		environmentRepoMock := mocks.NewEnvironmentRepository(t)
+		impl := EnvironmentServiceImpl{
+			environmentRepository: environmentRepoMock,
+		}
+
+		mockError := error(nil)
+		mockModels := []*repository.Environment{}
+		mockModel := repository.Environment{
+			Id:   1,
+			Name: "demo-devtron",
+			Cluster: &repository.Cluster{
+				ClusterName: "demo",
+				CdArgoSetup: true,
+			},
+		}
+		mockModels = append(mockModels, &mockModel)
+		environmentRepoMock.On("FindAllActive").Return(mockModels, mockError)
+
+		environmentList, _ := impl.GetEnvironmentListForAutocomplete(false)
+		assert.Equal(t, "demo-devtron", environmentList[0].Environment)
+	})
+}
diff --git a/pkg/pipeline/GitopsOrHelmOption_test.go b/pkg/pipeline/GitopsOrHelmOption_test.go
index 72e14c756..3ad195f06 100644
--- a/pkg/pipeline/GitopsOrHelmOption_test.go
+++ b/pkg/pipeline/GitopsOrHelmOption_test.go
@@ -24,7 +24,7 @@ func TestGitopsOrHelmOption(t *testing.T) {
 			nil, nil, nil,
 			nil, nil, nil, nil,
 			nil, nil, nil, nil,
-			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: false}, nil, nil, nil, nil, nil, nil, nil, nil)
+			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: false}, nil, nil, nil, nil, nil, nil, nil, nil, nil)
 
 		pipelineCreateRequest := &bean.CdPipelines{
 			Pipelines: []*bean.CDPipelineConfigObject{
@@ -77,7 +77,7 @@ func TestGitopsOrHelmOption(t *testing.T) {
 			nil, nil, nil,
 			nil, nil, nil, nil,
 			nil, nil, nil, nil,
-			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: false}, nil, nil, nil, nil, nil, nil, nil, nil)
+			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: false}, nil, nil, nil, nil, nil, nil, nil, nil, nil)
 
 		pipelineCreateRequest := &bean.CdPipelines{
 			Pipelines: []*bean.CDPipelineConfigObject{
@@ -130,7 +130,7 @@ func TestGitopsOrHelmOption(t *testing.T) {
 			nil, nil, nil,
 			nil, nil, nil, nil,
 			nil, nil, nil, nil,
-			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: true}, nil, nil, nil, nil, nil, nil, nil, nil)
+			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: true}, nil, nil, nil, nil, nil, nil, nil, nil, nil)
 
 		pipelineCreateRequestHelm := &bean.CdPipelines{
 			Pipelines: []*bean.CDPipelineConfigObject{
@@ -221,7 +221,7 @@ func TestGitopsOrHelmOption(t *testing.T) {
 			nil, nil, nil,
 			nil, nil, nil, nil,
 			nil, nil, nil, nil,
-			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: false}, nil, nil, nil, nil, nil, nil, nil, nil)
+			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: false}, nil, nil, nil, nil, nil, nil, nil, nil, nil)
 
 		pipelineCreateRequest := &bean.CdPipelines{
 			Pipelines: []*bean.CDPipelineConfigObject{
@@ -278,7 +278,7 @@ func TestGitopsOrHelmOption(t *testing.T) {
 			nil, nil, nil,
 			nil, nil, nil, nil,
 			nil, nil, nil, nil,
-			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: true}, nil, nil, nil, nil, nil, nil, nil, nil)
+			nil, nil, nil, nil, nil, nil, nil, nil, &DeploymentServiceTypeConfig{IsInternalUse: true}, nil, nil, nil, nil, nil, nil, nil, nil, nil)
 
 		pipelineCreateRequest := &bean.CdPipelines{
 			Pipelines: []*bean.CDPipelineConfigObject{
diff --git a/pkg/pipeline/PipelineBuilder_test.go b/pkg/pipeline/PipelineBuilder_test.go
new file mode 100644
index 000000000..9304544a4
--- /dev/null
+++ b/pkg/pipeline/PipelineBuilder_test.go
@@ -0,0 +1,120 @@
+package pipeline
+
+import (
+	"github.com/devtron-labs/devtron/internal/sql/repository"
+	"github.com/devtron-labs/devtron/internal/sql/repository/mocks"
+	"github.com/devtron-labs/devtron/internal/util"
+	"github.com/devtron-labs/devtron/pkg/bean"
+	"github.com/devtron-labs/devtron/pkg/sql"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+	"net/http"
+	"testing"
+)
+
+func TestPipelineBuilderImpl_validateDeploymentAppType(t *testing.T) {
+
+	t.Run("DeploymentConfigDoesNotExist", func(t *testing.T) {
+		attributesRepoMock := mocks.NewAttributesRepository(t)
+
+		impl := PipelineBuilderImpl{
+			attributesRepository: attributesRepoMock, // Provide a mock implementation of attributesRepository
+		}
+		pipeline := &bean.CDPipelineConfigObject{
+			EnvironmentId:     123,
+			DeploymentAppType: "SomeAppType",
+		}
+
+		mockDeploymentConfigConfig := &repository.Attributes{
+			Id:       1,
+			Key:      "2",
+			Value:    "",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+		mockError := error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfigConfig, mockError)
+
+		err := impl.validateDeploymentAppType(pipeline)
+		assert.Nil(t, err)
+	})
+
+	t.Run("AllDeploymentConfigTrue", func(t *testing.T) {
+		attributesRepoMock := mocks.NewAttributesRepository(t)
+
+		impl := PipelineBuilderImpl{
+			attributesRepository: attributesRepoMock, // Provide a mock implementation of attributesRepository
+		}
+		pipeline := &bean.CDPipelineConfigObject{
+			EnvironmentId:     123,
+			DeploymentAppType: "SomeAppType",
+		}
+
+		mockDeploymentConfig := &repository.Attributes{
+			Id:       1,
+			Key:      "123",
+			Value:    "{\"argo_cd\": true, \"helm\": true}",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+		mockError := error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfig, mockError)
+
+		err := impl.validateDeploymentAppType(pipeline)
+
+		assert.Nil(t, err)
+	})
+
+	t.Run("ValidDeploymentConfigReceived", func(t *testing.T) {
+		attributesRepoMock := mocks.NewAttributesRepository(t)
+
+		impl := PipelineBuilderImpl{
+			attributesRepository: attributesRepoMock, // Provide a mock implementation of attributesRepository
+		}
+		pipeline := &bean.CDPipelineConfigObject{
+			EnvironmentId:     123,
+			DeploymentAppType: "helm",
+		}
+
+		mockDeploymentConfigConfig := &repository.Attributes{
+			Id:       1,
+			Key:      "123",
+			Value:    "{\"argo_cd\": false, \"helm\": true}",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+		mockError := error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfigConfig, mockError)
+
+		err := impl.validateDeploymentAppType(pipeline)
+
+		assert.Nil(t, err)
+	})
+
+	t.Run("InvalidDeploymentConfigReceived", func(t *testing.T) {
+		attributesRepoMock := mocks.NewAttributesRepository(t)
+
+		impl := PipelineBuilderImpl{
+			attributesRepository: attributesRepoMock, // Provide a mock implementation of attributesRepository
+		}
+		pipeline := &bean.CDPipelineConfigObject{
+			EnvironmentId:     123,
+			DeploymentAppType: "SomeOtherAppType",
+		}
+
+		mockDeploymentConfigConfig := &repository.Attributes{
+			Id:       1,
+			Key:      "123",
+			Value:    "{\"argo_cd\": false, \"helm\": true}",
+			Active:   false,
+			AuditLog: sql.AuditLog{},
+		}
+
+		mockError := error(nil)
+		attributesRepoMock.On("FindByKey", mock.Anything).Return(mockDeploymentConfigConfig, mockError)
+
+		err := impl.validateDeploymentAppType(pipeline)
+		apiErr, _ := err.(*util.ApiError)
+		assert.Equal(t, http.StatusBadRequest, apiErr.HttpStatusCode)
+	})
+}