同步工厂优化过的流水线代码

This commit is contained in:
xxq250 2026-05-26 14:38:54 +08:00
parent cdc03e5e6d
commit 4f59fb7e2f
4 changed files with 74 additions and 51 deletions

View File

@ -8,9 +8,15 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
tip_exception('没有查看组织的权限')
end
@project_ids = @owner.projects.ids
project_gpids = @owner.projects.pluck(:gpid)
if params[:project_ids].present?
@project_ids = params[:project_ids].split(",")
end
projects = Project.where(id: @project_ids)
projects = projects.where(is_public: ActiveModel::Type::Boolean.new.cast(params[:is_public])) if params[:is_public].present?
project_gpids = projects.pluck(:gpid)
@project_ids = projects.ids
action_runs = Gitea::ActionRun.where(owner_id: @owner.gitea_uid)
group_data = action_runs.where(status: [1,2]).group(:workflow_id, :status).count
group_data = action_runs.where(status: [1,2]).group(:workflow_id, :status, :repo_id).count
pipelines = Action::Pipeline.where(project_id: @project_ids).order(updated_at: :desc)
run_files = Gitea::ActionRun.select(:workflow_id, :repo_id).where(owner_id: @owner.gitea_uid).group(:workflow_id, :repo_id)
db_files = pipelines.pluck(:file_name)
@ -19,23 +25,25 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
file = file_info.workflow_id
project = Project.find_by(gpid: file_info.repo_id)
next if project.blank?
# unless db_files.include?(".gitea/workflows/#{file}")
# pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
# file_name: ".gitea/workflows/#{file}",
# branch: project.default_branch,
# disable: false,
# project_id: project.id)
# interactor = Repositories::EntriesInteractor.call(@owner, project.identifier, ".gitea/workflows/#{file}", ref: project.default_branch)
# if interactor.success?
# pipeline.yaml = decode64_content(interactor.result, @owner, project.repository, project.default_branch, nil)
# file = interactor.result
# pipeline.sha = file['content']['sha']
# end
# pipeline.user_id = current_user.id
# pipeline.save
# # 导入的流水线统一先禁用
# $gitea_hat_client.post_repos_actions_disable(project&.owner&.login, project&.identifier, {query: {workflow: file}}) rescue nil
# end
if params[:generate_actions].present?
unless db_files.include?(".gitea/workflows/#{file}")
pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
file_name: ".gitea/workflows/#{file}",
branch: project.default_branch,
disable: false,
project_id: project.id)
interactor = Repositories::EntriesInteractor.call(@owner, project.identifier, ".gitea/workflows/#{file}", ref: project.default_branch)
if interactor.success?
pipeline.yaml = decode64_content(interactor.result, @owner, project.repository, project.default_branch, nil)
file = interactor.result
pipeline.sha = file['content']['sha']
end
pipeline.user_id = current_user.id
pipeline.save
# 导入的流水线统一先禁用
# $gitea_hat_client.post_repos_actions_disable(project&.owner&.login, project&.identifier, {query: {workflow: file}}) rescue nil
end
end
last_action_run = action_runs.where(repo_id: project.gpid).where(workflow_id: file).order(updated: :desc).first
last_action_run_json = last_action_run.present? ? {
id: last_action_run.id,
@ -43,9 +51,9 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
title: last_action_run.title,
index: last_action_run.index,
status: last_action_run.status,
started: last_action_run.started,
stopped: last_action_run.stopped,
length: last_action_run.stopped-last_action_run.started,
started: last_action_run.started.zero? ? Time.now.to_i : last_action_run.started,
stopped: last_action_run.stopped.zero? ? Time.now.to_i : last_action_run.stopped,
length: last_action_run.stopped.zero? ? 0 : last_action_run.stopped-last_action_run.started,
created: last_action_run.created,
updated: last_action_run.updated,
} : {}
@ -54,12 +62,12 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
success = 0
failure = 0
group_data.each do |k,v|
total += v if k[0] == file
success += v if k[0] == file && k[1] == 1
failure += v if k[0] == file && k[1] == 2
total += v if k[0] == file && k[2] == file_info.repo_id
success += v if k[0] == file && k[1] == 1 && k[2] == file_info.repo_id
failure += v if k[0] == file && k[1] == 2 && k[2] == file_info.repo_id
end
@run_result << {
repo_id: last_action_run.repo_id,
repo_id: last_action_run&.repo_id,
filename: ".gitea/workflows/#{file}",
total: total,
success: success,
@ -68,8 +76,8 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
end
# Rails.logger.info("@run_result======#{@run_result}")
@disabled_workflows = Gitea::RepoUnit.where(repo_id: project_gpids, type: 10).where("config is not null")
@pipelines = Action::Pipeline.select("distinct project_id,max(updated_at) as updated_at")
.where(project_id: @project_ids).group(:project_id).order("updated_at desc")
@pipelines = Action::Pipeline.select("distinct project_id,max(updated_at) as updated_at, max(created_at) as created_at")
.where(project_id: @project_ids).group(:project_id).order("created_at desc")
@pipelines = @pipelines.where("pipeline_name like ?", "%#{params[:pipeline_name]}%") if params[:pipeline_name].present?
@pipelines = @pipelines.where(pipeline_type: params[:pipeline_type]) if params[:pipeline_type].present?
@pipelines = kaminari_paginate(@pipelines)

View File

@ -1,10 +1,10 @@
class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::BaseController
def index
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue []
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows", {query: {ref: params[:ref]}}) rescue []
@has_file = @files.select { |i| i['name'] == params[:workflow] }.present?
if @has_file
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token)
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit, ref: params[:ref]}, current_user&.gitea_token)
@begin_num = (page.to_i - 1) * limit.to_i
end
end
@ -12,7 +12,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
def create
return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
return render_error("请输入正确的分支!") if params[:ref].blank?
gitea_result = $gitea_hat_client.post_repos_actions_runs_by_owner_repo(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow], ref: params[:ref]}})
gitea_result = $gitea_hat_client.post_repos_actions_runs_by_owner_repo(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow], ref: params[:ref], access_token: current_user.gitea_token}})
if gitea_result
render_ok
else
@ -22,7 +22,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
def rerun
return render_error("请输入正确的流水线记录ID") if params[:run_id].blank?
gitea_result = $gitea_hat_client.post_repos_actions_runs_rerun_by_owner_repo_run(@project&.owner&.login, @project&.identifier, params[:run_id]) rescue nil
gitea_result = $gitea_hat_client.post_repos_actions_runs_rerun_by_owner_repo_run(@project&.owner&.login, @project&.identifier, params[:run_id], {query: {access_token: current_user.gitea_token}}) rescue nil
if gitea_result
render_ok
else
@ -33,7 +33,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
def job_rerun
return render_error("请输入正确的流水线记录ID") if params[:run_id].blank?
return render_error("请输入正确的流水线任务ID") if params[:job].blank?
gitea_result = $gitea_hat_client.post_repos_actions_runs_jobs_rerun_by_owner_repo_run_job(@project&.owner&.login, @project&.identifier, params[:run_id], params[:job]) rescue nil
gitea_result = $gitea_hat_client.post_repos_actions_runs_jobs_rerun_by_owner_repo_run_job(@project&.owner&.login, @project&.identifier, params[:run_id], params[:job], {query: {access_token: current_user.gitea_token}}) rescue nil
if gitea_result
render_ok
else
@ -51,7 +51,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
domain = GiteaService.gitea_config[:domain]
api_url = GiteaService.gitea_config[:hat_base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/actions/runs/#{URI.escape(params[:run_id])}/jobs/#{URI.escape(params[:job])}/logs"
url = "/repos/#{@owner.login}/#{@repository.identifier}/actions/runs/#{CGI.escape(params[:run_id])}/jobs/#{CGI.escape(params[:job])}/logs"
file_path = [domain, api_url, url].join
file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("?")

View File

@ -7,7 +7,7 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
pipelines = Action::Pipeline.where(project_id: @project.id).order(updated_at: :desc)
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue []
@action_runs = Gitea::ActionRun.where(repo_id: @project.gpid)
group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status).count
group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status, :repo_id).count
db_files = pipelines.pluck(:file_name)
@run_result = []
@files.map { |i| i['name'] }.each do |file|
@ -45,9 +45,9 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
success = 0
failure = 0
group_data.each do |k,v|
total += v if k[0] == file
success += v if k[0] == file && k[1] == 1
failure += v if k[0] == file && k[1] == 2
total += v if k[0] == file && k[2] == @project.gpid
success += v if k[0] == file && k[1] == 1 && k[2] == @project.gpid
failure += v if k[0] == file && k[1] == 2 && k[2] == @project.gpid
end
@run_result << {
filename: ".gitea/workflows/#{file}",
@ -74,7 +74,8 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
end
def create
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id)
branch = params[:branch] || @project.default_branch
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id, branch: branch)
if @pipeline.pipeline_name != params[:pipeline_name]
has_pipeline = Action::Pipeline.where(pipeline_name: params[:pipeline_name], project_id: @project.id).where.not(id: @pipeline.id)
tip_exception("已经存在#{params[:pipeline_name]}流水线!") if has_pipeline.present?
@ -92,25 +93,29 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
tip_exception(interactor.error) unless interactor.success?
end
end
else
has_pipeline = Action::Pipeline.where(pipeline_name: params[:pipeline_name], project_id: @project.id)
tip_exception("已经存在#{params[:pipeline_name]}流水线!") if has_pipeline.present?
end
@pipeline.user_id = current_user.id
@pipeline.pipeline_name = params[:pipeline_name]
@pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
@pipeline.branch = params[:branch] || @project.default_branch
@pipeline.branch = branch
@pipeline.is_graphic_design = params[:pipeline_type] == 2 ? true : false
@pipeline.pipeline_type = params[:pipeline_type] if params[:pipeline_type].present?
@pipeline.save!
end
def save_yaml
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id)
branch = params[:branch] || @project.default_branch
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id, branch: branch)
@pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
@pipeline.branch = params[:branch] if params[:branch].present?
@pipeline.json = params[:pipeline_json].to_json if params[:pipeline_json].present?
@pipeline.pipeline_name = params[:pipeline_name] if params[:pipeline_name].present?
pipeline_yaml = params[:pipeline_yaml].present? ? params[:pipeline_yaml] : build_pipeline_yaml_new(@pipeline.pipeline_name, params[:pipeline_json])
tip_exception("流水线yaml内空不能为空") if pipeline_yaml.blank?
result = validate_string(pipeline_yaml)
result = validate_string(pipeline_yaml, @pipeline.branch, @project.default_branch)
unless result[:valid]
tip_exception(result[:errors].join(","))
end
@ -118,11 +123,11 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
#Rails.logger.info "pipeline_yaml base64=========================#{Base64.encode64(@pipeline.yaml).gsub(/\n/, '')}"
sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch)
#Rails.logger.info "content_params=========#{content_params("create")}"
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"))
interactor = sha.present? ? Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update").merge(sha: sha, from_path: ".gitea/workflows/#{@pipeline.pipeline_name}.yml")) : Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create"))
tip_exception(interactor.error) unless interactor.success?
file = interactor.result
@pipeline.user_id = current_user.id if @pipeline.user_id.blank?
@pipeline.pipeline_type = @pipeline.json.present? ? 2 : 1
@pipeline.pipeline_type = params[:pipeline_json].present? ? 2 : 1
@pipeline.sha = sha.present? ? sha : file['content']['sha']
@pipeline.save
render_ok({ pipeline_yaml: pipeline_yaml, pipeline_name: @pipeline.pipeline_name, file_name: @pipeline.file_name, sha: sha.present? ? sha : file['content']['sha'] })
@ -306,16 +311,22 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
node.node_id = input_node["id"] if input_node["id"].present?
run_values = {}
input_values = {}
env_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"]}" })
if input["type"] == "Action::NodeInputs::Env"
env_input_values = env_input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
else
input_values = input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
end
end
end
node.run_values = run_values
node.input_values = input_values
node.env_input_values = env_input_values
end
node
end

