diff --git a/api_document.md b/api_document.md index b39eb25ad..fa536b9ec 100644 --- a/api_document.md +++ b/api_document.md @@ -3520,6 +3520,7 @@ http://localhost:3000/api/Jason/forge/builds | jq |page |否|string |页数,第几页 | |limit |否|string |每页多少条数据,默认20条 | |search |是|string |构建状态条件过滤; 值说明:pending: 准备中,failure: 构建失败,running: 运行中,error:构建失败(.trustie-pipeline.yml文件错误),success: 构建成功,killed: 撤销构建 | +|branch |是|string |分支 | *返回参数说明:* @@ -4042,13 +4043,15 @@ http://localhost:3000/api/ci/pipelines/list.json?identifier="xxx" | jq *返回参数说明:* -| 参数名 | 类型 | 说明 | -| ------------- | ------ | --------------- | -| id | int | 流水线id | -| pipeline_name | string | 流水线名称 | -| file_name | string | 流水线文件名 | -| created_at | string | 创建时间 | -| sync | int | 是否同步到gitea | +| 参数名 | 类型 | 说明 | +| ----------------- | ------ | ------------ | +| id | int | 流水线id | +| pipeline_name | string | 流水线名称 | +| file_name | string | 流水线文件名 | +| branch | string | 触发分支 | +| event | string | 触发事件 | +| last_build_time | string | 上次构建时间 | +| last_build_status | string | 上次构建状态 | 返回值 @@ -4056,11 +4059,15 @@ http://localhost:3000/api/ci/pipelines/list.json?identifier="xxx" | jq { "pipelines": [ { - "id": 1, - "pipeline_name": "2020-01-08 流水线", - "file_name": ".trustie.pipeline.yaml", - "created_at": "2021-01-08 04:16:24", - "updated_at": "2021-01-08 04:16:24" + "id": 65, + "pipeline_name": "流水线 2021-01-25", + "file_name": ".drone.yml", + "branch": "develop", + "event": "push", + "sha": "19fb5eb28603a4a1ec799ad44c1a3ef69d5c2cd0", + "identifier": "trustieTest", + "last_build_status": "success", + "last_build_time": "2021-01-25 15:54:22" } ] } @@ -4082,7 +4089,10 @@ curl --location --request POST 'http://localhost:3000/api/ci/pipelines' \ --data-raw ' { "pipeline_name": "流水线 2021-01-12", "file_name": ".trustie.pipeline.yaml", - "identifier": "xxx" + "repo": "xxx", + "owner": "xxx", + "branch": "master", + "event": "push" }' ``` @@ -4092,7 +4102,10 @@ curl --location --request POST 'http://localhost:3000/api/ci/pipelines' \ | ------------- | ---- | ------ | ---------------------------------------------- | | pipeline_name | 是 | string | 流水线名称 | | file_name | 是 | string | 文件名称(默认初始值:.trustie.pipeline.yaml) | -| identifier | 是 | string | 项目identifier | +| repo | 是 | string | 项目identifier | +| owner | 是 | string | 项目的owner | +| branch | 否 | string | 分支名称, branch必须存在一个 | +| event | 是 | string | 触发事件,可多选,多个逗号隔开 | *返回参数说明:* @@ -4633,6 +4646,192 @@ http://localhost:3000/api/ci/templates/templates_by_stage.json?stage_type=build ------ +#### 模板列表查询 + +``` +GET /api/ci/templates/list.json?limit=10&page=1&name=&stage_type=customize +``` + +*示例* + +```bash +curl --location --request GET 'http://localhost:3000/api/ci/templates/list.json?limit=10&page=1&name=&stage_type=customize' +``` + +*请求参数说明:* + +| 参数名 | 必选 | 类型 | 说明 | +| ---------- | ---- | ------ | ----------------------------------------- | +| stage_type | 是 | string | 阶段类型:init/build/deploy/customize/all | +| limit | 是 | int | 每页条数 | +| page | 是 | int | 页码 | +| name | 否 | string | 模糊查询参数 | + +*返回参数说明:* + +| 参数名 | 类型 | 说明 | +| ------------- | ------ | ---------------- | +| category | string | 分类名称 | +| templates | arr | 分类下的模板列表 | +| id | int | 模板id | +| template_name | string | 模板名称 | +| content | String | 模板内容 | + +返回值 + +```json +{ + "total_count": 1, + "templates": [ + { + "id": 19, + "template_name": "工具1", + "stage_type": "customize", + "category": "其他", + "content": "xxxxxxxxxxxxxxxxxxxxxx", + "login": "victor", + "created_at": "2021-01-26T15:51:30.000+08:00", + "updated_at": "2021-01-26T15:51:30.000+08:00" + } + ] +} +``` + + + +------ + +#### 模板详情查询 + +``` +GET /api/ci/templates/id +``` + +*示例* + +```bash +curl --location --request GET 'http://localhost:3000/api/ci/templates/17.json' +``` + +*请求参数说明:* + +| 参数名 | 必选 | 类型 | 说明 | +| ------ | ---- | ---- | ------ | +| id | 是 | int | 模板id | + +*返回参数说明:* + +| 参数名 | 类型 | 说明 | +| ------------- | ------ | -------- | +| category | string | 分类名称 | +| id | int | 模板id | +| template_name | string | 模板名称 | +| content | String | 模板内容 | + +返回值 + +```json +{ + "id": 17, + "template_name": "win/x86_64", + "stage_type": "init", + "category": "初始化", + "content": "kind: pipeline\r\ntype: docker\r\nname: default\r\nplatform:\r\n os: linux\r\n arch: amd64", + "login": "victor", + "created_at": "2021-01-26T15:29:27.000+08:00", + "updated_at": "2021-01-26T15:29:27.000+08:00" +} +``` + + + +------ + +#### 模板新增/更新 + +``` +POST /api/ci/templates +``` + +*示例* + +```bash +curl --location --request POST 'http://localhost:3000/api/ci/templates' \ +--data-raw ' { + "template_name": "java++", + "stage_type": "build", + "category": "java", + "content": "xxxxxxxxxxxxxxxxxxxxxx", + "id": 21 +}' +``` + +*请求参数说明:* + +| 参数名 | 必选 | 类型 | 说明 | +| ------------- | ---- | ------ | ---------------- | +| template_name | 是 | string | 模板名称 | +| stage_type | 是 | string | 阶段类型 | +| category | 是 | string | 分类 | +| content | 是 | string | 模板内容 | +| id | 否 | int | 模板id,更新时传 | + +*返回参数说明:* + +| 参数名 | 类型 | 说明 | +| ------- | ------ | ------------ | +| status | int | 状态码 0成功 | +| message | string | 消息 | + +返回值 + +```json +{ + "status": 0, + "message": "success" +} +``` + +------ + +#### 模板删除 + +``` +DELETE /api/ci/templates/{id} +``` + +*示例* + +```bash +curl --location --request DELETE 'http://localhost:3000/api/ci/templates/10' +``` + +*请求参数说明:* + +| 参数名 | 必选 | 类型 | 说明 | +| ------ | ---- | ---- | -------- | +| id | 是 | int | 流水线id | + +*返回参数说明:* + +| 参数名 | 类型 | 说明 | +| ------- | ------ | ------------ | +| status | int | 状态码 0成功 | +| message | string | 返回消息 | + +返回值 + +```json +{ + "status": 0, + "message": "success" +} +``` + +------ + +------ + #### 解除CI服务器绑定 ``` diff --git a/app/controllers/ci/base_controller.rb b/app/controllers/ci/base_controller.rb index 5aedbddbf..1649721cd 100644 --- a/app/controllers/ci/base_controller.rb +++ b/app/controllers/ci/base_controller.rb @@ -16,6 +16,10 @@ class Ci::BaseController < ApplicationController @repos = Ci::Repo.find_all_with_namespace(namespace) end + def load_repo_by_repo_slug(slug) + @repo_slug = Ci::Repo.load_repo_by_repo_slug(slug) + end + private def authorize_access_project! unless @project.manager?(current_user) diff --git a/app/controllers/ci/cloud_accounts_controller.rb b/app/controllers/ci/cloud_accounts_controller.rb index 043d24fe0..7d829dbd7 100644 --- a/app/controllers/ci/cloud_accounts_controller.rb +++ b/app/controllers/ci/cloud_accounts_controller.rb @@ -38,7 +38,7 @@ class Ci::CloudAccountsController < Ci::BaseController ActiveRecord::Base.transaction do if @repo return render_error('该项目已经激活') if @repo.repo_active? - @repo.activate!(@ci_user.user_id) + @repo.activate!(@project) else @repo = Ci::Repo.auto_create!(@ci_user, @project) @user.update_column(:user_syncing, false) diff --git a/app/controllers/ci/pipelines_controller.rb b/app/controllers/ci/pipelines_controller.rb index 19460fde9..50417ce80 100644 --- a/app/controllers/ci/pipelines_controller.rb +++ b/app/controllers/ci/pipelines_controller.rb @@ -1,18 +1,37 @@ class Ci::PipelinesController < Ci::BaseController before_action :require_login, only: %i[list create] - skip_before_action :connect_to_ci_db - before_action :load_project, only: %i[content create_trustie_pipeline] - before_action :load_repository, only: %i[create_trustie_pipeline] + skip_before_action :connect_to_ci_db, except: %i[list create destroy] + before_action :load_project, only: %i[create] + before_action :load_repo, only: %i[create] # ======流水线相关接口========== # def list - @pipelines = Ci::Pipeline.where('identifier=?', params[:identifier]) + @result = Array.new + list = Ci::Pipeline.where('identifier=?', params[:identifier]) + # 查询build状态 + list = list.collect do |pipeline| + repo = load_repo_by_repo_slug("#{pipeline.login}/#{pipeline.identifier}") + build = repo.builds.order("build_created desc").find_by(build_target: pipeline.branch) + if build + pipeline.pipeline_status = build.build_status + pipeline.last_build_time = Time.at(build.build_created) + end + @result.push(pipeline) + end + @total_count = @result.size + @pipelines = paginate @result end def create ActiveRecord::Base.transaction do - pipeline = Ci::Pipeline.new(pipeline_name: params[:pipeline_name], file_name: params[:file_name], login: current_user.login, identifier: params[:identifier]) + size = Ci::Pipeline.where('branch=? and identifier=?', params[:branch], params[:repo]).size + if size > 0 + render_error("#{params[:branch]}分支已经存在流水线!") + return + end + pipeline = Ci::Pipeline.new(pipeline_name: params[:pipeline_name], file_name: params[:file_name], + login: current_user.login, identifier: params[:repo], branch: params[:branch], event: params[:event]) pipeline.save! # 默认创建四个初始阶段 @@ -26,12 +45,70 @@ class Ci::PipelinesController < Ci::BaseController ).save! index += 1 end + create_pipeline_file(pipeline) + create_ci_repo(pipeline) render_ok({id: pipeline.id}) end rescue Exception => ex render_error(ex.message) end + # 在代码库创建文件 + def create_pipeline_file(pipeline) + sha = get_pipeline_file_sha(pipeline.file_name, pipeline.branch) + if sha + logger.info "#{pipeline.file_name}已存在" + pipeline.update!(sync: 1, sha: sha) + else + interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params) + if interactor.success? + logger.info "#{pipeline.file_name}创建成功" + pipeline.update!(sync: 1, sha: interactor.result['content']['sha']) + end + end + end + + # 在drone数据库repo表新增一条repo记录 + def create_ci_repo(pipeline) + create_params = { + repo_user_id: @ci_user.user_id, + repo_namespace: @project.owner.login, + repo_name: @project.identifier, + repo_slug: "#{@project.owner.login}/#{@project.identifier}-" + pipeline.id.to_s, + repo_clone_url: @project.repository.url, + repo_branch: pipeline.branch, + repo_config: pipeline.file_name + } + repo = Ci::Repo.create_repo(create_params) + repo + end + + def get_pipeline_file_sha(file_name, branch) + file_path_uri = URI.parse(file_name) + interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: branch || 'master') + if interactor.success? + file = interactor.result + return file['sha'] + else + return nil + end + end + + def content_params + { + filepath: params[:file_name], + branch: params[:branch], + new_branch: params[:new_branch], + content: "#pipeline \n", + message: 'create pipeline', + committer: { + email: current_user.mail, + name: current_user.login + }, + identifier: params[:repo] + } + end + def update pipeline = Ci::Pipeline.find(params[:id]) if pipeline @@ -45,6 +122,10 @@ class Ci::PipelinesController < Ci::BaseController def destroy pipeline = Ci::Pipeline.find(params[:id]) if pipeline + repo = load_repo_by_repo_slug("#{pipeline.login}/#{pipeline.identifier}-" + pipeline.id.to_s) + if repo + repo.destroy! + end pipeline.destroy! end render_ok @@ -53,10 +134,9 @@ class Ci::PipelinesController < Ci::BaseController end def content - @yaml = "#pipeline \n" + @yaml = "\n" pipeline = Ci::Pipeline.find(params[:id]) - @sync = pipeline.sync - @sha = '' + @sha = pipeline.sha stages = pipeline.pipeline_stages if stages && !stages.empty? init_step = stages.first.pipeline_stage_steps.first @@ -72,55 +152,13 @@ class Ci::PipelinesController < Ci::BaseController end end end - if @sync == 1 - @sha = get_pipeline_file_sha(pipeline.file_name) + trigger = '' + trigger += " branch:\r\n - #{pipeline.branch}\r\n" unless pipeline.branch.blank? + unless pipeline.event.blank? + trigger += " event:\r\n" + pipeline.event.split(',').each { |event| trigger += " - #{event}\r\n"} end - end - - def get_pipeline_file_sha(file_name) - file_path_uri = URI.parse(file_name) - interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: params[:ref] || "master") - if interactor.success? - file = interactor.result - return file['sha'] - end - end - - def create_trustie_pipeline - pipeline = Ci::Pipeline.find(params[:id]) - sha = get_pipeline_file_sha(pipeline.file_name) - if sha - pipeline.update!(sync: 1) - interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, params[:owner], params.merge(identifier: @project.identifier,sha: sha)) - if interactor.success? - render_ok - else - render_error(interactor.error) - end - else - interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params) - if interactor.success? - pipeline.update!(sync: 1) - render_ok - else - render_error(interactor.error) - end - end - end - - def content_params - { - filepath: params[:filepath], - branch: params[:branch], - new_branch: params[:new_branch], - content: params[:content], - message: params[:message], - committer: { - email: current_user.mail, - name: current_user.login - }, - identifier: @project.identifier - } + @yaml += "trigger:\r\n" + trigger unless trigger.blank? end # =========阶段相关接口========= # @@ -135,8 +173,8 @@ class Ci::PipelinesController < Ci::BaseController # 修改stage排序 update_stage_index(params[:id], params[:show_index], 1) pipeline_stage = Ci::PipelineStage.new(stage_name: params[:stage_name], - stage_type: params[:stage_type].blank? ? 'customize' : params[:stage_type], - pipeline_id: params[:id], show_index: params[:show_index]) + stage_type: params[:stage_type].blank? ? 'customize' : params[:stage_type], + pipeline_id: params[:id], show_index: params[:show_index]) pipeline_stage.save! render_ok end @@ -188,7 +226,7 @@ class Ci::PipelinesController < Ci::BaseController unless steps.empty? steps.each do |step| unless step[:template_id] - render_error("请选择模板!") + render_error('请选择模板!') return end if !step[:id] diff --git a/app/controllers/ci/projects_controller.rb b/app/controllers/ci/projects_controller.rb index c7b7338f1..69644e7a5 100644 --- a/app/controllers/ci/projects_controller.rb +++ b/app/controllers/ci/projects_controller.rb @@ -41,11 +41,8 @@ class Ci::ProjectsController < Ci::BaseController ActiveRecord::Base.transaction do if @repo return render_error('该项目已经激活') if @repo.repo_active? - if @project.ci_reactivate? - @project.ci_reactivate!(@repo) - return render_ok - end - @repo.activate!(@ci_user.user_id) + @repo.activate!(@project) + return render_ok else @repo = Ci::Repo.auto_create!(@ci_user, @project) @ci_user.update_column(:user_syncing, false) @@ -66,7 +63,7 @@ class Ci::ProjectsController < Ci::BaseController return render_error('该项目已经取消激活') if !@repo.repo_active? @project.update_column(:open_devops, false) - @repo.deactivate! + @repo.deactivate_repos! render_ok end diff --git a/app/controllers/ci/templates_controller.rb b/app/controllers/ci/templates_controller.rb index c77a91445..11c6f2779 100644 --- a/app/controllers/ci/templates_controller.rb +++ b/app/controllers/ci/templates_controller.rb @@ -1,30 +1,53 @@ -class Ci::TemplatesController < ApplicationController +class Ci::TemplatesController < Ci::BaseController + before_action :require_login, only: %i[list create] + skip_before_action :connect_to_ci_db + + #======模板管理======# def list - @templates = Ci::Template.all + stage_type = params[:stage_type] + template_name = params[:name] + templates = template_name.blank? ? Ci::Template.all : Ci::Template.where("template_name like ?", "%#{template_name}%") + templates = templates.select{ |template| template.login == current_user.login} unless current_user.admin? + if !stage_type.blank? && stage_type != 'all' + templates = templates.select{ |template| template.stage_type == stage_type} + end + @total_count = templates.map(&:id).count + @templates = paginate templates end - def templates_by_stage - stage_type = params[:stage_type] - if stage_type != Ci::PipelineStage::CUSTOMIZE_STAGE_TYPE - @templates = Ci::Template.where("stage_type = ?", stage_type) - # 根据模板类别分组 - @category_templates = @templates.group_by{ |template| template.category } - else - # 自定义阶段,按阶段分类分类返回模板列表 - @templates = Ci::Template.where("stage_type != ?", Ci::PipelineStage::INIT_STAGE_TYPE) - @category_templates = @templates.group_by{ |template| template.parent_category } - end + def show + @template = Ci::Template.find(params[:id]) end def create - template = Ci::Template.new(template_name: params[:template_name], - stage_type: params[:stage_type], - category: params[:category], - parent_category: params[:parent_category], - content: params[:content] - ) - template.save! + stage_type = params[:stage_type] + category = params[:category] + if category.blank? + category = Ci::Template::STAGE_TYPES[:"#{stage_type}"] + end + + if params[:id] + template = Ci::Template.find(params[:id]) + if template + template.update!(template_name: params[:template_name], + stage_type: stage_type, + category: category, + parent_category: Ci::Template::STAGE_TYPES[:"#{stage_type}"], + content: params[:content], + login: current_user.admin? ? 'admin' : current_user.login + ) + end + else + template = Ci::Template.new(template_name: params[:template_name], + stage_type: stage_type, + category: category, + parent_category: Ci::Template::STAGE_TYPES[:"#{stage_type}"], + content: params[:content], + login: current_user.admin? ? 'admin' : current_user.login + ) + template.save! + end render_ok rescue Exception => ex render_error(ex.message) @@ -53,4 +76,20 @@ class Ci::TemplatesController < ApplicationController render_error(ex.message) end + #======流水线模板查询=====# + def templates_by_stage + stage_type = params[:stage_type] + if stage_type != Ci::PipelineStage::CUSTOMIZE_STAGE_TYPE + @templates = Ci::Template.where("stage_type = ?", stage_type) + @templates = @templates.select{ |template| template.login == current_user.login || template.login == 'admin'} unless current_user.admin? + # 根据模板类别分组 + @category_templates = @templates.group_by{ |template| template.category } + else + # 自定义阶段,按阶段分类分类返回模板列表 + @templates = Ci::Template.where("stage_type != ?", Ci::PipelineStage::INIT_STAGE_TYPE) + @templates = @templates.select{ |template| template.login == current_user.login || template.login == 'admin'} unless current_user.admin? + @category_templates = @templates.group_by{ |template| template.parent_category } + end + end + end diff --git a/app/controllers/concerns/ci/cloud_account_manageable.rb b/app/controllers/concerns/ci/cloud_account_manageable.rb index 00c42305d..13edb09c6 100644 --- a/app/controllers/concerns/ci/cloud_account_manageable.rb +++ b/app/controllers/concerns/ci/cloud_account_manageable.rb @@ -101,9 +101,6 @@ module Ci::CloudAccountManageable if cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_SELF @connection.execute("DROP DATABASE IF EXISTS #{current_user.login}_drone") # TOTO drop drone database - else - #删除drone用户 - @trustie_db_connection.execute("DELETE FROM users WHERE user_login = '#{cloud_account.account}'") end cloud_account.destroy! unless cloud_account.blank? diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 6873f2ede..a21e84459 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -11,4 +11,6 @@ class Ci::Build < Ci::RemoteBase scope :pending, -> { by_status('pending') } scope :killed, -> { by_status('killed') } scope :by_status, ->(status) { where(build_status: status) } + + scope :by_branch, ->(branch) { where(build_target: branch) } end diff --git a/app/models/ci/perm.rb b/app/models/ci/perm.rb index e6bc2ebbb..41ea2c164 100644 --- a/app/models/ci/perm.rb +++ b/app/models/ci/perm.rb @@ -4,10 +4,10 @@ class Ci::Perm < Ci::RemoteBase belongs_to :user, class_name: 'Ci::User', foreign_key: :perm_user_id belongs_to :repo, class_name: 'Ci::Repo', foreign_key: :perm_repo_uid - def self.auto_create!(user, repo) + def self.auto_create!(user_id, repo_id) perm = new( - perm_user_id: user.user_id, - perm_repo_uid: repo.repo_id, + perm_user_id: user_id, + perm_repo_uid: repo_id, perm_read: true, perm_write: true, perm_admin: true, diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 9448512b7..99a4a9950 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -10,7 +10,10 @@ # pipeline_status :string(50) default("unknown"), not null # login :string(255) # sync :integer default("0"), not null -# project_id :integer +# identifier :string(11) +# branch :string(255) +# event :string(255) +# sha :string(255) # class Ci::Pipeline < Ci::LocalBase @@ -20,4 +23,6 @@ class Ci::Pipeline < Ci::LocalBase has_many :pipeline_stages, -> { reorder(show_index: :asc) }, foreign_key: "pipeline_id", :class_name => 'Ci::PipelineStage', dependent: :destroy + attr_accessor :last_build_time + end diff --git a/app/models/ci/repo.rb b/app/models/ci/repo.rb index 6fb42e046..6c2a6d744 100644 --- a/app/models/ci/repo.rb +++ b/app/models/ci/repo.rb @@ -20,37 +20,53 @@ class Ci::Repo < Ci::RemoteBase return repos end - def activate!(ci_user_id) - update(repo_active: 1, - repo_signer: generate_code, - repo_secret: generate_code, - repo_user_id: ci_user_id, - repo_timeout: 60, - repo_config: '.trustie-pipeline.yml', - repo_updated: Time.now.to_i) + def self.load_repo_by_repo_slug(repo_slug) + logger.info "########repo_slug: #{repo_slug}" + repo = Ci::Repo.where(repo_slug: repo_slug).first + return repo + end + + def find_by_repo_name(repo_name) + logger.info "########repo_name: #{repo_name}" + repos = Ci::Repo.where(repo_name: repo_name) + return repos end def self.auto_create!(user, project) - repo = new( + create_params = { repo_user_id: user.user_id, repo_namespace: project.owner.login, repo_name: project.identifier, repo_slug: "#{project.owner.login}/#{project.identifier}", + repo_clone_url: project.repository.url, + repo_branch: 'master', + repo_config: '.trustie-pipeline.yml' + } + repo = create_repo(create_params) + repo + end + + def self.create_repo(create_params) + repo = new( + repo_user_id: create_params[:repo_user_id], + repo_namespace: create_params[:repo_namespace], + repo_name: create_params[:repo_name], + repo_slug: create_params[:repo_slug], repo_scm: "git", repo_ssh_url: "", repo_html_url: "", - repo_clone_url: project.repository.url, + repo_clone_url: create_params[:repo_clone_url], repo_active: 1, repo_private: true, repo_visibility: 'private', - repo_branch: 'master', + repo_branch: create_params[:repo_branch], repo_counter: 0, repo_trusted: false, repo_protected: false, repo_synced: 0, repo_version: 1, repo_timeout: 60, - repo_config: '.trustie-pipeline.yml', + repo_config: create_params[:repo_config], repo_created: Time.now.to_i, repo_updated: Time.now.to_i ) @@ -58,13 +74,34 @@ class Ci::Repo < Ci::RemoteBase repo.repo_signer = repo.generate_code repo.repo_secret = repo.generate_code if repo.save! - Ci::Perm.auto_create!(user, repo) + Ci::Perm.auto_create!(create_params[:repo_user_id], repo.id) repo.update_column(:repo_uid, repo.id) repo end end + # 取消激活同一个项目(多个repo) + def deactivate_repos! + repos = find_by_repo_name(self.repo_name) + repos.each do |repo| + repo.update_column(:repo_active, 0) + end + end + + def activate!(project) + repos = find_by_repo_name(self.repo_name) + project.update_column(:open_devops, true) + project.increment!(:open_devops_count) + repos.each do |repo| + repo.update_column(:repo_active, 1) + end + end + def deactivate! update_column(:repo_active, 0) end + + def destroy! + self.destroy + end end diff --git a/app/models/ci/template.rb b/app/models/ci/template.rb index e7be34a3b..74f06cf07 100644 --- a/app/models/ci/template.rb +++ b/app/models/ci/template.rb @@ -10,6 +10,7 @@ # created_at :datetime not null # updated_at :datetime not null # parent_category :string(255) +# login :string(255) # # Indexes # @@ -20,4 +21,7 @@ class Ci::Template < Ci::LocalBase validates :template_name, presence: {message: "模板名称不能为空"} validates :stage_type, presence: {message: "阶段类型不能为空"} validates :category, presence: {message: "模板类型不能为空"} + + STAGE_TYPES = {init:'初始化',build:'编译构建',deploy:'部署',customize:'其他'} + end diff --git a/app/queries/ci/builds/list_query.rb b/app/queries/ci/builds/list_query.rb index bfb0b0a59..7091723a4 100644 --- a/app/queries/ci/builds/list_query.rb +++ b/app/queries/ci/builds/list_query.rb @@ -24,6 +24,9 @@ class Ci::Builds::ListQuery < ApplicationQuery else scope end + + builds = scope.by_branch(params[:branch]) if params[:branch] + custom_sort(builds, params[:sort_by], params[:sort_direction]) end end diff --git a/app/views/ci/builds/_author.json.jbuilder b/app/views/ci/builds/_author.json.jbuilder index 280f7ef98..163bcad9c 100644 --- a/app/views/ci/builds/_author.json.jbuilder +++ b/app/views/ci/builds/_author.json.jbuilder @@ -1,4 +1,4 @@ json.id user.id -json.name user.real_name +json.name user.real_name == '游客' ? '-' : user.real_name json.login user.login json.image_url url_to_avatar(user) diff --git a/app/views/ci/pipelines/_list.json.jbuilder b/app/views/ci/pipelines/_list.json.jbuilder index 0113da58d..97720ce9f 100644 --- a/app/views/ci/pipelines/_list.json.jbuilder +++ b/app/views/ci/pipelines/_list.json.jbuilder @@ -1,8 +1,12 @@ json.id pipeline.id json.pipeline_name pipeline.pipeline_name -json.pipeline_status pipeline.pipeline_status +json.pipeline_status pipeline.pipeline_status == 'unknown' ? '' : pipeline.pipeline_status json.file_name pipeline.file_name json.sync pipeline.sync +json.branch pipeline.branch +json.event pipeline.event +json.sha pipeline.sha json.identifier pipeline.identifier +json.last_build_time pipeline.last_build_time.nil? ? '' : pipeline.last_build_time.strftime("%Y-%m-%d %H:%M:%S") json.created_at pipeline.created_at.strftime("%Y-%m-%d %H:%M:%S") json.updated_at pipeline.updated_at.strftime("%Y-%m-%d %H:%M:%S") diff --git a/app/views/ci/pipelines/list.json.jbuilder b/app/views/ci/pipelines/list.json.jbuilder index 7cfbeb1a6..86c241421 100644 --- a/app/views/ci/pipelines/list.json.jbuilder +++ b/app/views/ci/pipelines/list.json.jbuilder @@ -1,3 +1,4 @@ +json.total_count @total_count json.pipelines @pipelines do |pipeline| json.partial! "/ci/pipelines/list", pipeline: pipeline end \ No newline at end of file diff --git a/app/views/ci/templates/_list.json.jbuilder b/app/views/ci/templates/_list.json.jbuilder index 1aff25a43..a3f3868a0 100644 --- a/app/views/ci/templates/_list.json.jbuilder +++ b/app/views/ci/templates/_list.json.jbuilder @@ -3,6 +3,7 @@ json.template_name template.template_name json.stage_type template.stage_type json.category template.category json.content template.content +json.login template.login json.created_at template.created_at json.updated_at template.updated_at diff --git a/app/views/ci/templates/list.json.jbuilder b/app/views/ci/templates/list.json.jbuilder index 3b463057b..823bdfb2a 100644 --- a/app/views/ci/templates/list.json.jbuilder +++ b/app/views/ci/templates/list.json.jbuilder @@ -1,3 +1,4 @@ +json.total_count @total_count json.templates @templates do |template| json.partial! "/ci/templates/list", template: template end \ No newline at end of file diff --git a/app/views/ci/templates/show.json.jbuilder b/app/views/ci/templates/show.json.jbuilder new file mode 100644 index 000000000..cbed032dd --- /dev/null +++ b/app/views/ci/templates/show.json.jbuilder @@ -0,0 +1,9 @@ +json.id @template.id +json.template_name @template.template_name +json.stage_type @template.stage_type +json.category @template.category +json.content @template.content +json.login @template.login +json.created_at @template.created_at +json.updated_at @template.updated_at + diff --git a/config/routes.rb b/config/routes.rb index 8af453cf8..067adcce0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,7 +32,7 @@ Rails.application.routes.draw do end end - resources :templates, only: [:list,:templates_by_stage,:create,:update,:destroy] do + resources :templates, only: [:list,:templates_by_stage,:create,:update,:destroy,:show] do collection do get :list get :templates_by_stage diff --git a/db/migrate/20210122052755_add_branch_and_event_and_sha_to_ci_pipelines.rb b/db/migrate/20210122052755_add_branch_and_event_and_sha_to_ci_pipelines.rb new file mode 100644 index 000000000..4d89e3be5 --- /dev/null +++ b/db/migrate/20210122052755_add_branch_and_event_and_sha_to_ci_pipelines.rb @@ -0,0 +1,7 @@ +class AddBranchAndEventAndShaToCiPipelines < ActiveRecord::Migration[5.2] + def change + add_column :ci_pipelines, :branch, :string + add_column :ci_pipelines, :event, :string + add_column :ci_pipelines, :sha, :string + end +end diff --git a/db/migrate/20210126071814_add_login_to_ci_templates.rb b/db/migrate/20210126071814_add_login_to_ci_templates.rb new file mode 100644 index 000000000..eb5da0222 --- /dev/null +++ b/db/migrate/20210126071814_add_login_to_ci_templates.rb @@ -0,0 +1,5 @@ +class AddLoginToCiTemplates < ActiveRecord::Migration[5.2] + def change + add_column :ci_templates, :login, :string + end +end