diff --git a/app/controllers/api/pm/pipelines_controller.rb b/app/controllers/api/pm/pipelines_controller.rb index 3f7f752e3..729ef175e 100644 --- a/app/controllers/api/pm/pipelines_controller.rb +++ b/app/controllers/api/pm/pipelines_controller.rb @@ -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) diff --git a/app/controllers/api/v1/projects/actions/runs_controller.rb b/app/controllers/api/v1/projects/actions/runs_controller.rb index 9119b73e4..d14ad7e91 100644 --- a/app/controllers/api/v1/projects/actions/runs_controller.rb +++ b/app/controllers/api/v1/projects/actions/runs_controller.rb @@ -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("?") diff --git a/app/controllers/api/v1/projects/pipelines_controller.rb b/app/controllers/api/v1/projects/pipelines_controller.rb index 558da2a9f..dfd54308b 100644 --- a/app/controllers/api/v1/projects/pipelines_controller.rb +++ b/app/controllers/api/v1/projects/pipelines_controller.rb @@ -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 diff --git a/app/controllers/concerns/api/action_validator_helper.rb b/app/controllers/concerns/api/action_validator_helper.rb index 7bc6c7695..f0e7ae752 100644 --- a/app/controllers/concerns/api/action_validator_helper.rb +++ b/app/controllers/concerns/api/action_validator_helper.rb @@ -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