diff --git a/app/controllers/api/pm/dashboards_controller.rb b/app/controllers/api/pm/dashboards_controller.rb index 2798c3c52..36e361079 100644 --- a/app/controllers/api/pm/dashboards_controller.rb +++ b/app/controllers/api/pm/dashboards_controller.rb @@ -20,6 +20,7 @@ class Api::Pm::DashboardsController < Api::Pm::BaseController pm_issue_types = params[:pm_issue_types].split(",") rescue [] @all_issues = Issue.where(pm_project_id: pm_project_ids, pm_issue_type: pm_issue_types) @issues = @all_issues.joins(:issue_participants).where(issue_participants: {participant_id: current_user.id}) + @issues = @issues.where.not(status_id: 5) if params[:category] == "opened" @issues = kaminari_paginate(@issues.distinct.pm_includes) @my_assign_requirements_count = @all_issues.where(pm_issue_type: 1).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size diff --git a/app/controllers/api/v1/projects/actions/actions_controller.rb b/app/controllers/api/v1/projects/actions/actions_controller.rb index cc80b68de..65fb8139d 100644 --- a/app/controllers/api/v1/projects/actions/actions_controller.rb +++ b/app/controllers/api/v1/projects/actions/actions_controller.rb @@ -4,7 +4,9 @@ class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions @files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue [] @workflows = params[:workflows].split(",") if params[:workflows].present? @action_runs = Gitea::ActionRun.where(repo_id: @project.gpid) - @action_runs = @action_runs.where(id: params[:ids].split(",")) if params[:ids].present? + disabled_config = Gitea::RepoUnit.where(repo_id: @project.gpid, type: 10)&.first&.config + disabled_workflows = disabled_config.present? ? JSON.parse(disabled_config)["DisabledWorkflows"] : [] + @action_runs = @action_runs.where(id: params[:ids].split(",")) if params[:ids].present? @action_runs = @action_runs.where(workflow_id: @workflows) if params[:workflows].present? group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status).count @result = [] @@ -14,6 +16,7 @@ class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions end last_action_run = @action_runs.where(workflow_id: file).order(updated: :desc).first last_action_run_json = last_action_run.present? ? { + pipeline_id: Action::Pipeline.find_by(pipeline_name: file, project_id: @project.id), id: last_action_run.id, schedule: last_action_run.schedule_id > 0, title: last_action_run.title, @@ -47,6 +50,7 @@ class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions end @result << { filename: file, + disabled: disabled_workflows.include?(file.to_s), name: file.to_s.gsub(".yml","").gsub(".yaml","") , branch: last_action_run.present? ? last_action_run.ref.gsub("refs/heads/","") : @project.default_branch, pipeline_type: pipeline_type, diff --git a/app/controllers/api/v1/projects/pipelines_controller.rb b/app/controllers/api/v1/projects/pipelines_controller.rb index 1e1be4dc8..5aa62caab 100644 --- a/app/controllers/api/v1/projects/pipelines_controller.rb +++ b/app/controllers/api/v1/projects/pipelines_controller.rb @@ -1,7 +1,61 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController + include RepositoriesHelper before_action :require_operate_above, except: [:upload_results, :run_results] def index + 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 + db_files = pipelines.pluck(:file_name) + @run_result = [] + @files.map { |i| i['name'] }.each do |file| + unless db_files.include?(".gitea/workflows/#{file}") + disabled_config = Gitea::RepoUnit.where(repo_id: @project.gpid, type: 10)&.first&.config + disabled_workflows = disabled_config.present? ? JSON.parse(disabled_config)["DisabledWorkflows"] : [] + pipeline = Action::Pipeline.new(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""), + file_name: ".gitea/workflows/#{file}", + branch: @project.default_branch, + is_graphic_design: false, + disable: disabled_workflows.include?(file.to_s), + 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) + end + pipeline.user_id = current_user.id + pipeline.save + end + last_action_run = @action_runs.where(workflow_id: file).order(updated: :desc).first + last_action_run_json = last_action_run.present? ? { + id: last_action_run.id, + schedule: last_action_run.schedule_id > 0, + 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, + created: last_action_run.created, + updated: last_action_run.updated, + } : {} + + total = 0 + 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 + end + @run_result << { + filename: ".gitea/workflows/#{file}", + total: total, + success: success, + failure: failure + }.merge(last_action_run_json) + end + Rails.logger.info("@run_result======#{@run_result}") @pipelines = Action::Pipeline.where(project_id: @project.id).order(updated_at: :desc) @pipelines = paginate @pipelines end @@ -17,29 +71,32 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController 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 = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id) + 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? + if @pipeline.yaml.present? + sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch) + if sha.present? + interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update", params[:pipeline_name]).merge(sha: sha, from_path: "#{@pipeline.pipeline_name}")) + tip_exception(interactor.error) unless interactor.success? + end + end + end + @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.is_graphic_design = params[:pipeline_type] == 2 ? true : false + @pipeline.pipeline_type = params[:pipeline_type] if params[:pipeline_type].present? @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 = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(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]) + @pipeline.json = params[:pipeline_json].to_json if params[:pipeline_json].present? + pipeline_yaml = params[:pipeline_yaml].present? ? params[: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/, '')}" @@ -47,6 +104,7 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController 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 + @pipeline.pipeline_type = @pipeline.json.present? ? 2 : 1 @pipeline.save render_ok({ pipeline_yaml: pipeline_yaml, pipeline_name: params[:pipeline_name], file_name: @pipeline.file_name, sha: sha.present? ? sha : file['content']['sha'] }) end @@ -81,14 +139,16 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController def destroy @pipeline = Action::Pipeline.find(params[:id]) if @pipeline - interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, del_content_params.merge(identifier: @project.identifier)) - tip_exception(interactor.error) unless interactor.success? + sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch) + if sha.present? + interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, del_content_params(sha).merge(identifier: @project.identifier)) + tip_exception(interactor.error) unless interactor.success? + end @pipeline.destroy! end render_ok end - def upload_results tip_exception("参数错误") if params[:owner].blank? || params[:repo].blank? || params[:run_id].blank? @project, @owner = Project.find_with_namespace(params[:owner], params[:repo]) @@ -109,7 +169,7 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController tip_exception("参数错误") if params[:owner].blank? || params[:repo].blank? || params[:run_id].blank? @project, @owner = Project.find_with_namespace(params[:owner], params[:repo]) tip_exception("项目不存在") if @project.blank? - results = Action::PipelineResult.where(run_id: params[:run_id], project_id: @project.id) + results = Action::PipelineResult.where(run_id: params[:run_id], project_id: @project.id) render_ok(run_results: results.as_json(only: %i[id run_id job_name job_show_type job_result])) end @@ -158,9 +218,9 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController end end - def content_params(opt) + def content_params(opt, rename_file=nil) { - filepath: ".gitea/workflows/#{@pipeline.pipeline_name}.yml", + filepath: ".gitea/workflows/#{rename_file.present? ? rename_file : @pipeline.pipeline_name}.yml", branch: @pipeline.branch, new_branch: @pipeline.branch, content: opt == "create" ? Base64.encode64(@pipeline.yaml).gsub(/\n/, '') : @pipeline.yaml, @@ -173,12 +233,12 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController } end - def del_content_params(opt) + def del_content_params(sha) { filepath: ".gitea/workflows/#{@pipeline.pipeline_name}.yml", base64_filepath: Base64.encode64(".gitea/workflows/#{@pipeline.pipeline_name}.yml").gsub(/\n/, ''), branch: @pipeline.branch, - sha: get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch) + sha: sha } end diff --git a/app/models/gitea/repo_unit.rb b/app/models/gitea/repo_unit.rb new file mode 100644 index 000000000..c83712b0e --- /dev/null +++ b/app/models/gitea/repo_unit.rb @@ -0,0 +1,9 @@ +class Gitea::RepoUnit < Gitea::Base + self.inheritance_column = nil # FIX The single-table inheritance mechanism failed + # establish_connection :gitea_db + + self.table_name = "repo_unit" + + # belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true + +end diff --git a/app/views/api/v1/projects/pipelines/create.json.jbuilder b/app/views/api/v1/projects/pipelines/create.json.jbuilder new file mode 100644 index 000000000..83b3aabd9 --- /dev/null +++ b/app/views/api/v1/projects/pipelines/create.json.jbuilder @@ -0,0 +1,4 @@ +json.status 0 +json.message "success" +json.extract! @pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, :pipeline_type, + :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at \ No newline at end of file diff --git a/app/views/api/v1/projects/pipelines/index.json.jbuilder b/app/views/api/v1/projects/pipelines/index.json.jbuilder index 7c3f2a405..fb0a74393 100644 --- a/app/views/api/v1/projects/pipelines/index.json.jbuilder +++ b/app/views/api/v1/projects/pipelines/index.json.jbuilder @@ -1,8 +1,9 @@ json.status 0 json.message "success" -json.pipelines @pipelines.each do |pip| - json.extract! pip, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, +json.pipelines @pipelines.each do |pipeline| + json.extract! pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at - # json.project + json.pipeline_type pipeline.pipeline_type + json.run_data @run_result.select { |result| result[:filename] == pipeline.file_name }.first end diff --git a/app/views/api/v1/projects/pipelines/show.json.jbuilder b/app/views/api/v1/projects/pipelines/show.json.jbuilder index d82015ade..996bd0556 100644 --- a/app/views/api/v1/projects/pipelines/show.json.jbuilder +++ b/app/views/api/v1/projects/pipelines/show.json.jbuilder @@ -1,5 +1,4 @@ json.status 0 json.message "success" -json.extract! @pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, +json.extract! @pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, :pipeline_type, :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at -# json.project \ No newline at end of file diff --git a/config/puma.rb b/config/puma.rb index e31c00feb..7b1c435c7 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -4,12 +4,12 @@ # the maximum value specified for Puma. Default is set to 5 threads for minimum # and maximum; this matches the default thread size of Active Record. # -threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 8 } threads threads_count, threads_count # Specifies the `port` that Puma will listen on to receive requests; default is 3000. # -port ENV.fetch("PORT") { 3000 } +port ENV.fetch("PORT") { 4000 } # Specifies the `environment` that Puma will run in. # @@ -21,7 +21,8 @@ environment ENV.fetch("RAILS_ENV") { "development" } # Workers do not work on JRuby or Windows (both of which do not support # processes). # -# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +workers ENV.fetch("WEB_CONCURRENCY") { 8 } # Use the `preload_app!` method when specifying a `workers` number. # This directive tells Puma to first boot the application and load code diff --git a/db/migrate/202503180515147_add_pipelines_type.rb b/db/migrate/202503180515147_add_pipelines_type.rb new file mode 100644 index 000000000..2f34900c0 --- /dev/null +++ b/db/migrate/202503180515147_add_pipelines_type.rb @@ -0,0 +1,5 @@ +class AddPipelinesType < ActiveRecord::Migration[5.2] + def change + add_column :action_pipelines, :pipeline_type, :integer, :default => 1 + end +end