View File

@ -4,10 +4,10 @@ require 'json'
module Api::ActionValidatorHelper
extend ActiveSupport::Concern
def validate_string(yaml_string)
def validate_string(yaml_string, branch, default_branch)
begin
yaml_content = YAML.safe_load(yaml_string)
validate_content(yaml_content)
validate_content(yaml_content, branch, default_branch)
rescue Psych::SyntaxError => e
{ valid: false, errors: ["YAML语法错误: #{e.message}"] }
rescue => e
@ -15,7 +15,7 @@ module Api::ActionValidatorHelper
end
end
def validate_content(data)
def validate_content(data, branch, default_branch)
errors = []
warnings = []
@ -23,7 +23,7 @@ module Api::ActionValidatorHelper
errors.concat(validate_basic_structure(data))
# 触发器验证
# errors.concat(validate_trigger(data))
errors.concat(validate_trigger(data, branch, default_branch))
# 任务验证
errors.concat(validate_job(data))
@ -68,9 +68,10 @@ module Api::ActionValidatorHelper
errors
end
def validate_trigger(data)
def validate_trigger(data, branch, default_branch)
errors = []
Rails.logger.info "data==#{data}"
Rails.logger.info "data==true#{data[true]}"
if data[true]
if data[true]['push']
unless data[true]['push'].key?('branches')
@ -81,6 +82,9 @@ module Api::ActionValidatorHelper
errors << "push触发器缺少paths-ignore配置"
end
end
if data[true]['schedule'] && branch != default_branch
errors << "只有#{default_branch}分支支持定时触发器"
end
end
errors