diff --git a/api/restHandler/CoreAppRestHandler.go b/api/restHandler/CoreAppRestHandler.go index 3cc040d4e7..df5d44f1e2 100644 --- a/api/restHandler/CoreAppRestHandler.go +++ b/api/restHandler/CoreAppRestHandler.go @@ -1587,6 +1587,15 @@ func (handler CoreAppRestHandlerImpl) createWorkflows(ctx context.Context, appId } func (handler CoreAppRestHandlerImpl) createWorkflowInDb(workflowName string, appId int, userId int32) (int, error) { + //checking if workflow name already exist or not + ok, err := handler.appWorkflowService.IsWorkflowNameFound(workflowName, appId) + if err != nil { + return 0, err + } + // if workflow name already exists then we will assign a new name to the workflow + if ok { + workflowName = util.GenerateNewWorkflowName(workflowName) + } wf := &appWorkflow2.AppWorkflow{ Name: workflowName, AppId: appId, diff --git a/pkg/appWorkflow/AppWorkflowService.go b/pkg/appWorkflow/AppWorkflowService.go index fc3dee9bcd..36a982d630 100644 --- a/pkg/appWorkflow/AppWorkflowService.go +++ b/pkg/appWorkflow/AppWorkflowService.go @@ -20,6 +20,7 @@ package appWorkflow import ( "errors" "fmt" + util2 "github.com/devtron-labs/devtron/util" "time" mapset "github.com/deckarep/golang-set" @@ -59,7 +60,7 @@ type AppWorkflowService interface { FindAppWorkflowMappingByComponent(id int, compType string) ([]*appWorkflow.AppWorkflowMapping, error) CheckCdPipelineByCiPipelineId(id int) bool FindAppWorkflowByName(name string, appId int) (AppWorkflowDto, error) - + IsWorkflowNameFound(workflowName string, appId int) (bool, error) FindAllWorkflowsComponentDetails(appId int) (*AllAppWorkflowComponentDetails, error) FindAppWorkflowsByEnvironmentId(request resourceGroup2.ResourceGroupingRequest, token string) ([]*AppWorkflowDto, error) FindAllWorkflowsForApps(request WorkflowNamesRequest) (*WorkflowNamesResponse, error) @@ -178,7 +179,10 @@ func (impl AppWorkflowServiceImpl) CreateAppWorkflow(req AppWorkflowDto) (AppWor var wf *appWorkflow.AppWorkflow var savedAppWf *appWorkflow.AppWorkflow var err error - + ok, err := impl.IsWorkflowNameFound(req.Name, req.AppId) + if err != nil { + return req, err + } if req.Id != 0 { wf = &appWorkflow.AppWorkflow{ Id: req.Id, @@ -189,19 +193,20 @@ func (impl AppWorkflowServiceImpl) CreateAppWorkflow(req AppWorkflowDto) (AppWor UpdatedBy: req.UserId, }, } - savedAppWf, err = impl.appWorkflowRepository.UpdateAppWorkflow(wf) - } else { - workflow, err := impl.appWorkflowRepository.FindByNameAndAppId(req.Name, req.AppId) - if err != nil && err != pg.ErrNoRows { - impl.Logger.Errorw("error in finding workflow by app id and name", "name", req.Name, "appId", req.AppId) - return req, err - } - if workflow.Id != 0 { + // if workflow name already exists then we will not allow update workflow name with same name + if ok { impl.Logger.Errorw("workflow with this name already exist", "err", err) return req, errors.New(bean2.WORKFLOW_EXIST_ERROR) } + savedAppWf, err = impl.appWorkflowRepository.UpdateAppWorkflow(wf) + } else { + workflowName := req.Name + // if workflow already exists then we will assign a new name to the workflow + if ok { + workflowName = util2.GenerateNewWorkflowName(workflowName) + } wf := &appWorkflow.AppWorkflow{ - Name: req.Name, + Name: workflowName, AppId: req.AppId, Active: true, AuditLog: sql.AuditLog{ @@ -911,3 +916,15 @@ func getMappingsFromIds(identifierToNodeMapping map[PipelineIdentifier]*AppWorkf } return result } + +func (impl AppWorkflowServiceImpl) IsWorkflowNameFound(workflowName string, appId int) (bool, error) { + workflow, err := impl.appWorkflowRepository.FindByNameAndAppId(workflowName, appId) + if err != nil && !errors.Is(err, pg.ErrNoRows) && !errors.Is(err, pg.ErrMultiRows) { + impl.Logger.Errorw("error in finding workflow by app id and name", "name", workflowName, "appId", appId) + return false, err + } + if workflow.Id != 0 { + return true, nil + } + return false, nil +} diff --git a/util/helper.go b/util/helper.go index 1c03e5c2cc..eeb31ce977 100644 --- a/util/helper.go +++ b/util/helper.go @@ -135,6 +135,11 @@ func Generate(size int) string { return str } +// Generates random name format name-clone-xyts +func GenerateNewWorkflowName(name string) string { + return fmt.Sprintf("%s-clone-%s", name, Generate(4)) +} + func HttpRequest(url string) (map[string]interface{}, error) { req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil {