forked from Gitlink/forgeplus
创建多条流水线、模板管理
This commit is contained in:
parent
131ccc36c7
commit
6c77b73ec6
227
api_document.md
227
api_document.md
|
@ -3520,6 +3520,7 @@ http://localhost:3000/api/Jason/forge/builds | jq
|
||||||
|page |否|string |页数,第几页 |
|
|page |否|string |页数,第几页 |
|
||||||
|limit |否|string |每页多少条数据,默认20条 |
|
|limit |否|string |每页多少条数据,默认20条 |
|
||||||
|search |是|string |构建状态条件过滤; 值说明:pending: 准备中,failure: 构建失败,running: 运行中,error:构建失败(.trustie-pipeline.yml文件错误),success: 构建成功,killed: 撤销构建 |
|
|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 |
|
| id | int | 流水线id |
|
||||||
| pipeline_name | string | 流水线名称 |
|
| pipeline_name | string | 流水线名称 |
|
||||||
| file_name | string | 流水线文件名 |
|
| file_name | string | 流水线文件名 |
|
||||||
| created_at | string | 创建时间 |
|
| branch | string | 触发分支 |
|
||||||
| sync | int | 是否同步到gitea |
|
| 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": [
|
"pipelines": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 65,
|
||||||
"pipeline_name": "2020-01-08 流水线",
|
"pipeline_name": "流水线 2021-01-25",
|
||||||
"file_name": ".trustie.pipeline.yaml",
|
"file_name": ".drone.yml",
|
||||||
"created_at": "2021-01-08 04:16:24",
|
"branch": "develop",
|
||||||
"updated_at": "2021-01-08 04:16:24"
|
"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 ' {
|
--data-raw ' {
|
||||||
"pipeline_name": "流水线 2021-01-12",
|
"pipeline_name": "流水线 2021-01-12",
|
||||||
"file_name": ".trustie.pipeline.yaml",
|
"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 | 流水线名称 |
|
| pipeline_name | 是 | string | 流水线名称 |
|
||||||
| file_name | 是 | string | 文件名称(默认初始值:.trustie.pipeline.yaml) |
|
| 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服务器绑定
|
#### 解除CI服务器绑定
|
||||||
```
|
```
|
||||||
|
|
|
@ -16,6 +16,10 @@ class Ci::BaseController < ApplicationController
|
||||||
@repos = Ci::Repo.find_all_with_namespace(namespace)
|
@repos = Ci::Repo.find_all_with_namespace(namespace)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_repo_by_repo_slug(slug)
|
||||||
|
@repo_slug = Ci::Repo.load_repo_by_repo_slug(slug)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def authorize_access_project!
|
def authorize_access_project!
|
||||||
unless @project.manager?(current_user)
|
unless @project.manager?(current_user)
|
||||||
|
|
|
@ -38,7 +38,7 @@ class Ci::CloudAccountsController < Ci::BaseController
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
if @repo
|
if @repo
|
||||||
return render_error('该项目已经激活') if @repo.repo_active?
|
return render_error('该项目已经激活') if @repo.repo_active?
|
||||||
@repo.activate!(@ci_user.user_id)
|
@repo.activate!(@project)
|
||||||
else
|
else
|
||||||
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||||
@user.update_column(:user_syncing, false)
|
@user.update_column(:user_syncing, false)
|
||||||
|
|
|
@ -1,18 +1,37 @@
|
||||||
class Ci::PipelinesController < Ci::BaseController
|
class Ci::PipelinesController < Ci::BaseController
|
||||||
|
|
||||||
before_action :require_login, only: %i[list create]
|
before_action :require_login, only: %i[list create]
|
||||||
skip_before_action :connect_to_ci_db
|
skip_before_action :connect_to_ci_db, except: %i[list create destroy]
|
||||||
before_action :load_project, only: %i[content create_trustie_pipeline]
|
before_action :load_project, only: %i[create]
|
||||||
before_action :load_repository, only: %i[create_trustie_pipeline]
|
before_action :load_repo, only: %i[create]
|
||||||
|
|
||||||
# ======流水线相关接口========== #
|
# ======流水线相关接口========== #
|
||||||
def list
|
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
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
ActiveRecord::Base.transaction do
|
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!
|
pipeline.save!
|
||||||
|
|
||||||
# 默认创建四个初始阶段
|
# 默认创建四个初始阶段
|
||||||
|
@ -26,12 +45,70 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
).save!
|
).save!
|
||||||
index += 1
|
index += 1
|
||||||
end
|
end
|
||||||
|
create_pipeline_file(pipeline)
|
||||||
|
create_ci_repo(pipeline)
|
||||||
render_ok({id: pipeline.id})
|
render_ok({id: pipeline.id})
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
render_error(ex.message)
|
||||||
end
|
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
|
def update
|
||||||
pipeline = Ci::Pipeline.find(params[:id])
|
pipeline = Ci::Pipeline.find(params[:id])
|
||||||
if pipeline
|
if pipeline
|
||||||
|
@ -45,6 +122,10 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
pipeline = Ci::Pipeline.find(params[:id])
|
pipeline = Ci::Pipeline.find(params[:id])
|
||||||
if pipeline
|
if pipeline
|
||||||
|
repo = load_repo_by_repo_slug("#{pipeline.login}/#{pipeline.identifier}-" + pipeline.id.to_s)
|
||||||
|
if repo
|
||||||
|
repo.destroy!
|
||||||
|
end
|
||||||
pipeline.destroy!
|
pipeline.destroy!
|
||||||
end
|
end
|
||||||
render_ok
|
render_ok
|
||||||
|
@ -53,10 +134,9 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def content
|
def content
|
||||||
@yaml = "#pipeline \n"
|
@yaml = "\n"
|
||||||
pipeline = Ci::Pipeline.find(params[:id])
|
pipeline = Ci::Pipeline.find(params[:id])
|
||||||
@sync = pipeline.sync
|
@sha = pipeline.sha
|
||||||
@sha = ''
|
|
||||||
stages = pipeline.pipeline_stages
|
stages = pipeline.pipeline_stages
|
||||||
if stages && !stages.empty?
|
if stages && !stages.empty?
|
||||||
init_step = stages.first.pipeline_stage_steps.first
|
init_step = stages.first.pipeline_stage_steps.first
|
||||||
|
@ -72,55 +152,13 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if @sync == 1
|
trigger = ''
|
||||||
@sha = get_pipeline_file_sha(pipeline.file_name)
|
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
|
||||||
end
|
@yaml += "trigger:\r\n" + trigger unless trigger.blank?
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# =========阶段相关接口========= #
|
# =========阶段相关接口========= #
|
||||||
|
@ -135,8 +173,8 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
# 修改stage排序
|
# 修改stage排序
|
||||||
update_stage_index(params[:id], params[:show_index], 1)
|
update_stage_index(params[:id], params[:show_index], 1)
|
||||||
pipeline_stage = Ci::PipelineStage.new(stage_name: params[:stage_name],
|
pipeline_stage = Ci::PipelineStage.new(stage_name: params[:stage_name],
|
||||||
stage_type: params[:stage_type].blank? ? 'customize' : params[:stage_type],
|
stage_type: params[:stage_type].blank? ? 'customize' : params[:stage_type],
|
||||||
pipeline_id: params[:id], show_index: params[:show_index])
|
pipeline_id: params[:id], show_index: params[:show_index])
|
||||||
pipeline_stage.save!
|
pipeline_stage.save!
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
@ -188,7 +226,7 @@ class Ci::PipelinesController < Ci::BaseController
|
||||||
unless steps.empty?
|
unless steps.empty?
|
||||||
steps.each do |step|
|
steps.each do |step|
|
||||||
unless step[:template_id]
|
unless step[:template_id]
|
||||||
render_error("请选择模板!")
|
render_error('请选择模板!')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if !step[:id]
|
if !step[:id]
|
||||||
|
|
|
@ -41,11 +41,8 @@ class Ci::ProjectsController < Ci::BaseController
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
if @repo
|
if @repo
|
||||||
return render_error('该项目已经激活') if @repo.repo_active?
|
return render_error('该项目已经激活') if @repo.repo_active?
|
||||||
if @project.ci_reactivate?
|
@repo.activate!(@project)
|
||||||
@project.ci_reactivate!(@repo)
|
return render_ok
|
||||||
return render_ok
|
|
||||||
end
|
|
||||||
@repo.activate!(@ci_user.user_id)
|
|
||||||
else
|
else
|
||||||
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||||
@ci_user.update_column(:user_syncing, false)
|
@ci_user.update_column(:user_syncing, false)
|
||||||
|
@ -66,7 +63,7 @@ class Ci::ProjectsController < Ci::BaseController
|
||||||
return render_error('该项目已经取消激活') if !@repo.repo_active?
|
return render_error('该项目已经取消激活') if !@repo.repo_active?
|
||||||
|
|
||||||
@project.update_column(:open_devops, false)
|
@project.update_column(:open_devops, false)
|
||||||
@repo.deactivate!
|
@repo.deactivate_repos!
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
end
|
||||||
|
|
||||||
def templates_by_stage
|
def show
|
||||||
stage_type = params[:stage_type]
|
@template = Ci::Template.find(params[:id])
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
template = Ci::Template.new(template_name: params[:template_name],
|
stage_type = params[:stage_type]
|
||||||
stage_type: params[:stage_type],
|
category = params[:category]
|
||||||
category: params[:category],
|
if category.blank?
|
||||||
parent_category: params[:parent_category],
|
category = Ci::Template::STAGE_TYPES[:"#{stage_type}"]
|
||||||
content: params[:content]
|
end
|
||||||
)
|
|
||||||
template.save!
|
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
|
render_ok
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
render_error(ex.message)
|
render_error(ex.message)
|
||||||
|
@ -53,4 +76,20 @@ class Ci::TemplatesController < ApplicationController
|
||||||
render_error(ex.message)
|
render_error(ex.message)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -101,9 +101,6 @@ module Ci::CloudAccountManageable
|
||||||
|
|
||||||
if cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_SELF
|
if cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_SELF
|
||||||
@connection.execute("DROP DATABASE IF EXISTS #{current_user.login}_drone") # TOTO drop drone database
|
@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
|
end
|
||||||
|
|
||||||
cloud_account.destroy! unless cloud_account.blank?
|
cloud_account.destroy! unless cloud_account.blank?
|
||||||
|
|
|
@ -11,4 +11,6 @@ class Ci::Build < Ci::RemoteBase
|
||||||
scope :pending, -> { by_status('pending') }
|
scope :pending, -> { by_status('pending') }
|
||||||
scope :killed, -> { by_status('killed') }
|
scope :killed, -> { by_status('killed') }
|
||||||
scope :by_status, ->(status) { where(build_status: status) }
|
scope :by_status, ->(status) { where(build_status: status) }
|
||||||
|
|
||||||
|
scope :by_branch, ->(branch) { where(build_target: branch) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,10 +4,10 @@ class Ci::Perm < Ci::RemoteBase
|
||||||
belongs_to :user, class_name: 'Ci::User', foreign_key: :perm_user_id
|
belongs_to :user, class_name: 'Ci::User', foreign_key: :perm_user_id
|
||||||
belongs_to :repo, class_name: 'Ci::Repo', foreign_key: :perm_repo_uid
|
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 = new(
|
||||||
perm_user_id: user.user_id,
|
perm_user_id: user_id,
|
||||||
perm_repo_uid: repo.repo_id,
|
perm_repo_uid: repo_id,
|
||||||
perm_read: true,
|
perm_read: true,
|
||||||
perm_write: true,
|
perm_write: true,
|
||||||
perm_admin: true,
|
perm_admin: true,
|
||||||
|
|
|
@ -10,7 +10,10 @@
|
||||||
# pipeline_status :string(50) default("unknown"), not null
|
# pipeline_status :string(50) default("unknown"), not null
|
||||||
# login :string(255)
|
# login :string(255)
|
||||||
# sync :integer default("0"), not null
|
# 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
|
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
|
has_many :pipeline_stages, -> { reorder(show_index: :asc) }, foreign_key: "pipeline_id", :class_name => 'Ci::PipelineStage', dependent: :destroy
|
||||||
|
|
||||||
|
attr_accessor :last_build_time
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,37 +20,53 @@ class Ci::Repo < Ci::RemoteBase
|
||||||
return repos
|
return repos
|
||||||
end
|
end
|
||||||
|
|
||||||
def activate!(ci_user_id)
|
def self.load_repo_by_repo_slug(repo_slug)
|
||||||
update(repo_active: 1,
|
logger.info "########repo_slug: #{repo_slug}"
|
||||||
repo_signer: generate_code,
|
repo = Ci::Repo.where(repo_slug: repo_slug).first
|
||||||
repo_secret: generate_code,
|
return repo
|
||||||
repo_user_id: ci_user_id,
|
end
|
||||||
repo_timeout: 60,
|
|
||||||
repo_config: '.trustie-pipeline.yml',
|
def find_by_repo_name(repo_name)
|
||||||
repo_updated: Time.now.to_i)
|
logger.info "########repo_name: #{repo_name}"
|
||||||
|
repos = Ci::Repo.where(repo_name: repo_name)
|
||||||
|
return repos
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.auto_create!(user, project)
|
def self.auto_create!(user, project)
|
||||||
repo = new(
|
create_params = {
|
||||||
repo_user_id: user.user_id,
|
repo_user_id: user.user_id,
|
||||||
repo_namespace: project.owner.login,
|
repo_namespace: project.owner.login,
|
||||||
repo_name: project.identifier,
|
repo_name: project.identifier,
|
||||||
repo_slug: "#{project.owner.login}/#{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_scm: "git",
|
||||||
repo_ssh_url: "",
|
repo_ssh_url: "",
|
||||||
repo_html_url: "",
|
repo_html_url: "",
|
||||||
repo_clone_url: project.repository.url,
|
repo_clone_url: create_params[:repo_clone_url],
|
||||||
repo_active: 1,
|
repo_active: 1,
|
||||||
repo_private: true,
|
repo_private: true,
|
||||||
repo_visibility: 'private',
|
repo_visibility: 'private',
|
||||||
repo_branch: 'master',
|
repo_branch: create_params[:repo_branch],
|
||||||
repo_counter: 0,
|
repo_counter: 0,
|
||||||
repo_trusted: false,
|
repo_trusted: false,
|
||||||
repo_protected: false,
|
repo_protected: false,
|
||||||
repo_synced: 0,
|
repo_synced: 0,
|
||||||
repo_version: 1,
|
repo_version: 1,
|
||||||
repo_timeout: 60,
|
repo_timeout: 60,
|
||||||
repo_config: '.trustie-pipeline.yml',
|
repo_config: create_params[:repo_config],
|
||||||
repo_created: Time.now.to_i,
|
repo_created: Time.now.to_i,
|
||||||
repo_updated: 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_signer = repo.generate_code
|
||||||
repo.repo_secret = repo.generate_code
|
repo.repo_secret = repo.generate_code
|
||||||
if repo.save!
|
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.update_column(:repo_uid, repo.id)
|
||||||
repo
|
repo
|
||||||
end
|
end
|
||||||
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!
|
def deactivate!
|
||||||
update_column(:repo_active, 0)
|
update_column(:repo_active, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def destroy!
|
||||||
|
self.destroy
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# parent_category :string(255)
|
# parent_category :string(255)
|
||||||
|
# login :string(255)
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
@ -20,4 +21,7 @@ class Ci::Template < Ci::LocalBase
|
||||||
validates :template_name, presence: {message: "模板名称不能为空"}
|
validates :template_name, presence: {message: "模板名称不能为空"}
|
||||||
validates :stage_type, presence: {message: "阶段类型不能为空"}
|
validates :stage_type, presence: {message: "阶段类型不能为空"}
|
||||||
validates :category, presence: {message: "模板类型不能为空"}
|
validates :category, presence: {message: "模板类型不能为空"}
|
||||||
|
|
||||||
|
STAGE_TYPES = {init:'初始化',build:'编译构建',deploy:'部署',customize:'其他'}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,9 @@ class Ci::Builds::ListQuery < ApplicationQuery
|
||||||
else
|
else
|
||||||
scope
|
scope
|
||||||
end
|
end
|
||||||
|
|
||||||
|
builds = scope.by_branch(params[:branch]) if params[:branch]
|
||||||
|
|
||||||
custom_sort(builds, params[:sort_by], params[:sort_direction])
|
custom_sort(builds, params[:sort_by], params[:sort_direction])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
json.id user.id
|
json.id user.id
|
||||||
json.name user.real_name
|
json.name user.real_name == '游客' ? '-' : user.real_name
|
||||||
json.login user.login
|
json.login user.login
|
||||||
json.image_url url_to_avatar(user)
|
json.image_url url_to_avatar(user)
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
json.id pipeline.id
|
json.id pipeline.id
|
||||||
json.pipeline_name pipeline.pipeline_name
|
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.file_name pipeline.file_name
|
||||||
json.sync pipeline.sync
|
json.sync pipeline.sync
|
||||||
|
json.branch pipeline.branch
|
||||||
|
json.event pipeline.event
|
||||||
|
json.sha pipeline.sha
|
||||||
json.identifier pipeline.identifier
|
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.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")
|
json.updated_at pipeline.updated_at.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
json.total_count @total_count
|
||||||
json.pipelines @pipelines do |pipeline|
|
json.pipelines @pipelines do |pipeline|
|
||||||
json.partial! "/ci/pipelines/list", pipeline: pipeline
|
json.partial! "/ci/pipelines/list", pipeline: pipeline
|
||||||
end
|
end
|
|
@ -3,6 +3,7 @@ json.template_name template.template_name
|
||||||
json.stage_type template.stage_type
|
json.stage_type template.stage_type
|
||||||
json.category template.category
|
json.category template.category
|
||||||
json.content template.content
|
json.content template.content
|
||||||
|
json.login template.login
|
||||||
json.created_at template.created_at
|
json.created_at template.created_at
|
||||||
json.updated_at template.updated_at
|
json.updated_at template.updated_at
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
json.total_count @total_count
|
||||||
json.templates @templates do |template|
|
json.templates @templates do |template|
|
||||||
json.partial! "/ci/templates/list", template: template
|
json.partial! "/ci/templates/list", template: template
|
||||||
end
|
end
|
|
@ -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
|
||||||
|
|
|
@ -32,7 +32,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
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
|
collection do
|
||||||
get :list
|
get :list
|
||||||
get :templates_by_stage
|
get :templates_by_stage
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddLoginToCiTemplates < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :ci_templates, :login, :string
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue