diff --git a/pkg/plugin/GlobalPluginService.go b/pkg/plugin/GlobalPluginService.go index 611d904b5f..b59fe00ce4 100644 --- a/pkg/plugin/GlobalPluginService.go +++ b/pkg/plugin/GlobalPluginService.go @@ -1753,6 +1753,116 @@ func (impl *GlobalPluginServiceImpl) GetPluginParentMetadataDtos(parentIdVsPlugi return pluginParentMetadataDtos, nil } +func buildPluginStepsByPluginId(pluginSteps []*repository.PluginStep, pluginStepVariables []*repository.PluginStepVariable, + pluginStepConditions []*repository.PluginStepCondition, pluginScripts []*repository.PluginPipelineScript, + scriptMappings []*repository.ScriptPathArgPortMapping) map[int][]*bean2.PluginStepsDto { + pluginStepsDto := adaptor.GetPluginStepsDtoFromDbObjects(pluginSteps) + pluginStepVariablesDto := adaptor.GetPluginStepVariablesDtoFromDbObjects(pluginStepVariables) + pluginStepConditionsDto := adaptor.GetPluginStepConditionsDtoFromDbObjects(pluginStepConditions) + pluginScriptsDto := adaptor.GetPluginPipelineScriptsDtoFromDbObjects(pluginScripts) + scriptMappingsDto := adaptor.GetScripPathArgPortMappingsDtoFromDbObjects(scriptMappings) + + variableIdVsConditionsMap := helper2.GetVariableIdVsPluginStepConditionsMap(pluginStepConditionsDto) + for _, variable := range pluginStepVariablesDto { + variable.PluginStepCondition = variableIdVsConditionsMap[variable.Id] + } + pluginStepIdVsVariablesMap := helper2.GetPluginStepIdVsPluginStepVariablesMap(pluginStepVariablesDto) + + scriptIdVsMappingsMap := helper2.GetScriptIdVsScriptArgsDetailsMap(scriptMappingsDto) + for _, script := range pluginScriptsDto { + script.PathArgPortMapping = scriptIdVsMappingsMap[script.Id] + } + scriptIdVsScriptMap := helper2.GetScriptIdVsPluginScript(pluginScriptsDto) + + pluginIdVsStepsMap := make(map[int][]*bean2.PluginStepsDto) + for index, step := range pluginStepsDto { + step.PluginStepVariable = pluginStepIdVsVariablesMap[step.Id] + step.PluginPipelineScript = scriptIdVsScriptMap[step.ScriptId] + pluginId := pluginSteps[index].PluginId + pluginIdVsStepsMap[pluginId] = append(pluginIdVsStepsMap[pluginId], step) + } + return pluginIdVsStepsMap +} + +func (impl *GlobalPluginServiceImpl) getPluginStepsByPluginIds(pluginIds []int) (map[int][]*bean2.PluginStepsDto, error) { + pluginSteps, err := impl.globalPluginRepository.GetStepsByPluginIds(pluginIds) + if err != nil { + impl.logger.Errorw("getPluginStepsByPluginIds, error in getting plugin steps", "pluginIds", pluginIds, "err", err) + return nil, err + } + if len(pluginSteps) == 0 { + return map[int][]*bean2.PluginStepsDto{}, nil + } + + stepIds := make([]int, 0, len(pluginSteps)) + scriptIds := make([]int, 0, len(pluginSteps)) + seenScriptIds := make(map[int]bool, len(pluginSteps)) + for _, step := range pluginSteps { + stepIds = append(stepIds, step.Id) + if step.ScriptId > 0 && !seenScriptIds[step.ScriptId] { + scriptIds = append(scriptIds, step.ScriptId) + seenScriptIds[step.ScriptId] = true + } + } + + pluginStepVariables, err := impl.globalPluginRepository.GetVariablesByStepIds(stepIds) + if err != nil { + impl.logger.Errorw("getPluginStepsByPluginIds, error in getting plugin step variables", "stepIds", stepIds, "err", err) + return nil, err + } + pluginStepConditions, err := impl.globalPluginRepository.GetConditionsByStepIds(stepIds) + if err != nil { + impl.logger.Errorw("getPluginStepsByPluginIds, error in getting plugin step conditions", "stepIds", stepIds, "err", err) + return nil, err + } + + var pluginScripts []*repository.PluginPipelineScript + var scriptMappings []*repository.ScriptPathArgPortMapping + if len(scriptIds) > 0 { + pluginScripts, err = impl.globalPluginRepository.GetScriptDetailByIds(scriptIds) + if err != nil { + impl.logger.Errorw("getPluginStepsByPluginIds, error in getting plugin scripts", "scriptIds", scriptIds, "err", err) + return nil, err + } + scriptMappings, err = impl.globalPluginRepository.GetScriptMappingDetailByScriptIds(scriptIds) + if err != nil { + impl.logger.Errorw("getPluginStepsByPluginIds, error in getting plugin script mappings", "scriptIds", scriptIds, "err", err) + return nil, err + } + } + + return buildPluginStepsByPluginId(pluginSteps, pluginStepVariables, pluginStepConditions, pluginScripts, scriptMappings), nil +} + +func (impl *GlobalPluginServiceImpl) populateCustomPluginSteps(pluginParentMetadataDtos []*bean2.PluginParentMetadataDto) error { + customPluginVersionIds := make([]int, 0) + for _, parentPlugin := range pluginParentMetadataDtos { + if parentPlugin.Type != string(repository.PLUGIN_TYPE_SHARED) || parentPlugin.Versions == nil { + continue + } + for _, version := range parentPlugin.Versions.DetailedPluginVersionData { + customPluginVersionIds = append(customPluginVersionIds, version.Id) + } + } + if len(customPluginVersionIds) == 0 { + return nil + } + + pluginIdVsStepsMap, err := impl.getPluginStepsByPluginIds(customPluginVersionIds) + if err != nil { + return err + } + for _, parentPlugin := range pluginParentMetadataDtos { + if parentPlugin.Type != string(repository.PLUGIN_TYPE_SHARED) || parentPlugin.Versions == nil { + continue + } + for _, version := range parentPlugin.Versions.DetailedPluginVersionData { + version.PluginSteps = pluginIdVsStepsMap[version.Id] + } + } + return nil +} + func (impl *GlobalPluginServiceImpl) ListAllPluginsV2(filter *bean2.PluginsListFilter) (*bean2.PluginsDto, error) { impl.logger.Infow("request received, ListAllPluginsV2", "filter", filter) pluginVersionsMetadata, err := impl.globalPluginRepository.GetMetaDataForAllPlugins(true) @@ -1873,6 +1983,13 @@ func (impl *GlobalPluginServiceImpl) GetPluginDetailV2(queryParams bean2.GlobalP impl.logger.Errorw("GetPluginDetailV2, error in getting plugin parent metadata dtos by pluginParentMetadata ids", "pluginParentMetadataIds", pluginParentMetadataIds, "err", err) return nil, err } + if queryParams.FetchPluginSteps { + err = impl.populateCustomPluginSteps(pluginParentMetadataDtos) + if err != nil { + impl.logger.Errorw("GetPluginDetailV2, error in getting custom plugin steps", "pluginParentMetadataIds", pluginParentMetadataIds, "err", err) + return nil, err + } + } pluginsDto := bean2.NewPluginsDto().WithParentPlugins(pluginParentMetadataDtos) return pluginsDto, nil @@ -2220,7 +2337,7 @@ func (impl *GlobalPluginServiceImpl) createNewPluginVersionOfExistingPlugin(tx * return 0, err } // before saving new plugin version marking previous version's isLatest as false. - err = impl.globalPluginRepository.MarkPreviousPluginVersionLatestFalse(pluginParentMinData.Id) + err = impl.globalPluginRepository.MarkPreviousPluginVersionLatestFalse(pluginParentMinData.Id, tx) if err != nil { impl.logger.Errorw("createNewPluginVersionOfExistingPlugin, error in MarkPreviousPluginVersionLatestFalse", "pluginParentId", pluginDto.Id, "err", err) return 0, err diff --git a/pkg/plugin/GlobalPluginService_test.go b/pkg/plugin/GlobalPluginService_test.go new file mode 100644 index 0000000000..a7ec379d78 --- /dev/null +++ b/pkg/plugin/GlobalPluginService_test.go @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2026. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package plugin + +import ( + "testing" + + "github.com/devtron-labs/devtron/pkg/plugin/repository" +) + +func TestBuildPluginStepsByPluginId(t *testing.T) { + pluginSteps := []*repository.PluginStep{ + {Id: 1, PluginId: 10, Name: "inline", Index: 1, StepType: repository.PLUGIN_STEP_TYPE_INLINE, ScriptId: 100}, + {Id: 2, PluginId: 11, Name: "reference", Index: 1, StepType: repository.PLUGIN_STEP_TYPE_REF_PLUGIN, RefPluginId: 20}, + } + pluginStepVariables := []*repository.PluginStepVariable{ + {Id: 101, PluginStepId: 1, Name: "input", VariableType: repository.PLUGIN_VARIABLE_TYPE_INPUT}, + {Id: 102, PluginStepId: 1, Name: "output", VariableType: repository.PLUGIN_VARIABLE_TYPE_OUTPUT}, + } + pluginStepConditions := []*repository.PluginStepCondition{ + {Id: 201, PluginStepId: 1, ConditionVariableId: 102, ConditionalOperator: "==", ConditionalValue: "success"}, + } + pluginScripts := []*repository.PluginPipelineScript{ + {Id: 100, Script: "echo hello", Type: repository.SCRIPT_TYPE_SHELL}, + } + scriptMappings := []*repository.ScriptPathArgPortMapping{ + {Id: 301, ScriptId: 100, TypeOfMapping: repository.SCRIPT_MAPPING_TYPE_PORT, PortOnLocal: 8080, PortOnContainer: 80}, + } + + stepsByPluginId := buildPluginStepsByPluginId(pluginSteps, pluginStepVariables, pluginStepConditions, pluginScripts, scriptMappings) + + customPluginSteps := stepsByPluginId[10] + if len(customPluginSteps) != 1 { + t.Fatalf("expected one step for plugin 10, got %d", len(customPluginSteps)) + } + step := customPluginSteps[0] + if step.Name != "inline" || step.PluginPipelineScript == nil || step.PluginPipelineScript.Script != "echo hello" { + t.Fatalf("unexpected hydrated step: %#v", step) + } + if len(step.PluginStepVariable) != 2 { + t.Fatalf("expected two variables, got %d", len(step.PluginStepVariable)) + } + if len(step.PluginStepVariable[0].PluginStepCondition) != 0 { + t.Fatal("did not expect conditions on the input variable") + } + if len(step.PluginStepVariable[1].PluginStepCondition) != 1 || step.PluginStepVariable[1].PluginStepCondition[0].Id != 201 { + t.Fatalf("expected the output condition to be preserved: %#v", step.PluginStepVariable[1].PluginStepCondition) + } + if len(step.PluginPipelineScript.PathArgPortMapping) != 1 || step.PluginPipelineScript.PathArgPortMapping[0].Id != 301 { + t.Fatalf("expected the script mapping to be preserved: %#v", step.PluginPipelineScript.PathArgPortMapping) + } + + referencePluginSteps := stepsByPluginId[11] + if len(referencePluginSteps) != 1 || referencePluginSteps[0].PluginPipelineScript != nil { + t.Fatalf("expected a reference step without an inline script: %#v", referencePluginSteps) + } +} + +func TestBuildPluginStepsByPluginIdEmpty(t *testing.T) { + stepsByPluginId := buildPluginStepsByPluginId(nil, nil, nil, nil, nil) + if len(stepsByPluginId) != 0 { + t.Fatalf("expected no plugin steps, got %#v", stepsByPluginId) + } +} diff --git a/pkg/plugin/adaptor/adaptor.go b/pkg/plugin/adaptor/adaptor.go index e145f766d0..d697f08c61 100644 --- a/pkg/plugin/adaptor/adaptor.go +++ b/pkg/plugin/adaptor/adaptor.go @@ -142,6 +142,23 @@ func GetPluginStepVariablesDtoFromDbObjects(pluginStepVarsDbObj []*repository.Pl return pluginStepVarsDto } +// GetPluginStepConditionsDtoFromDbObjects converts persisted step conditions to API DTOs. +func GetPluginStepConditionsDtoFromDbObjects(pluginStepConditionsDbObj []*repository.PluginStepCondition) []*pluginBean.PluginStepCondition { + pluginStepConditionsDto := make([]*pluginBean.PluginStepCondition, 0, len(pluginStepConditionsDbObj)) + for _, condition := range pluginStepConditionsDbObj { + pluginStepConditionsDto = append(pluginStepConditionsDto, &pluginBean.PluginStepCondition{ + Id: condition.Id, + PluginStepId: condition.PluginStepId, + ConditionVariableId: condition.ConditionVariableId, + ConditionType: condition.ConditionType, + ConditionalOperator: condition.ConditionalOperator, + ConditionalValue: condition.ConditionalValue, + Deleted: condition.Deleted, + }) + } + return pluginStepConditionsDto +} + // GetPluginPipelineScriptDtoFromDbObject returns PluginPipelineScript dto object without ScriptPathArgPortMapping object func GetPluginPipelineScriptDtoFromDbObject(pluginPipelineScript *repository.PluginPipelineScript) *pluginBean.PluginPipelineScript { if pluginPipelineScript == nil { diff --git a/pkg/plugin/bean/bean.go b/pkg/plugin/bean/bean.go index 2434d375ce..2cf628c974 100644 --- a/pkg/plugin/bean/bean.go +++ b/pkg/plugin/bean/bean.go @@ -448,6 +448,7 @@ type GlobalPluginDetailsRequest struct { PluginIds []int `schema:"pluginId" json:"pluginIds"` ParentPluginIds []int `schema:"parentPluginId" json:"parentPluginIds"` FetchAllVersionDetails bool `schema:"fetchAllVersionDetails" json:"fetchAllVersionDetails"` + FetchPluginSteps bool `schema:"fetchPluginSteps" json:"fetchPluginSteps"` ParentPluginIdentifier string `schema:"parentPluginIdentifier"` // comma separated parentPluginIdentifiers ParentPluginIdentifiers []string `schema:"-" json:"parentPluginIdentifiers"` AppId int `schema:"appId" json:"appId"` diff --git a/pkg/plugin/helper/helper.go b/pkg/plugin/helper/helper.go index 42cbfaf0e6..bc70866395 100644 --- a/pkg/plugin/helper/helper.go +++ b/pkg/plugin/helper/helper.go @@ -139,6 +139,15 @@ func GetPluginStepIdVsPluginStepVariablesMap(pluginStepVariables []*bean.PluginV return pluginStepIdVsPluginStepVariablesMap } +// GetVariableIdVsPluginStepConditionsMap groups conditions by the variable on which they are defined. +func GetVariableIdVsPluginStepConditionsMap(pluginStepConditions []*bean.PluginStepCondition) map[int][]*bean.PluginStepCondition { + variableIdVsPluginStepConditionsMap := make(map[int][]*bean.PluginStepCondition, len(pluginStepConditions)) + for _, condition := range pluginStepConditions { + variableIdVsPluginStepConditionsMap[condition.ConditionVariableId] = append(variableIdVsPluginStepConditionsMap[condition.ConditionVariableId], condition) + } + return variableIdVsPluginStepConditionsMap +} + func GetScriptIdVsScriptArgsDetailsMap(scriptArgDetails []*bean.ScriptPathArgPortMapping) map[int][]*bean.ScriptPathArgPortMapping { scriptIdVsScriptArgsDetailsMap := make(map[int][]*bean.ScriptPathArgPortMapping, len(scriptArgDetails)) for _, scriptArgDetail := range scriptArgDetails { diff --git a/pkg/plugin/repository/GlobalPluginRepository.go b/pkg/plugin/repository/GlobalPluginRepository.go index f401da1a29..2e71fc2173 100644 --- a/pkg/plugin/repository/GlobalPluginRepository.go +++ b/pkg/plugin/repository/GlobalPluginRepository.go @@ -387,6 +387,7 @@ type GlobalPluginRepository interface { GetExposedVariablesByPluginId(pluginId int) ([]*PluginStepVariable, error) GetExposedVariablesForAllPlugins() ([]*PluginStepVariable, error) GetConditionsByStepId(stepId int) ([]*PluginStepCondition, error) + GetConditionsByStepIds(stepIds []int) ([]*PluginStepCondition, error) GetPluginByName(pluginName string) ([]*PluginMetadata, error) GetAllPluginMetaData() ([]*PluginMetadata, error) GetPluginStepsByPluginId(pluginId int) ([]*PluginStep, error) @@ -404,7 +405,7 @@ type GlobalPluginRepository interface { GetAllPluginMinData() ([]*PluginParentMetadata, error) GetAllPluginMinDataByType(pluginType string) ([]*PluginParentMetadata, error) GetPluginParentMinDataById(id int) (*PluginParentMetadata, error) - MarkPreviousPluginVersionLatestFalse(pluginParentId int) error + MarkPreviousPluginVersionLatestFalse(pluginParentId int, tx *pg.Tx) error GetPluginMetadataByPluginIdentifier(identifier string) (*PluginMetadata, error) SavePluginMetadata(pluginMetadata *PluginMetadata, tx *pg.Tx) (*PluginMetadata, error) @@ -545,7 +546,9 @@ func (impl *GlobalPluginRepositoryImpl) GetStepsByPluginIds(pluginIds []int) ([] var pluginSteps []*PluginStep err := impl.dbConnection.Model(&pluginSteps). Where("deleted = ?", false). - Where("plugin_id in (?)", pg.In(pluginIds)).Select() + Where("plugin_id in (?)", pg.In(pluginIds)). + Order("plugin_id, index, id"). + Select() if err != nil { impl.logger.Errorw("err in getting plugin steps by pluginIds", "err", err, "pluginIds", pluginIds) return nil, err @@ -569,7 +572,9 @@ func (impl *GlobalPluginRepositoryImpl) GetScriptDetailByIds(ids []int) ([]*Plug var scriptDetail []*PluginPipelineScript err := impl.dbConnection.Model(&scriptDetail). Where("id in (?)", pg.In(ids)). - Where("deleted = ?", false).Select() + Where("deleted = ?", false). + Order("id"). + Select() if err != nil { impl.logger.Errorw("err in getting script detail by ids", "ids", ids, "err", err) return nil, err @@ -593,7 +598,9 @@ func (impl *GlobalPluginRepositoryImpl) GetScriptMappingDetailByScriptIds(script var scriptMappingDetail []*ScriptPathArgPortMapping err := impl.dbConnection.Model(&scriptMappingDetail). Where("script_id in (?)", pg.In(scriptIds)). - Where("deleted = ?", false).Select() + Where("deleted = ?", false). + Order("script_id, id"). + Select() if err != nil { impl.logger.Errorw("err in getting script mapping detail by id", "scriptIds", scriptIds, "err", err) return nil, err @@ -617,7 +624,9 @@ func (impl *GlobalPluginRepositoryImpl) GetVariablesByStepIds(stepIds []int) ([] var variables []*PluginStepVariable err := impl.dbConnection.Model(&variables). Where("plugin_step_id in (?)", pg.In(stepIds)). - Where("deleted = ?", false).Select() + Where("deleted = ?", false). + Order("plugin_step_id, variable_step_index, id"). + Select() if err != nil { impl.logger.Errorw("err in getting variables by stepIds", "stepIds", stepIds, "err", err) return nil, err @@ -689,6 +698,20 @@ func (impl *GlobalPluginRepositoryImpl) GetConditionsByStepId(stepId int) ([]*Pl return conditions, nil } +func (impl *GlobalPluginRepositoryImpl) GetConditionsByStepIds(stepIds []int) ([]*PluginStepCondition, error) { + var conditions []*PluginStepCondition + err := impl.dbConnection.Model(&conditions). + Where("plugin_step_id in (?)", pg.In(stepIds)). + Where("deleted = ?", false). + Order("plugin_step_id, condition_variable_id, id"). + Select() + if err != nil { + impl.logger.Errorw("err in getting conditions by stepIds", "stepIds", stepIds, "err", err) + return nil, err + } + return conditions, nil +} + func (impl *GlobalPluginRepositoryImpl) GetPluginByName(pluginName string) ([]*PluginMetadata, error) { var plugin []*PluginMetadata err := impl.dbConnection.Model(&plugin). @@ -1039,9 +1062,9 @@ func (impl *GlobalPluginRepositoryImpl) GetAllPluginMinDataByType(pluginType str return plugins, nil } -func (impl *GlobalPluginRepositoryImpl) MarkPreviousPluginVersionLatestFalse(pluginParentId int) error { +func (impl *GlobalPluginRepositoryImpl) MarkPreviousPluginVersionLatestFalse(pluginParentId int, tx *pg.Tx) error { var model PluginMetadata - _, err := impl.dbConnection.Model(&model). + _, err := tx.Model(&model). Set("is_latest = ?", false). Where("id = (select id from plugin_metadata where plugin_parent_metadata_id = ? and is_latest =true order by created_on desc limit ?)", pluginParentId, 1). Update() diff --git a/specs/plugin/global.yaml b/specs/plugin/global.yaml index 56f53185f5..7c265cea8a 100644 --- a/specs/plugin/global.yaml +++ b/specs/plugin/global.yaml @@ -254,9 +254,7 @@ paths: content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/PluginMetaDataDto' + $ref: '#/components/schemas/PluginsDto' '400': description: Bad request content: @@ -284,7 +282,7 @@ paths: /orchestrator/plugin/global/list/detail/v2: post: - description: Get detailed information for multiple plugins + description: Get detailed information for multiple plugins. Set fetchPluginSteps to include the saved configuration of detailed SHARED plugin versions so they can be edited and saved as a new version. operationId: GetPluginDetailByIds requestBody: required: true @@ -298,9 +296,7 @@ paths: content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/PluginMetaDataDto' + $ref: '#/components/schemas/PluginsDto' '400': description: Bad request content: @@ -471,7 +467,7 @@ components: id: type: integer description: Unique identifier for the plugin version - version: + pluginVersion: type: string description: Version number of the plugin description: @@ -489,8 +485,31 @@ components: type: integer description: ID of the user who created this version updatedBy: - type: integer - description: ID of the user who last updated this version + type: string + description: Email of the user who last updated this version + docLink: + type: string + description: Documentation link for this version + isLatest: + type: boolean + description: Whether this is the latest plugin version + tags: + type: array + items: + type: string + inputVariables: + type: array + items: + $ref: '#/components/schemas/PluginVariableDto' + outputVariables: + type: array + items: + $ref: '#/components/schemas/PluginVariableDto' + pluginSteps: + type: array + description: Complete saved step configuration. Returned only for detailed SHARED plugin versions. + items: + $ref: '#/components/schemas/PluginStepDto' PluginParentMetadataDto: type: object @@ -501,6 +520,9 @@ components: name: type: string description: Name of the plugin + pluginIdentifier: + type: string + description: Stable identifier for the plugin description: type: string description: Detailed description of what the plugin does @@ -511,16 +533,174 @@ components: icon: type: string description: URL or base64 encoded icon - tags: + pluginVersions: + $ref: '#/components/schemas/PluginVersionsDto' + + PluginVersionsDto: + type: object + properties: + detailedPluginVersionData: type: array items: - type: string - description: List of tags - versions: + $ref: '#/components/schemas/PluginVersionDto' + minimalPluginVersionData: type: array items: $ref: '#/components/schemas/PluginVersionDto' + PluginsDto: + type: object + properties: + parentPlugins: + type: array + items: + $ref: '#/components/schemas/PluginParentMetadataDto' + totalCount: + type: integer + + PluginStepDto: + type: object + properties: + id: + type: integer + name: + type: string + description: + type: string + index: + type: integer + stepType: + type: string + enum: [INLINE, REF_PLUGIN] + refPluginId: + type: integer + outputDirectoryPath: + type: array + items: + type: string + dependentOnStep: + type: string + pluginStepVariable: + type: array + items: + $ref: '#/components/schemas/PluginVariableDto' + pluginPipelineScript: + $ref: '#/components/schemas/PluginPipelineScriptDto' + + PluginVariableDto: + type: object + properties: + id: + type: integer + name: + type: string + format: + type: string + enum: [STRING, NUMBER, BOOL, DATE] + description: + type: string + isExposed: + type: boolean + allowEmptyValue: + type: boolean + defaultValue: + type: string + value: + type: string + variableType: + type: string + enum: [INPUT, OUTPUT] + valueType: + type: string + enum: [NEW, FROM_PREVIOUS_STEP, GLOBAL] + previousStepIndex: + type: integer + variableStepIndex: + type: integer + variableStepIndexInPlugin: + type: integer + referenceVariableName: + type: string + pluginStepCondition: + type: array + items: + $ref: '#/components/schemas/PluginStepConditionDto' + + PluginStepConditionDto: + type: object + properties: + id: + type: integer + pluginStepId: + type: integer + conditionVariableId: + type: integer + conditionType: + type: string + conditionalOperator: + type: string + conditionalValue: + type: string + + PluginPipelineScriptDto: + type: object + properties: + id: + type: integer + script: + type: string + storeScriptAt: + type: string + type: + type: string + enum: [SHELL, DOCKERFILE, CONTAINER_IMAGE] + dockerfileExists: + type: boolean + mountPath: + type: string + mountCodeToContainer: + type: boolean + mountCodeToContainerPath: + type: string + mountDirectoryFromHost: + type: boolean + containerImagePath: + type: string + imagePullSecretType: + type: string + enum: [CONTAINER_REGISTRY, SECRET_PATH] + imagePullSecret: + type: string + pathArgPortMapping: + type: array + items: + $ref: '#/components/schemas/ScriptPathArgPortMappingDto' + + ScriptPathArgPortMappingDto: + type: object + properties: + id: + type: integer + typeOfMapping: + type: string + enum: [FILE_PATH, DOCKER_ARG, PORT] + filePathOnDisk: + type: string + filePathOnContainer: + type: string + command: + type: string + args: + type: array + items: + type: string + portOnLocal: + type: integer + portOnContainer: + type: integer + scriptId: + type: integer + PluginMinDto: type: object properties: @@ -534,6 +714,22 @@ components: appId: type: integer description: ID of the application + pluginIds: + type: array + items: + type: integer + description: Plugin version IDs to fetch + parentPluginIds: + type: array + items: + type: integer + description: Parent plugin IDs to fetch + fetchAllVersionDetails: + type: boolean + description: Include detailed data for every version instead of only requested or latest versions + fetchPluginSteps: + type: boolean + description: Include saved steps, scripts, variables, conditions, and mappings for detailed SHARED plugin versions parentPluginIdentifiers: type: array items: