|
- class Api::V1::Projects::PipelinesController < Api::V1::BaseController
- before_action :require_operate_above
-
- def index
- @pipelines = Action::Pipeline.where(project_id: @project.id).order(updated_at: :desc)
- @pipelines = paginate @pipelines
- end
-
- def test_yaml
- pipeline_yaml = build_pipeline_yaml_new("test", JSON.parse(demo2.to_json))
- respond_to do |format|
- format.html { @nodes = Action::Node.all }
- # format.yaml { @nodes = Action::Node.all }
- format.yaml { render template: "api/v1/projects/pipelines/test_yaml", content_type: "text/html" }
- format.json { render_ok({ pipeline_yaml: pipeline_yaml }) }
- end
- end
-
- def create
- size = Action::Pipeline.where(pipeline_name: params[:pipeline_name], project_id: @project.id).size
- tip_exception("已经存在#{params[:pipeline_name]}流水线!") if size > 0
- @pipeline = Action::Pipeline.new(pipeline_name: params[:pipeline_name], project_id: @project.id)
- @pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
- @pipeline.branch = params[:branch] || @project.default_branch
- @pipeline.json = params[:pipeline_json].to_json
- pipeline_yaml = build_pipeline_yaml(params[:pipeline_name], params[:pipeline_json])
- tip_exception("流水线yaml内空不能为空") if pipeline_yaml.blank?
- @pipeline.yaml = pipeline_yaml
- @pipeline.save!
- sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch)
- tip_exception("#{@pipeline.file_name}已存在") if sha
- interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create"))
- tip_exception(interactor.error) unless interactor.success?
- render_ok({ id: @pipeline.id })
- end
-
- def save_yaml
- @pipeline = Action::Pipeline.new(pipeline_name: params[:pipeline_name], project_id: @project.id)
- @pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
- @pipeline.branch = params[:branch] || @project.default_branch
- @pipeline.json = params[:pipeline_json].to_json
- pipeline_yaml = build_pipeline_yaml_new(params[:pipeline_name], params[:pipeline_json])
- tip_exception("流水线yaml内空不能为空") if pipeline_yaml.blank?
- @pipeline.yaml = pipeline_yaml
- Rails.logger.info "pipeline_yaml base64=========================#{Base64.encode64(@pipeline.yaml).gsub(/\n/, '')}"
- sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch)
- interactor = sha.present? ? Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update").merge(sha: sha)) : Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create"))
- tip_exception(interactor.error) unless interactor.success?
- file = interactor.result
- render_ok({ pipeline_yaml: pipeline_yaml, pipeline_name: params[:pipeline_name], file_name: @pipeline.file_name, sha: sha.present? ? sha : file['content']['sha'] })
- end
-
- def build_yaml
- if params[:pipeline_json].present?
- pipeline_yaml = build_pipeline_yaml(params[:pipeline_name], params[:pipeline_json])
- else
- pipeline_yaml = build_test_yaml
- end
- # render plain: pipeline_yaml
- render_ok({ pipeline_yaml: pipeline_yaml })
- end
-
- def update
- @pipeline = Action::Pipeline.find(params[:id])
- @pipeline.pipeline_name = params[:pipeline_name]
- @pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
- @pipeline.branch = params[:branch] || @project.default_branch
- @pipeline.json = params[:pipeline_json].to_json
- pipeline_yaml = build_pipeline_yaml(params[:pipeline_name], params[:pipeline_json])
- tip_exception("流水线yaml内空不能为空") if pipeline_yaml.blank?
- @pipeline.yaml = pipeline_yaml
- @pipeline.save
- sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch)
- interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create").merge(sha: sha))
- tip_exception(interactor.error) unless interactor.success?
- file = interactor.result
- render_ok({ pipeline_yaml: pipeline_yaml, pipeline_name: params[:pipeline_name], file_name: @pipeline.file_name, sha: file['content']['sha'] })
- end
-
- def destroy
- @pipeline = Action::Pipeline.find(params[:id])
- if pipeline
- interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update"))
- tip_exception(interactor.error) unless interactor.success?
- @pipeline.destroy!
- end
- render_ok
- end
-
- def show
- @pipeline = Action::Pipeline.find_by(id: params[:id])
- @pipeline = Action::Pipeline.new(id: 0, pipeline_name: "test-ss", yaml: build_test_yaml) if @pipeline.blank?
- end
-
- def build_pipeline_yaml(pipeline_name, pipeline_json)
- if pipeline_json.present? && pipeline_json.present?
- @pipeline_name = pipeline_name
- params_nodes = pipeline_json["nodes"].select { |node| !["on-push", "on-schedule", "on-pull_request", "on-fork"].include?(node["name"]) }
- on_nodes = pipeline_json["nodes"].select { |node| ["on-push", "on-schedule", "on-pull_request", "on-fork"].include?(node["name"]) }
- @on_nodes = build_nodes(on_nodes)
- @steps_nodes = build_nodes(params_nodes)
- yaml = ERB.new(File.read(File.join(Rails.root, "app/views/api/v1/projects/pipelines", "build_pipeline.yaml.erb"))).result(binding)
- # 删除空行内容
- pipeline_yaml = yaml.gsub(/^\s*\n/, "")
- else
- pipeline_yaml = params[:pipeline_yaml]
- end
- Rails.logger.info "pipeline_yaml========================="
- Rails.logger.info pipeline_yaml
- pipeline_yaml
- end
-
- def build_pipeline_yaml_new(pipeline_name, pipeline_json)
- @pipeline_name = pipeline_name
- job_nodes = pipeline_json["nodes"].select { |node| node["data"]["name"].to_s.include?("job") }
- on_nodes = pipeline_json["nodes"].select { |node| ["on-push", "on-schedule", "on-pull_request", "on-fork"].include?(node["data"]["name"]) }
- @on_nodes = build_nodes(on_nodes)
- Rails.logger.info "111=========================#{@on_nodes}"
- @job_nodes = []
- job_nodes.each do |job|
- node = Action::Node.find_by(name: job["data"]["name"])
- node.label = job["data"]["label"] if job["data"]["label"].present?
- next if node.blank?
- next_edge_nodes = JSON.parse(demo2.to_json)["edges"].select { |edge| edge["source"]["cell"].include?(job["id"]) }
- node_ids = next_edge_nodes.map { |t| t["target"]["cell"] }
- next_step_node = JSON.parse(demo2.to_json)["nodes"].select { |node| node_ids.include?(node["data"]["id"]) && !node["data"]["name"].to_s.include?("job") }&.first
- node.sub_nodes = []
- get_all_child_nodes(node, next_step_node) if next_step_node.present?
- @job_nodes.push(node)
- end
- Rails.logger.info "222=========================#{@job_nodes}"
- yaml = ERB.new(File.read(File.join(Rails.root, "app/views/api/v1/projects/pipelines", "build_pipeline.yaml.erb"))).result(binding)
- pipeline_yaml = yaml.gsub(/^\s*\n/, "")
- Rails.logger.info "========================="
- Rails.logger.info pipeline_yaml
- pipeline_yaml
- end
-
- private
-
- def get_pipeline_file_sha(file_name, branch)
- file_path_uri = URI.parse(URI.encode(file_name))
- interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: branch || @project.default_branch)
- if interactor.success?
- file = interactor.result
- file['sha']
- else
- nil
- end
- end
-
- def content_params(opt)
- {
- filepath: ".gitea/workflows/#{@pipeline.pipeline_name}.yml",
- branch: @pipeline.branch,
- new_branch: @pipeline.branch,
- content: opt == "create" ? Base64.encode64(@pipeline.yaml).gsub(/\n/, '') : @pipeline.yaml,
- message: opt == "create" ? "创建流水线:#{@pipeline.pipeline_name}" : "修改流水线:#{@pipeline.pipeline_name}",
- committer: {
- email: current_user.mail,
- name: current_user.login
- },
- identifier: @project.identifier
- }
- end
-
- def build_nodes(params_nodes)
- steps_nodes = []
- params_nodes.each do |input_node|
- node = Action::Node.find_by(name: input_node["data"]["name"])
- next if node.blank?
- node.label = input_node["data"]["label"] if input_node["data"]["label"].present?
- run_values = {}
- input_values = {}
- if input_node["inputs"].present?
- input_node["inputs"].each do |input|
- if input["name"].to_s.gsub("--", "") == "run"
- run_values = run_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
- else
- input_values = input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
- end
- end
- node.run_values = run_values
- node.input_values = input_values
- end
- steps_nodes.push(node)
- end
- steps_nodes
- end
-
- def get_all_child_nodes(job_node, target_node)
- job_node.sub_nodes.push(get_node_info(target_node))
- target_edge = JSON.parse(demo2.to_json)["edges"].select { |node| node["source"]["cell"].to_s.include?(target_node["id"]) }&.first
- # 判断是否有子节点
- if target_edge.present?
- next_node = JSON.parse(demo2.to_json)["nodes"].select { |node| node["id"].include?(target_edge["target"]["cell"]) }.first
- get_all_child_nodes(job_node, next_node)
- end
- end
-
- def get_node_info(input_node)
- node = Action::Node.find_by(name: input_node["data"]["name"])
- return nil if node.blank?
- node.label = input_node["data"]["label"] if input_node["data"]["label"].present?
- run_values = {}
- input_values = {}
- if input_node["data"]["inputs"].present?
- input_node["data"]["inputs"].each do |input|
- if input["name"].to_s.gsub("--", "") == "run"
- run_values = run_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
- else
- input_values = input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
- end
- end
- node.run_values = run_values
- node.input_values = input_values
- end
- node
- end
-
- def demo2
- {
- "nodes": [
- {
- "position": {
- "x": 290,
- "y": 190
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "on-push-b2c871f-left",
- "group": "left"
- },
- {
- "id": "on-push-b2c871f-right",
- "group": "right"
- },
- {
- "id": "on-push-b2c871f-top",
- "group": "top"
- },
- {
- "id": "on-push-b2c871f-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "on-push-b2c871f",
- "data": {
- "id": 11,
- "label": "代码push事件启动",
- "name": "on-push",
- "full_name": "on-push",
- "description": "GitLink仓库push事件",
- "icon": "http://172.20.32.201:4000/api/attachments/c2f255e7-f359-4085-b5ce-1f05850ad74c",
- "action_node_types_id": 3,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "start",
- "is_mutil_link": true,
- "link_type": "job",
- "inputs": [
- {
- "id": 6,
- "name": "branches",
- "input_type": "input",
- "description": "分支名称,多个分支英文逗号隔开,如'master,dev'",
- "is_required": true
- },
- {
- "id": 7,
- "name": "paths-ignore",
- "input_type": "input",
- "description": "忽略文件,多个文件英文逗号隔开,如'**.md,**.yaml'",
- "is_required": false
- }
- ],
- "x": 673,
- "y": 495,
- "img": "http://172.20.32.201:4000/api/attachments/c2f255e7-f359-4085-b5ce-1f05850ad74c"
- },
- "zIndex": 1,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 680,
- "y": 190
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "job-ed9ed25-left",
- "group": "left"
- },
- {
- "id": "job-ed9ed25-right",
- "group": "right"
- },
- {
- "id": "job-ed9ed25-top",
- "group": "top"
- },
- {
- "id": "job-ed9ed25-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "job-ed9ed25",
- "data": {
- "id": 29,
- "label": "任务",
- "name": "job",
- "full_name": "",
- "description": "允许并行多个任务",
- "icon": "",
- "action_node_types_id": 7,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "job",
- "is_mutil_link": true,
- "link_type": "job,step",
- "inputs": [],
- "x": 1093,
- "y": 513,
- "img": ""
- },
- "zIndex": 2,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 1090,
- "y": 190
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "job-3359fd2c-left",
- "group": "left"
- },
- {
- "id": "job-3359fd2c-right",
- "group": "right"
- },
- {
- "id": "job-3359fd2c-top",
- "group": "top"
- },
- {
- "id": "job-3359fd2c-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "job-3359fd2c",
- "data": {
- "id": 29,
- "label": "任务",
- "name": "job",
- "full_name": "",
- "description": "允许并行多个任务",
- "icon": "",
- "action_node_types_id": 7,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "job",
- "is_mutil_link": true,
- "link_type": "job,step",
- "inputs": [],
- "x": 1493,
- "y": 540,
- "img": ""
- },
- "zIndex": 3,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 680,
- "y": 380
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "shell-79d5ba5d-left",
- "group": "left"
- },
- {
- "id": "shell-79d5ba5d-right",
- "group": "right"
- },
- {
- "id": "shell-79d5ba5d-top",
- "group": "top"
- },
- {
- "id": "shell-79d5ba5d-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "shell-79d5ba5d",
- "data": {
- "id": "shell-79d5ba5d",
- "label": "运行Shell脚本",
- "name": "shell",
- "full_name": "shell",
- "description": "",
- "icon": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "action_node_types_id": 4,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "step",
- "is_mutil_link": false,
- "link_type": "step",
- "inputs": [
- {
- "id": 3,
- "name": "run",
- "input_type": "input",
- "is_required": false,
- "value": "echo 111"
- }
- ],
- "x": 1190,
- "y": 662,
- "img": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "run": "echo 111"
- },
- "zIndex": 5,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 1470,
- "y": 190
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "job-7760b89e-left",
- "group": "left"
- },
- {
- "id": "job-7760b89e-right",
- "group": "right"
- },
- {
- "id": "job-7760b89e-top",
- "group": "top"
- },
- {
- "id": "job-7760b89e-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "job-7760b89e",
- "data": {
- "id": 29,
- "label": "任务",
- "name": "job",
- "full_name": "",
- "description": "允许并行多个任务",
- "icon": "",
- "action_node_types_id": 7,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "job",
- "is_mutil_link": true,
- "link_type": "job,step",
- "inputs": [],
- "x": 1909,
- "y": 552,
- "img": ""
- },
- "zIndex": 4,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 1090,
- "y": 370
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "shell-dd97c50-left",
- "group": "left"
- },
- {
- "id": "shell-dd97c50-right",
- "group": "right"
- },
- {
- "id": "shell-dd97c50-top",
- "group": "top"
- },
- {
- "id": "shell-dd97c50-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "shell-dd97c50",
- "data": {
- "id": "shell-dd97c50",
- "label": "运行Shell脚本",
- "name": "shell",
- "full_name": "shell",
- "description": "",
- "icon": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "action_node_types_id": 4,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "step",
- "is_mutil_link": false,
- "link_type": "step",
- "inputs": [
- {
- "id": 3,
- "name": "run",
- "input_type": "input",
- "is_required": false,
- "value": "echo 444"
- }
- ],
- "x": 1572,
- "y": 725,
- "img": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "run": "echo 444"
- },
- "zIndex": 7,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 680,
- "y": 560
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "shell-799aadee-left",
- "group": "left"
- },
- {
- "id": "shell-799aadee-right",
- "group": "right"
- },
- {
- "id": "shell-799aadee-top",
- "group": "top"
- },
- {
- "id": "shell-799aadee-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "shell-799aadee",
- "data": {
- "id": "shell-799aadee",
- "label": "运行Shell脚本",
- "name": "shell",
- "full_name": "shell",
- "description": "",
- "icon": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "action_node_types_id": 4,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "step",
- "is_mutil_link": false,
- "link_type": "step",
- "inputs": [
- {
- "id": 3,
- "name": "run",
- "input_type": "input",
- "is_required": false,
- "value": "echo 222"
- }
- ],
- "x": 1190,
- "y": 922,
- "img": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "run": "echo 222"
- },
- "zIndex": 6,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 1470,
- "y": 370
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "shell-1766a765-left",
- "group": "left"
- },
- {
- "id": "shell-1766a765-right",
- "group": "right"
- },
- {
- "id": "shell-1766a765-top",
- "group": "top"
- },
- {
- "id": "shell-1766a765-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "shell-1766a765",
- "data": {
- "id": "shell-1766a765",
- "label": "运行Shell脚本",
- "name": "shell",
- "full_name": "shell",
- "description": "",
- "icon": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "action_node_types_id": 4,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "step",
- "is_mutil_link": false,
- "link_type": "step",
- "inputs": [
- {
- "id": 3,
- "name": "run",
- "input_type": "input",
- "is_required": false,
- "value": "echo 666"
- }
- ],
- "x": 1986,
- "y": 702,
- "img": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "run": "echo 666"
- },
- "zIndex": 9,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 1090,
- "y": 550
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "shell-4e09400-left",
- "group": "left"
- },
- {
- "id": "shell-4e09400-right",
- "group": "right"
- },
- {
- "id": "shell-4e09400-top",
- "group": "top"
- },
- {
- "id": "shell-4e09400-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "shell-4e09400",
- "data": {
- "id": "shell-4e09400",
- "label": "运行Shell脚本",
- "name": "shell",
- "full_name": "shell",
- "description": "",
- "icon": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "action_node_types_id": 4,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "step",
- "is_mutil_link": false,
- "link_type": "step",
- "inputs": [
- {
- "id": 3,
- "name": "run",
- "input_type": "input",
- "is_required": false,
- "value": "echo 555"
- }
- ],
- "x": 1577,
- "y": 904,
- "img": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "run": "echo 555"
- },
- "zIndex": 8,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- },
- {
- "position": {
- "x": 680,
- "y": 760
- },
- "size": {
- "width": 212,
- "height": 48
- },
- "view": "react-shape-view",
- "shape": "data-processing-dag-node",
- "ports": {
- "groups": {
- "top": {
- "position": {
- "name": "top",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "bottom": {
- "position": {
- "name": "bottom",
- "args": {
- "dx": 0
- }
- },
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "left": {
- "position": "left",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- },
- "right": {
- "position": "right",
- "attrs": {
- "circle": {
- "r": 4,
- "magnet": true,
- "strokeWidth": 1,
- "fill": "#fff",
- "stroke": "#85A5FF"
- }
- }
- }
- },
- "items": [
- {
- "id": "shell-5cec9ec-left",
- "group": "left"
- },
- {
- "id": "shell-5cec9ec-right",
- "group": "right"
- },
- {
- "id": "shell-5cec9ec-top",
- "group": "top"
- },
- {
- "id": "shell-5cec9ec-bottom",
- "group": "bottom"
- }
- ]
- },
- "id": "shell-5cec9ec",
- "data": {
- "id": "shell-5cec9ec",
- "label": "运行Shell脚本",
- "name": "shell",
- "full_name": "shell",
- "description": "",
- "icon": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "action_node_types_id": 4,
- "yaml": "",
- "sort_no": 0,
- "use_count": 0,
- "node_type": "step",
- "is_mutil_link": false,
- "link_type": "step",
- "inputs": [
- {
- "id": 3,
- "name": "run",
- "input_type": "input",
- "is_required": false,
- "value": "echo 333"
- }
- ],
- "x": 1189,
- "y": 1082,
- "img": "http://172.20.32.201:4000/api/attachments/1d739f94-4e5e-41b8-be7b-13482a099c76",
- "run": "echo 333"
- },
- "zIndex": 10,
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "x": "100%",
- "y": 0
- }
- }
- ]
- }
- }
- ],
- "edges": [
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "9cd9fab0-875a-4ddc-9d32-06fb5abcd986",
- "zIndex": -1,
- "source": {
- "cell": "on-push-b2c871f",
- "port": "on-push-b2c871f-right"
- },
- "target": {
- "cell": "job-ed9ed25",
- "port": "job-ed9ed25-left"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "32fee66b-377e-49a6-9f5c-b6a7cb78b4f0",
- "zIndex": -1,
- "source": {
- "cell": "job-ed9ed25",
- "port": "job-ed9ed25-right"
- },
- "target": {
- "cell": "job-3359fd2c",
- "port": "job-3359fd2c-left"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "84b37c54-b347-4ecb-8e7d-f338bb83c503",
- "zIndex": -1,
- "source": {
- "cell": "job-3359fd2c",
- "port": "job-3359fd2c-right"
- },
- "target": {
- "cell": "job-7760b89e",
- "port": "job-7760b89e-left"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "1703563e-2233-4d23-89ec-ed61f4243791",
- "zIndex": -1,
- "source": {
- "cell": "job-ed9ed25",
- "port": "job-ed9ed25-bottom"
- },
- "target": {
- "cell": "shell-79d5ba5d",
- "port": "shell-79d5ba5d-top"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "0be52bf9-8be4-43a9-aaca-1632eaf450ce",
- "zIndex": -1,
- "source": {
- "cell": "shell-79d5ba5d",
- "port": "shell-79d5ba5d-bottom"
- },
- "target": {
- "cell": "shell-799aadee",
- "port": "shell-799aadee-top"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "5b9800bd-5486-4b30-9142-49e6c5a2f78b",
- "zIndex": -1,
- "source": {
- "cell": "job-3359fd2c",
- "port": "job-3359fd2c-bottom"
- },
- "target": {
- "cell": "shell-dd97c50",
- "port": "shell-dd97c50-top"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "0b01ccf2-0ac9-48d5-a5d1-34a4ccc3f1f7",
- "zIndex": -1,
- "source": {
- "cell": "shell-dd97c50",
- "port": "shell-dd97c50-bottom"
- },
- "target": {
- "cell": "shell-4e09400",
- "port": "shell-4e09400-top"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "c10ada7b-ada5-4970-b05d-ea31b97c1408",
- "zIndex": -1,
- "source": {
- "cell": "job-7760b89e",
- "port": "job-7760b89e-bottom"
- },
- "target": {
- "cell": "shell-1766a765",
- "port": "shell-1766a765-top"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- },
- {
- "shape": "data-processing-curve",
- "inherit": "edge",
- "connector": {
- "name": "rounded",
- "args": {
- "radius": 10
- }
- },
- "router": {
- "name": "manhattan"
- },
- "attrs": {
- "line": {
- "strokeDasharray": "0"
- }
- },
- "id": "78909862-8e2a-4750-8b5c-c621a7c327ba",
- "zIndex": -1,
- "source": {
- "cell": "shell-799aadee",
- "port": "shell-799aadee-bottom"
- },
- "target": {
- "cell": "shell-5cec9ec",
- "port": "shell-5cec9ec-top"
- },
- "tools": {
- "items": [
- {
- "name": "button-remove",
- "args": {
- "distance": -40
- }
- }
- ]
- }
- }
- ]
- }
- end
-
- end
|