From b8d445a82b46d7c65dcad641eec74236fee14d88 Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Thu, 8 May 2025 21:27:40 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0constant=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E8=BD=AC=E6=8D=A2=20#184=20#=20Reviewed,=20transactio?= =?UTF-8?q?n=20id:=2041679?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bkflow/pipeline_converter/constants.py | 6 + .../data_model_to_web_pipeline/component.py | 1 - .../data_model_to_web_pipeline/constant.py | 80 +++++++ .../data_model_to_web_pipeline/pipeline.py | 30 ++- .../converters/json_to_data_model/constant.py | 88 +++++++ .../converters/json_to_data_model/pipeline.py | 25 +- bkflow/pipeline_converter/data_models.py | 36 ++- .../json_to_data_model/test_pipeline.py | 217 +++++++++++++++++- 8 files changed, 473 insertions(+), 10 deletions(-) diff --git a/bkflow/pipeline_converter/constants.py b/bkflow/pipeline_converter/constants.py index b9800b3a9b..9af4324098 100644 --- a/bkflow/pipeline_converter/constants.py +++ b/bkflow/pipeline_converter/constants.py @@ -19,6 +19,12 @@ class NodeTypes(str, Enum): ] +class ConstantTypes(str, Enum): + CUSTOM_CONSTANT = "custom" + COMPONENT_INPUTS_CONSTANT = "component_inputs" + COMPONENT_OUTPUTS_CONSTANT = "component_outputs" + + class DataTypes(str, Enum): DATA_MODEL = "data_model" JSON = "json" diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/component.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/component.py index 4c91adc31d..f27a8182fa 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/component.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/component.py @@ -12,7 +12,6 @@ def convert(self, *args, **kwargs): for field in fields: self.target_data[field.key] = { "need_render": field.need_render, - "key": field.key, "value": field.value, "hook": False, # TODO: 可配置 } diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py index 40a96afc6f..7289322299 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py @@ -1 +1,81 @@ # -*- coding: utf-8 -*- +from bkflow.pipeline_converter.constants import ConstantTypes +from bkflow.pipeline_converter.converters.base import DataModelToPipelineTreeConverter +from bkflow.pipeline_converter.validators.node import NodeTypeValidator + + +class SourceInfoConverter(DataModelToPipelineTreeConverter): + def convert(self): + self.target_data = {} + for info in self.source_data: + self.target_data[info.key] = [info.value] + return self.target_data + + +class CustomConstantConverter(DataModelToPipelineTreeConverter): + validators = [NodeTypeValidator(ConstantTypes.CUSTOM_CONSTANT.value)] + + def convert(self): + converter_data = self.source_data + self.target_data = { + "name": converter_data.name, + "key": converter_data.key, + "desc": converter_data.desc, + "value": converter_data.value, + "custom_type": converter_data.custom_type, + "show_type": converter_data.show_type, + "source_tag": converter_data.source_tag, + "source_type": ConstantTypes.CUSTOM_CONSTANT.value, + "source_info": SourceInfoConverter(converter_data.source_info).convert(), + "validation": converter_data.validation, + "version": converter_data.version, + "pre_render_make": False, + "is_meta": converter_data.is_meta, + } + + return self.target_data + + +class ComponentInputConverter(DataModelToPipelineTreeConverter): + validators = [NodeTypeValidator(ConstantTypes.COMPONENT_INPUTS_CONSTANT.value)] + + def convert(self): + converter_data = self.source_data + self.target_data = { + "name": converter_data.name, + "key": converter_data.key, + "desc": converter_data.desc, + "value": [converter_data.value], + "custom_type": converter_data.custom_type, + "show_type": converter_data.show_type, + "source_tag": converter_data.source_tag, + "source_type": ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, + "source_info": SourceInfoConverter(converter_data.source_info).convert(), + "validation": converter_data.validation, + "version": converter_data.version, + "plugin_code": converter_data.plugin_code, + "extra_info": converter_data.extra_info, + } + return self.target_data + + +class ComponentOutputConverter(DataModelToPipelineTreeConverter): + validators = [NodeTypeValidator(ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value)] + + def convert(self): + converter_data = self.source_data + self.target_data = { + "name": converter_data.name, + "key": converter_data.key, + "desc": converter_data.desc, + "value": converter_data.value, + "custom_type": converter_data.custom_type, + "show_type": converter_data.show_type, + "source_tag": converter_data.source_tag, + "source_type": ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, + "source_info": SourceInfoConverter(converter_data.source_info).convert(), + "validation": converter_data.validation, + "plugin_code": converter_data.plugin_code, + "extra_info": converter_data.extra_info, + } + return self.target_data diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py index a593408ae6..60b6dabdc5 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py @@ -5,8 +5,13 @@ from pipeline.parser.utils import replace_all_id from pipeline.utils.uniqid import line_uniqid -from bkflow.pipeline_converter.constants import NodeTypes +from bkflow.pipeline_converter.constants import ConstantTypes, NodeTypes from bkflow.pipeline_converter.converters.base import DataModelToPipelineTreeConverter +from bkflow.pipeline_converter.converters.data_model_to_web_pipeline.constant import ( + ComponentInputConverter, + ComponentOutputConverter, + CustomConstantConverter, +) from bkflow.pipeline_converter.converters.data_model_to_web_pipeline.gateway import ( ConditionalParallelGatewayConverter, ConvergeGatewayConverter, @@ -19,6 +24,7 @@ StartNodeConverter, ) from bkflow.pipeline_converter.data_models import Flow, Node, Pipeline +from bkflow.pipeline_converter.hub import ConverterHub class PipelineConverter(DataModelToPipelineTreeConverter): @@ -28,6 +34,7 @@ def convert(self) -> dict: """ pipeline: Pipeline = self.source_data nodes: List[Node] = pipeline.nodes + constants = pipeline.constants self.target_data = { PE.id: pipeline.id, PE.name: pipeline.name, @@ -57,6 +64,9 @@ def convert(self) -> dict: elif node.type in NodeTypes.GATEWAYS: gateway_data = gateway_mapping[node.type](node).convert() self.target_data[PE.gateways][node.id] = gateway_data + + # 常量数据转换 + self.target_data[PE.constants] = self.constant_converter(constants) # 连线数据转换 flows = self._generate_flows_by_nodes(nodes) self.target_data[PE.flows] = {flow.id: flow.dict() for flow in flows} @@ -73,6 +83,24 @@ def convert(self) -> dict: replace_all_id(self.target_data) return self.target_data + def constant_converter(self, constants): + constant_type_converter_cls_name_map = { + ConstantTypes.CUSTOM_CONSTANT.value: CustomConstantConverter.__name__, + ConstantTypes.COMPONENT_INPUTS_CONSTANT.value: ComponentInputConverter.__name__, + ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value: ComponentOutputConverter.__name__, + } + result = {} + for index, constant in enumerate(constants): + converter_cls = ConverterHub.get_converter_cls( + source=self.source, + target=self.target, + converter_name=constant_type_converter_cls_name_map[constant.type], + ) + constant_data = converter_cls(constant).convert() + constant_data["index"] = index + result[constant.key] = constant_data + return result + @staticmethod def _generate_flows_by_nodes(nodes: List[Node]) -> List[Flow]: """生成流程中的连线信息""" diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py index 40a96afc6f..2143484486 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py @@ -1 +1,89 @@ # -*- coding: utf-8 -*- +from bkflow.pipeline_converter.constants import ConstantTypes +from bkflow.pipeline_converter.converters.base import JsonToDataModelConverter +from bkflow.pipeline_converter.data_models import ( + ComponentInputConstant, + ComponentOutConstant, + CustomConstant, + SourceInfo, +) +from bkflow.pipeline_converter.validators.node import JsonNodeTypeValidator + + +class SourceInfoConverter(JsonToDataModelConverter): + def convert(self): + self.target_data = [] + for info in self.source_data: + info_data = SourceInfo(key=info["key"], value=info["value"]) + self.target_data.append(info_data) + return self.target_data + + +class CustomConstantConverter(JsonToDataModelConverter): + validators = [JsonNodeTypeValidator(ConstantTypes.CUSTOM_CONSTANT.value)] + + def convert(self): + self.target_data = CustomConstant( + name=self.source_data["name"], + type=ConstantTypes.CUSTOM_CONSTANT.value, + key=self.source_data["key"], + value=self.source_data["value"], + custom_type=self.source_data["custom_type"], + source_tag=self.source_data["source_tag"], + pre_render_make=False, + source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), + ) + default_optional_field = ["desc", "source_info", "validation", "is_meta", "version", "show_type"] + for field in default_optional_field: + if field not in self.source_data: + continue + setattr(self.target_data, field, self.source_data[field]) + + return self.target_data + + +class ComponentInputConverter(JsonToDataModelConverter): + validators = [JsonNodeTypeValidator(ConstantTypes.COMPONENT_INPUTS_CONSTANT.value)] + + def convert(self): + self.target_data = ComponentInputConstant( + name=self.source_data["name"], + key=self.source_data["key"], + value=self.source_data["value"], + custom_type=self.source_data["custom_type"], + source_tag=self.source_data["source_tag"], + type=ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, + source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), + version=self.source_data["version"], + extra_info=self.source_data["extra_info"], + ) + default_optional_field = ["desc", "validation", "version", "show_type", "plugin_code"] + for field in default_optional_field: + if field not in self.source_data: + continue + setattr(self.target_data, field, self.source_data[field]) + + return self.target_data + + +class ComponentOutputConverter(JsonToDataModelConverter): + validators = [JsonNodeTypeValidator(ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value)] + + def convert(self): + self.target_data = ComponentOutConstant( + name=self.source_data["name"], + key=self.source_data["key"], + value=self.source_data["value"], + custom_type=self.source_data["custom_type"], + source_tag=self.source_data["source_tag"], + type=ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, + source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), + extra_info=self.source_data["extra_info"], + ) + default_optional_field = ["desc", "validation", "show_type", "plugin_code"] + for field in default_optional_field: + if field not in self.source_data: + continue + setattr(self.target_data, field, self.source_data[field]) + + return self.target_data diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py b/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py index 529a63e0bf..2b26974220 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py @@ -1,6 +1,11 @@ # -*- coding: utf-8 -*- -from bkflow.pipeline_converter.constants import NodeTypes +from bkflow.pipeline_converter.constants import ConstantTypes, NodeTypes from bkflow.pipeline_converter.converters.base import JsonToDataModelConverter +from bkflow.pipeline_converter.converters.json_to_data_model.constant import ( + ComponentInputConverter, + ComponentOutputConverter, + CustomConstantConverter, +) from bkflow.pipeline_converter.converters.json_to_data_model.gateway import ( ConditionalParallelGatewayConverter, ConvergeGatewayConverter, @@ -25,7 +30,7 @@ def convert(self) -> dict: target_nodes = [] # TODO: 这块考虑抽象公共逻辑 - node_type_converter_cls_name_map = { + data_type_converter_cls_name_map = { NodeTypes.COMPONENT.value: ComponentNodeConverter.__name__, NodeTypes.END_EVENT.value: EndNodeConverter.__name__, NodeTypes.START_EVENT.value: StartNodeConverter.__name__, @@ -33,12 +38,26 @@ def convert(self) -> dict: NodeTypes.EXCLUSIVE_GATEWAY.value: ExclusiveGatewayConverter.__name__, NodeTypes.CONDITIONAL_PARALLEL_GATEWAY.value: ConditionalParallelGatewayConverter.__name__, NodeTypes.CONVERGE_GATEWAY.value: ConvergeGatewayConverter.__name__, + ConstantTypes.CUSTOM_CONSTANT.value: CustomConstantConverter.__name__, + ConstantTypes.COMPONENT_INPUTS_CONSTANT.value: ComponentInputConverter.__name__, + ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value: ComponentOutputConverter.__name__, } for node in self.source_data.get("nodes", []): converter_cls = ConverterHub.get_converter_cls( - source=self.source, target=self.target, converter_name=node_type_converter_cls_name_map[node["type"]] + source=self.source, target=self.target, converter_name=data_type_converter_cls_name_map[node["type"]] ) target_nodes.append(converter_cls(node).convert()) self.target_data.nodes = target_nodes + target_constants = [] + for constant in self.source_data.get("constants", []): + converter_cls = ConverterHub.get_converter_cls( + source=self.source, + target=self.target, + converter_name=data_type_converter_cls_name_map[constant["type"]], + ) + converted_data = converter_cls(constant).convert() + target_constants.append(converted_data) + self.target_data.constants = target_constants + return self.target_data diff --git a/bkflow/pipeline_converter/data_models.py b/bkflow/pipeline_converter/data_models.py index 41e54d5663..28faf77bcb 100644 --- a/bkflow/pipeline_converter/data_models.py +++ b/bkflow/pipeline_converter/data_models.py @@ -3,7 +3,7 @@ from pydantic import BaseModel -from bkflow.pipeline_converter.constants import NodeTypes +from bkflow.pipeline_converter.constants import ConstantTypes, NodeTypes class Node(BaseModel): @@ -100,14 +100,42 @@ class ConditionalParallelGateway(ExclusiveGateway, ParallelGateway): type: str = NodeTypes.CONDITIONAL_PARALLEL_GATEWAY.value +class SourceInfo(BaseModel): + key: str + value: str + + class Constant(BaseModel): name: str - type: str + type: str # source_type key: str value: Any version: str = "legacy" - source_type: str - pre_render_mako: bool = False + desc: str = "" + show_type: str = "show" + validation: str = "" + custom_type: str + source_info: List[SourceInfo] + source_tag: str + + +class CustomConstant(Constant): + type: str = ConstantTypes.CUSTOM_CONSTANT.value + pre_render_make: bool = False + is_meta: bool = False + + +class ComponentInputConstant(Constant): + type: str = ConstantTypes.COMPONENT_INPUTS_CONSTANT.value + plugin_code: str = "" + extra_info: Dict[str, Any] + + +class ComponentOutConstant(Constant): + type: str = ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value + show_type: str = "hide" + plugin_code: str = "" + extra_info: Dict[str, Any] class Extensions(BaseModel): diff --git a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py index 7177b5b0c5..37439ff1f8 100644 --- a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py +++ b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py @@ -2,7 +2,7 @@ from bamboo_engine import validator as engine_validator from pipeline.core.constants import PE -from bkflow.pipeline_converter.constants import DataTypes +from bkflow.pipeline_converter.constants import ConstantTypes, DataTypes from bkflow.pipeline_converter.data_models import Pipeline from bkflow.pipeline_converter.hub import CONVERTER_HUB from bkflow.pipeline_web.parser.format import format_web_data_to_pipeline @@ -213,3 +213,218 @@ def test_json_2_web_pipeline_convert_with_gateway_success(self): validate_web_pipeline_tree(web_pipeline_tree) engine_pipeline_tree = format_web_data_to_pipeline(web_pipeline_tree) engine_validator.validate_and_process_pipeline(engine_pipeline_tree, cycle_tolerate=False) + + def test_json_2_web_pipeline_convert_with_custom_constant(self): + json_data = { + "id": "pipeline_id", + "name": "pipeline_name", + "nodes": [ + { + "id": "start_node", + "type": "start_event", + "next": "custom_node", + }, + { + "id": "custom_node", + "type": "component", + "name": "component_node", + "component": { + "code": "bk_display", + "version": "v1.0", + "data": [{"key": "bk_display_message", "value": "${test_name}"}], + }, + "next": "end_node", + }, + { + "id": "end_node", + "type": "end_event", + }, + ], + "constants": [ + { + "name": "test_name", + "type": ConstantTypes.CUSTOM_CONSTANT.value, + "key": "${test_name}", + "value": "test_value", + "custom_type": "textarea", + "source_tag": "textarea.textarea", + "source_info": [], + } + ], + } + json_pipeline_cvt = CONVERTER_HUB.get_converter_cls( + DataTypes.JSON.value, DataTypes.DATA_MODEL.value, "PipelineConverter" + ) + dm_pipeline = json_pipeline_cvt(json_data).convert() + assert isinstance(dm_pipeline, Pipeline) + + data_model_pipeline_cvt = CONVERTER_HUB.get_converter_cls( + DataTypes.DATA_MODEL.value, DataTypes.WEB_PIPELINE.value, "PipelineConverter" + ) + web_pipeline_tree = data_model_pipeline_cvt(dm_pipeline).convert() + + assert len(web_pipeline_tree[PE.activities]) == 1 + assert len(web_pipeline_tree[PE.flows]) == 2 + + # 确保 web_pipeline_tree 格式正确 且能够正常转换成 engine_pipeline_tree + validate_web_pipeline_tree(web_pipeline_tree) + engine_pipeline_tree = format_web_data_to_pipeline(web_pipeline_tree) + engine_validator.validate_and_process_pipeline(engine_pipeline_tree, cycle_tolerate=False) + + def test_json_2_web_pipeline_convert_with_component_output_constant(self): + json_data = { + "id": "pipeline_id", + "name": "pipeline_name", + "nodes": [ + { + "id": "start_node", + "type": "start_event", + "next": "custom_node", + }, + { + "id": "custom_node", + "type": "component", + "name": "component_node", + "component": { + "code": "bk_display", + "version": "v1.0", + "data": [{"key": "bk_display_message", "value": "${test_name}"}], + }, + "next": "exclusive_gateway", + }, + { + "id": "exclusive_gateway", + "name": "exclusive_gateway", + "type": "exclusive_gateway", + "conditions": [ + {"name": "condition_1", "next": "condition_node_1", "expr": "${_result_1} == true"}, + {"name": "condition_2", "next": "condition_node_2", "expr": "1 == 2"}, + ], + "next": ["condition_node_1", "condition_node_2"], + }, + { + "id": "condition_node_1", + "name": "condition_node_1", + "type": "component", + "component": { + "code": "bk_display", + "version": "v1.0", + "data": [{"key": "bk_display_message", "value": 123}], + }, + "next": "end_node", + }, + { + "id": "condition_node_2", + "name": "condition_node_2", + "type": "component", + "component": { + "code": "bk_display", + "version": "v1.0", + "data": [{"key": "bk_display_message", "value": 123}], + }, + "next": "end_node", + }, + { + "id": "end_node", + "type": "end_event", + }, + ], + "constants": [ + { + "name": "test_name", + "type": ConstantTypes.CUSTOM_CONSTANT.value, + "key": "${test_name}", + "value": "test_value", + "custom_type": "textarea", + "source_tag": "textarea.textarea", + "source_info": [], + }, + { + "name": "执行结果", + "type": ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, + "key": "${_result_1}", + "custom_type": "", + "source_tag": "", + "source_info": [{"key": "custom_node", "value": "_result"}], + "value": "", + "extra_info": {}, + }, + ], + } + json_pipeline_cvt = CONVERTER_HUB.get_converter_cls( + DataTypes.JSON.value, DataTypes.DATA_MODEL.value, "PipelineConverter" + ) + dm_pipeline = json_pipeline_cvt(json_data).convert() + assert isinstance(dm_pipeline, Pipeline) + + data_model_pipeline_cvt = CONVERTER_HUB.get_converter_cls( + DataTypes.DATA_MODEL.value, DataTypes.WEB_PIPELINE.value, "PipelineConverter" + ) + web_pipeline_tree = data_model_pipeline_cvt(dm_pipeline).convert() + + assert len(web_pipeline_tree[PE.activities]) == 3 + assert len(web_pipeline_tree[PE.flows]) == 6 + + # 确保 web_pipeline_tree 格式正确 且能够正常转换成 engine_pipeline_tree + validate_web_pipeline_tree(web_pipeline_tree) + engine_pipeline_tree = format_web_data_to_pipeline(web_pipeline_tree) + engine_validator.validate_and_process_pipeline(engine_pipeline_tree, cycle_tolerate=False) + + def test_json_2_web_pipeline_convert_with_component_input_constant(self): + json_data = { + "id": "pipeline_id", + "name": "pipeline_name", + "nodes": [ + { + "id": "start_node", + "type": "start_event", + "next": "custom_node", + }, + { + "id": "custom_node", + "type": "component", + "name": "component_node", + "component": { + "code": "bk_display", + "version": "v1.0", + "data": [{"key": "bk_display_message", "value": "${bk_display_message}"}], + }, + "next": "end_node", + }, + { + "id": "end_node", + "type": "end_event", + }, + ], + "constants": [ + { + "name": "bk_display_message", + "type": ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, + "key": "${bk_display_message}", + "value": "test_value", + "custom_type": "", + "source_tag": "bk_display.bk_display_message", + "version": "v1.0", + "source_info": [{"key": "custom_node", "value": "bk_display_message"}], + "extra_info": {}, + } + ], + } + json_pipeline_cvt = CONVERTER_HUB.get_converter_cls( + DataTypes.JSON.value, DataTypes.DATA_MODEL.value, "PipelineConverter" + ) + dm_pipeline = json_pipeline_cvt(json_data).convert() + assert isinstance(dm_pipeline, Pipeline) + + data_model_pipeline_cvt = CONVERTER_HUB.get_converter_cls( + DataTypes.DATA_MODEL.value, DataTypes.WEB_PIPELINE.value, "PipelineConverter" + ) + web_pipeline_tree = data_model_pipeline_cvt(dm_pipeline).convert() + + assert len(web_pipeline_tree[PE.activities]) == 1 + assert len(web_pipeline_tree[PE.flows]) == 2 + + # 确保 web_pipeline_tree 格式正确 且能够正常转换成 engine_pipeline_tree + validate_web_pipeline_tree(web_pipeline_tree) + engine_pipeline_tree = format_web_data_to_pipeline(web_pipeline_tree) + engine_validator.validate_and_process_pipeline(engine_pipeline_tree, cycle_tolerate=False) From ccf3408832bbc1c331598543d32a4bda2b1b17b0 Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Fri, 9 May 2025 16:57:31 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=A3=80=E9=AA=8C=20#184=20#=20Reviewed,=20transactio?= =?UTF-8?q?n=20id:=2041848?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bkflow/pipeline_converter/constants.py | 12 +++++ .../data_model_to_web_pipeline/constant.py | 14 ++++-- .../data_model_to_web_pipeline/pipeline.py | 34 ++++++++++++- .../converters/json_to_data_model/constant.py | 8 +++- .../pipeline_converter/validators/constant.py | 48 +++++++++++++++++++ .../json_to_data_model/test_pipeline.py | 6 +-- 6 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 bkflow/pipeline_converter/validators/constant.py diff --git a/bkflow/pipeline_converter/constants.py b/bkflow/pipeline_converter/constants.py index 9af4324098..cd85ed7e7a 100644 --- a/bkflow/pipeline_converter/constants.py +++ b/bkflow/pipeline_converter/constants.py @@ -24,6 +24,18 @@ class ConstantTypes(str, Enum): COMPONENT_INPUTS_CONSTANT = "component_inputs" COMPONENT_OUTPUTS_CONSTANT = "component_outputs" + CUSTOM_CONSTANT_TAGS = [ + "bk_manage_user_selector.bk_user_selector", + "datetime.datetime", + "input.input", + "int.int", + "select.select", + "textarea.textarea", + "datetime_range.datetime_range", + "datatable.datatable", + "json_variable.json_variable", + ] + class DataTypes(str, Enum): DATA_MODEL = "data_model" diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py index 7289322299..4c29ebb9e9 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py @@ -1,6 +1,10 @@ # -*- coding: utf-8 -*- from bkflow.pipeline_converter.constants import ConstantTypes from bkflow.pipeline_converter.converters.base import DataModelToPipelineTreeConverter +from bkflow.pipeline_converter.validators.constant import ( + ComponentInputValidator, + ConstantValidator, +) from bkflow.pipeline_converter.validators.node import NodeTypeValidator @@ -13,13 +17,13 @@ def convert(self): class CustomConstantConverter(DataModelToPipelineTreeConverter): - validators = [NodeTypeValidator(ConstantTypes.CUSTOM_CONSTANT.value)] + validators = [NodeTypeValidator(ConstantTypes.CUSTOM_CONSTANT.value), ConstantValidator()] def convert(self): converter_data = self.source_data self.target_data = { "name": converter_data.name, - "key": converter_data.key, + "key": f"${{{converter_data.key}}}", "desc": converter_data.desc, "value": converter_data.value, "custom_type": converter_data.custom_type, @@ -37,13 +41,13 @@ def convert(self): class ComponentInputConverter(DataModelToPipelineTreeConverter): - validators = [NodeTypeValidator(ConstantTypes.COMPONENT_INPUTS_CONSTANT.value)] + validators = [NodeTypeValidator(ConstantTypes.COMPONENT_INPUTS_CONSTANT.value), ComponentInputValidator()] def convert(self): converter_data = self.source_data self.target_data = { "name": converter_data.name, - "key": converter_data.key, + "key": f"${{{converter_data.key}}}", "desc": converter_data.desc, "value": [converter_data.value], "custom_type": converter_data.custom_type, @@ -66,7 +70,7 @@ def convert(self): converter_data = self.source_data self.target_data = { "name": converter_data.name, - "key": converter_data.key, + "key": f"${{{converter_data.key}}}", "desc": converter_data.desc, "value": converter_data.value, "custom_type": converter_data.custom_type, diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py index 60b6dabdc5..5e759d285c 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/pipeline.py @@ -66,6 +66,7 @@ def convert(self) -> dict: self.target_data[PE.gateways][node.id] = gateway_data # 常量数据转换 + self.validate_constant(self.target_data[PE.activities], constants) self.target_data[PE.constants] = self.constant_converter(constants) # 连线数据转换 flows = self._generate_flows_by_nodes(nodes) @@ -98,7 +99,7 @@ def constant_converter(self, constants): ) constant_data = converter_cls(constant).convert() constant_data["index"] = index - result[constant.key] = constant_data + result[constant_data.get("key")] = constant_data return result @staticmethod @@ -158,3 +159,34 @@ def remap_condition_keys_to_outgoing(gateways_data, flows): flow_id = flow_id_map.get((gateway_id, condition_node)) new_conditions[flow_id] = {"name": condition["name"], "evaluate": condition["evaluate"]} gateway["conditions"] = new_conditions + + @staticmethod + def validate_constant(nodes, constants): + validate_types = [ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value] + + for constant in constants: + # 只检查组件输入/输出类型的常量 + if constant.type not in validate_types: + continue + + constant_name = constant.name + + for info in constant.source_info: + node_id = info.key + # 检查源节点是否存在 + if node_id not in nodes: + raise ValueError(f"常量{constant_name}的源节点{node_id}不存在") + + if constant.type == ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value: + continue + + constant_node = nodes[node_id]["component"] + code, component_file = constant.source_tag.split(".") + + # 检查组件code是否匹配 + if code != constant_node["code"]: + raise ValueError(f"常量{constant_name}的source_tag字段信息与源节点{node_id}的组件信息不匹配") + + # 检查目标字段是否存在 + if component_file not in constant_node["data"]: + raise ValueError(f"常量{constant_name}的源节点{node_id}的字段{component_file}不存在") diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py index 2143484486..bf847db69c 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py @@ -7,6 +7,10 @@ CustomConstant, SourceInfo, ) +from bkflow.pipeline_converter.validators.constant import ( + JsonComponentInputValidator, + JsonConstantValidator, +) from bkflow.pipeline_converter.validators.node import JsonNodeTypeValidator @@ -20,7 +24,7 @@ def convert(self): class CustomConstantConverter(JsonToDataModelConverter): - validators = [JsonNodeTypeValidator(ConstantTypes.CUSTOM_CONSTANT.value)] + validators = [JsonNodeTypeValidator(ConstantTypes.CUSTOM_CONSTANT.value), JsonConstantValidator()] def convert(self): self.target_data = CustomConstant( @@ -43,7 +47,7 @@ def convert(self): class ComponentInputConverter(JsonToDataModelConverter): - validators = [JsonNodeTypeValidator(ConstantTypes.COMPONENT_INPUTS_CONSTANT.value)] + validators = [JsonNodeTypeValidator(ConstantTypes.COMPONENT_INPUTS_CONSTANT.value), JsonComponentInputValidator()] def convert(self): self.target_data = ComponentInputConstant( diff --git a/bkflow/pipeline_converter/validators/constant.py b/bkflow/pipeline_converter/validators/constant.py new file mode 100644 index 0000000000..adb57b302a --- /dev/null +++ b/bkflow/pipeline_converter/validators/constant.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +from typing import Any, Dict + +from bkflow.pipeline_converter.constants import ConstantTypes +from bkflow.pipeline_converter.data_models import ComponentInputConstant, CustomConstant +from bkflow.pipeline_converter.validators.base import BaseValidator + + +class ConstantValidator(BaseValidator): + def validate(self, data: CustomConstant, *args, **kwargs): + if data.source_tag not in ConstantTypes.CUSTOM_CONSTANT_TAGS.value: + raise ValueError("The parameter source tag does not meet the requirements") + + +class ComponentInputValidator(BaseValidator): + def validate(self, data: ComponentInputConstant, *args, **kwargs): + constant_key = data.key + try: + code, tag_field = data.source_tag.split(".") + except ValueError: + raise ValueError("parameter source_tag does not conform to the required format") + + for info in data.source_info: + info_field = info.value + + if not (constant_key == info_field == tag_field): + raise ValueError("the information about the source node fields must be consistent in the parameters") + + +class JsonConstantValidator(BaseValidator): + def validate(self, data: Dict[str, Any], *args, **kwargs): + if data.get("source_tag") not in ConstantTypes.CUSTOM_CONSTANT_TAGS.value: + raise ValueError("The parameter source tag does not meet the requirements") + + +class JsonComponentInputValidator(BaseValidator): + def validate(self, data: Dict[str, Any], *args, **kwargs): + constant_key = data.get("key") + try: + code, tag_field = data.get("source_tag").split(".") + except ValueError: + raise ValueError("parameter source_tag does not conform to the required format") + + for info in data.get("source_info"): + info_field = info.get("value") + + if not (constant_key == info_field == tag_field): + raise ValueError("the information about the source node fields must be consistent in the parameters") diff --git a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py index 37439ff1f8..27ea06571b 100644 --- a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py +++ b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py @@ -333,7 +333,7 @@ def test_json_2_web_pipeline_convert_with_component_output_constant(self): { "name": "test_name", "type": ConstantTypes.CUSTOM_CONSTANT.value, - "key": "${test_name}", + "key": "test_name", "value": "test_value", "custom_type": "textarea", "source_tag": "textarea.textarea", @@ -342,7 +342,7 @@ def test_json_2_web_pipeline_convert_with_component_output_constant(self): { "name": "执行结果", "type": ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, - "key": "${_result_1}", + "key": "_result_1", "custom_type": "", "source_tag": "", "source_info": [{"key": "custom_node", "value": "_result"}], @@ -400,7 +400,7 @@ def test_json_2_web_pipeline_convert_with_component_input_constant(self): { "name": "bk_display_message", "type": ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, - "key": "${bk_display_message}", + "key": "bk_display_message", "value": "test_value", "custom_type": "", "source_tag": "bk_display.bk_display_message", From e8093697d47d15d45c7c706e30ed81ba4bd65d99 Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Mon, 12 May 2025 14:34:16 +0800 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4extra=5Finfo?= =?UTF-8?q?=E5=8F=82=E6=95=B0=20#184=20#=20Reviewed,=20transaction=20id:?= =?UTF-8?q?=2041992?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../converters/data_model_to_web_pipeline/constant.py | 2 -- .../converters/json_to_data_model/constant.py | 2 -- bkflow/pipeline_converter/data_models.py | 2 -- .../converters/json_to_data_model/test_pipeline.py | 4 +--- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py index 4c29ebb9e9..9d4a63c070 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py @@ -58,7 +58,6 @@ def convert(self): "validation": converter_data.validation, "version": converter_data.version, "plugin_code": converter_data.plugin_code, - "extra_info": converter_data.extra_info, } return self.target_data @@ -80,6 +79,5 @@ def convert(self): "source_info": SourceInfoConverter(converter_data.source_info).convert(), "validation": converter_data.validation, "plugin_code": converter_data.plugin_code, - "extra_info": converter_data.extra_info, } return self.target_data diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py index bf847db69c..6f5c6d8df0 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py @@ -59,7 +59,6 @@ def convert(self): type=ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), version=self.source_data["version"], - extra_info=self.source_data["extra_info"], ) default_optional_field = ["desc", "validation", "version", "show_type", "plugin_code"] for field in default_optional_field: @@ -82,7 +81,6 @@ def convert(self): source_tag=self.source_data["source_tag"], type=ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), - extra_info=self.source_data["extra_info"], ) default_optional_field = ["desc", "validation", "show_type", "plugin_code"] for field in default_optional_field: diff --git a/bkflow/pipeline_converter/data_models.py b/bkflow/pipeline_converter/data_models.py index 28faf77bcb..9e866af248 100644 --- a/bkflow/pipeline_converter/data_models.py +++ b/bkflow/pipeline_converter/data_models.py @@ -128,14 +128,12 @@ class CustomConstant(Constant): class ComponentInputConstant(Constant): type: str = ConstantTypes.COMPONENT_INPUTS_CONSTANT.value plugin_code: str = "" - extra_info: Dict[str, Any] class ComponentOutConstant(Constant): type: str = ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value show_type: str = "hide" plugin_code: str = "" - extra_info: Dict[str, Any] class Extensions(BaseModel): diff --git a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py index 27ea06571b..b563fae6de 100644 --- a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py +++ b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py @@ -244,7 +244,7 @@ def test_json_2_web_pipeline_convert_with_custom_constant(self): { "name": "test_name", "type": ConstantTypes.CUSTOM_CONSTANT.value, - "key": "${test_name}", + "key": "test_name", "value": "test_value", "custom_type": "textarea", "source_tag": "textarea.textarea", @@ -347,7 +347,6 @@ def test_json_2_web_pipeline_convert_with_component_output_constant(self): "source_tag": "", "source_info": [{"key": "custom_node", "value": "_result"}], "value": "", - "extra_info": {}, }, ], } @@ -406,7 +405,6 @@ def test_json_2_web_pipeline_convert_with_component_input_constant(self): "source_tag": "bk_display.bk_display_message", "version": "v1.0", "source_info": [{"key": "custom_node", "value": "bk_display_message"}], - "extra_info": {}, } ], } From 9deeb007fd836577ecf3974ce36849cac48404a9 Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Wed, 2 Jul 2025 17:41:44 +0800 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98=20#184=20#=20Reviewed,=20t?= =?UTF-8?q?ransaction=20id:=2048602?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bkflow/pipeline_converter/constants.py | 14 +++----------- .../converters/json_to_data_model/pipeline.py | 15 +++++++++------ bkflow/pipeline_converter/data_models.py | 8 ++++---- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/bkflow/pipeline_converter/constants.py b/bkflow/pipeline_converter/constants.py index cd85ed7e7a..ca5e14750f 100644 --- a/bkflow/pipeline_converter/constants.py +++ b/bkflow/pipeline_converter/constants.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from enum import Enum +from pipeline.variable_framework.models import VariableModel + class NodeTypes(str, Enum): START_EVENT = "start_event" @@ -24,17 +26,7 @@ class ConstantTypes(str, Enum): COMPONENT_INPUTS_CONSTANT = "component_inputs" COMPONENT_OUTPUTS_CONSTANT = "component_outputs" - CUSTOM_CONSTANT_TAGS = [ - "bk_manage_user_selector.bk_user_selector", - "datetime.datetime", - "input.input", - "int.int", - "select.select", - "textarea.textarea", - "datetime_range.datetime_range", - "datatable.datatable", - "json_variable.json_variable", - ] + CUSTOM_CONSTANT_TAGS = [variable.tag for variable in VariableModel.objects.filter(status=True)] class DataTypes(str, Enum): diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py b/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py index 2b26974220..e4a3a00e9d 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/pipeline.py @@ -30,7 +30,7 @@ def convert(self) -> dict: target_nodes = [] # TODO: 这块考虑抽象公共逻辑 - data_type_converter_cls_name_map = { + node_type_converter_cls_name_map = { NodeTypes.COMPONENT.value: ComponentNodeConverter.__name__, NodeTypes.END_EVENT.value: EndNodeConverter.__name__, NodeTypes.START_EVENT.value: StartNodeConverter.__name__, @@ -38,23 +38,26 @@ def convert(self) -> dict: NodeTypes.EXCLUSIVE_GATEWAY.value: ExclusiveGatewayConverter.__name__, NodeTypes.CONDITIONAL_PARALLEL_GATEWAY.value: ConditionalParallelGatewayConverter.__name__, NodeTypes.CONVERGE_GATEWAY.value: ConvergeGatewayConverter.__name__, - ConstantTypes.CUSTOM_CONSTANT.value: CustomConstantConverter.__name__, - ConstantTypes.COMPONENT_INPUTS_CONSTANT.value: ComponentInputConverter.__name__, - ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value: ComponentOutputConverter.__name__, } for node in self.source_data.get("nodes", []): converter_cls = ConverterHub.get_converter_cls( - source=self.source, target=self.target, converter_name=data_type_converter_cls_name_map[node["type"]] + source=self.source, target=self.target, converter_name=node_type_converter_cls_name_map[node["type"]] ) target_nodes.append(converter_cls(node).convert()) self.target_data.nodes = target_nodes + constant_type_converter_cls_name_map = { + ConstantTypes.CUSTOM_CONSTANT.value: CustomConstantConverter.__name__, + ConstantTypes.COMPONENT_INPUTS_CONSTANT.value: ComponentInputConverter.__name__, + ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value: ComponentOutputConverter.__name__, + } + target_constants = [] for constant in self.source_data.get("constants", []): converter_cls = ConverterHub.get_converter_cls( source=self.source, target=self.target, - converter_name=data_type_converter_cls_name_map[constant["type"]], + converter_name=constant_type_converter_cls_name_map[constant["type"]], ) converted_data = converter_cls(constant).convert() target_constants.append(converted_data) diff --git a/bkflow/pipeline_converter/data_models.py b/bkflow/pipeline_converter/data_models.py index 9e866af248..106272f553 100644 --- a/bkflow/pipeline_converter/data_models.py +++ b/bkflow/pipeline_converter/data_models.py @@ -110,13 +110,13 @@ class Constant(BaseModel): type: str # source_type key: str value: Any - version: str = "legacy" - desc: str = "" - show_type: str = "show" - validation: str = "" custom_type: str source_info: List[SourceInfo] source_tag: str + show_type: str = "show" + validation: str = "" + version: str = "legacy" + desc: str = "" class CustomConstant(Constant): From b2d677176aa012810524af266b38c916c0a6da86 Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Wed, 2 Jul 2025 18:05:12 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=85=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=8F=98=E9=87=8F=E7=B1=BB=E5=9E=8B=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=20#184=20#=20Reviewed,=20transaction=20id:=2048614?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bkflow/pipeline_converter/constants.py | 1 + bkflow/pipeline_converter/validators/constant.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/bkflow/pipeline_converter/constants.py b/bkflow/pipeline_converter/constants.py index ca5e14750f..8419c5f690 100644 --- a/bkflow/pipeline_converter/constants.py +++ b/bkflow/pipeline_converter/constants.py @@ -26,6 +26,7 @@ class ConstantTypes(str, Enum): COMPONENT_INPUTS_CONSTANT = "component_inputs" COMPONENT_OUTPUTS_CONSTANT = "component_outputs" + CUSTOM_CONSTANT_CUSTOMS = [variable.code for variable in VariableModel.objects.filter(status=True)] CUSTOM_CONSTANT_TAGS = [variable.tag for variable in VariableModel.objects.filter(status=True)] diff --git a/bkflow/pipeline_converter/validators/constant.py b/bkflow/pipeline_converter/validators/constant.py index adb57b302a..9a6d870b31 100644 --- a/bkflow/pipeline_converter/validators/constant.py +++ b/bkflow/pipeline_converter/validators/constant.py @@ -8,6 +8,8 @@ class ConstantValidator(BaseValidator): def validate(self, data: CustomConstant, *args, **kwargs): + if data.custom_type not in ConstantTypes.CUSTOM_CONSTANT_CUSTOMS.value: + raise ValueError("The parameter custom type does not meet the requirements") if data.source_tag not in ConstantTypes.CUSTOM_CONSTANT_TAGS.value: raise ValueError("The parameter source tag does not meet the requirements") @@ -29,6 +31,8 @@ def validate(self, data: ComponentInputConstant, *args, **kwargs): class JsonConstantValidator(BaseValidator): def validate(self, data: Dict[str, Any], *args, **kwargs): + if data.get("custom_type") not in ConstantTypes.CUSTOM_CONSTANT_CUSTOMS.value: + raise ValueError("The parameter custom type does not meet the requirements") if data.get("source_tag") not in ConstantTypes.CUSTOM_CONSTANT_TAGS.value: raise ValueError("The parameter source tag does not meet the requirements") From f4204ca16132b7ed4802a4d712cb48c52453615d Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Thu, 3 Jul 2025 11:13:18 +0800 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20=E6=A8=A1=E5=9E=8B=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E4=BC=98=E5=8C=96=20#184=20#=20Reviewed,=20t?= =?UTF-8?q?ransaction=20id:=2048679?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../converters/json_to_data_model/constant.py | 5 ----- bkflow/pipeline_converter/data_models.py | 5 ++++- .../converters/json_to_data_model/test_pipeline.py | 5 ----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py index 6f5c6d8df0..d708288b43 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py @@ -35,7 +35,6 @@ def convert(self): custom_type=self.source_data["custom_type"], source_tag=self.source_data["source_tag"], pre_render_make=False, - source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), ) default_optional_field = ["desc", "source_info", "validation", "is_meta", "version", "show_type"] for field in default_optional_field: @@ -54,11 +53,9 @@ def convert(self): name=self.source_data["name"], key=self.source_data["key"], value=self.source_data["value"], - custom_type=self.source_data["custom_type"], source_tag=self.source_data["source_tag"], type=ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), - version=self.source_data["version"], ) default_optional_field = ["desc", "validation", "version", "show_type", "plugin_code"] for field in default_optional_field: @@ -77,8 +74,6 @@ def convert(self): name=self.source_data["name"], key=self.source_data["key"], value=self.source_data["value"], - custom_type=self.source_data["custom_type"], - source_tag=self.source_data["source_tag"], type=ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, source_info=SourceInfoConverter(self.source_data["source_info"]).convert(), ) diff --git a/bkflow/pipeline_converter/data_models.py b/bkflow/pipeline_converter/data_models.py index 106272f553..982e2e13f5 100644 --- a/bkflow/pipeline_converter/data_models.py +++ b/bkflow/pipeline_converter/data_models.py @@ -110,7 +110,7 @@ class Constant(BaseModel): type: str # source_type key: str value: Any - custom_type: str + custom_type: str = "" source_info: List[SourceInfo] source_tag: str show_type: str = "show" @@ -120,6 +120,8 @@ class Constant(BaseModel): class CustomConstant(Constant): + custom_type: str + source_info: str = "" type: str = ConstantTypes.CUSTOM_CONSTANT.value pre_render_make: bool = False is_meta: bool = False @@ -131,6 +133,7 @@ class ComponentInputConstant(Constant): class ComponentOutConstant(Constant): + source_tag: str = "" type: str = ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value show_type: str = "hide" plugin_code: str = "" diff --git a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py index b563fae6de..0cd8337c80 100644 --- a/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py +++ b/tests/pipeline_converter/converters/json_to_data_model/test_pipeline.py @@ -248,7 +248,6 @@ def test_json_2_web_pipeline_convert_with_custom_constant(self): "value": "test_value", "custom_type": "textarea", "source_tag": "textarea.textarea", - "source_info": [], } ], } @@ -337,14 +336,11 @@ def test_json_2_web_pipeline_convert_with_component_output_constant(self): "value": "test_value", "custom_type": "textarea", "source_tag": "textarea.textarea", - "source_info": [], }, { "name": "执行结果", "type": ConstantTypes.COMPONENT_OUTPUTS_CONSTANT.value, "key": "_result_1", - "custom_type": "", - "source_tag": "", "source_info": [{"key": "custom_node", "value": "_result"}], "value": "", }, @@ -401,7 +397,6 @@ def test_json_2_web_pipeline_convert_with_component_input_constant(self): "type": ConstantTypes.COMPONENT_INPUTS_CONSTANT.value, "key": "bk_display_message", "value": "test_value", - "custom_type": "", "source_tag": "bk_display.bk_display_message", "version": "v1.0", "source_info": [{"key": "custom_node", "value": "bk_display_message"}], From d7c549f86d78d0a46b6517d62de5c8595abccf35 Mon Sep 17 00:00:00 2001 From: guohelu <19503896967@163.com> Date: Thu, 3 Jul 2025 15:39:14 +0800 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=E5=AD=97=E6=AE=B5=E6=8B=BC=E5=86=99?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BF=AE=E5=A4=8D=20#184=20#=20Reviewed,=20t?= =?UTF-8?q?ransaction=20id:=2048748?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bkflow/pipeline_converter/constants.py | 3 +++ .../converters/data_model_to_web_pipeline/constant.py | 2 +- .../converters/json_to_data_model/constant.py | 11 +++++++++-- bkflow/pipeline_converter/data_models.py | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/bkflow/pipeline_converter/constants.py b/bkflow/pipeline_converter/constants.py index 8419c5f690..2a50f5a41e 100644 --- a/bkflow/pipeline_converter/constants.py +++ b/bkflow/pipeline_converter/constants.py @@ -22,8 +22,11 @@ class NodeTypes(str, Enum): class ConstantTypes(str, Enum): + # 自定义常量 CUSTOM_CONSTANT = "custom" + # 节点输入常量 COMPONENT_INPUTS_CONSTANT = "component_inputs" + # 节点输出常量 COMPONENT_OUTPUTS_CONSTANT = "component_outputs" CUSTOM_CONSTANT_CUSTOMS = [variable.code for variable in VariableModel.objects.filter(status=True)] diff --git a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py index 9d4a63c070..9f7310647f 100644 --- a/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py +++ b/bkflow/pipeline_converter/converters/data_model_to_web_pipeline/constant.py @@ -33,7 +33,7 @@ def convert(self): "source_info": SourceInfoConverter(converter_data.source_info).convert(), "validation": converter_data.validation, "version": converter_data.version, - "pre_render_make": False, + "pre_render_mako": converter_data.pre_render_mako, "is_meta": converter_data.is_meta, } diff --git a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py index d708288b43..7b3c8355b6 100644 --- a/bkflow/pipeline_converter/converters/json_to_data_model/constant.py +++ b/bkflow/pipeline_converter/converters/json_to_data_model/constant.py @@ -34,9 +34,16 @@ def convert(self): value=self.source_data["value"], custom_type=self.source_data["custom_type"], source_tag=self.source_data["source_tag"], - pre_render_make=False, ) - default_optional_field = ["desc", "source_info", "validation", "is_meta", "version", "show_type"] + default_optional_field = [ + "desc", + "source_info", + "validation", + "is_meta", + "version", + "show_type", + "pre_render_mako", + ] for field in default_optional_field: if field not in self.source_data: continue diff --git a/bkflow/pipeline_converter/data_models.py b/bkflow/pipeline_converter/data_models.py index 982e2e13f5..4ad4437856 100644 --- a/bkflow/pipeline_converter/data_models.py +++ b/bkflow/pipeline_converter/data_models.py @@ -123,7 +123,7 @@ class CustomConstant(Constant): custom_type: str source_info: str = "" type: str = ConstantTypes.CUSTOM_CONSTANT.value - pre_render_make: bool = False + pre_render_mako: bool = False is_meta: bool = False