Merge branch 'develop' into dev_military
This commit is contained in:
commit
0f01abd45f
766
api_document.md
766
api_document.md
|
@ -461,7 +461,7 @@ curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror | jq
|
||||||
|
|
||||||
#### 项目详情
|
#### 项目详情
|
||||||
```
|
```
|
||||||
GET /api/:namespace_id/:id
|
GET /api/:owner/:repo
|
||||||
```
|
```
|
||||||
*示例*
|
*示例*
|
||||||
```bash
|
```bash
|
||||||
|
@ -471,8 +471,8 @@ curl -X GET http://localhost:3000/api/jasder/jasder_test | jq
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|namespace_id |是|string |用户登录名 |
|
|owner |是|string |用户登录名 |
|
||||||
|id |是|string |项目标识identifier |
|
|repo |是|string |项目标识identifier |
|
||||||
|
|
||||||
|
|
||||||
*返回参数说明:*
|
*返回参数说明:*
|
||||||
|
@ -503,7 +503,7 @@ curl -X GET http://localhost:3000/api/jasder/jasder_test | jq
|
||||||
|
|
||||||
#### 项目详情(简版)
|
#### 项目详情(简版)
|
||||||
```
|
```
|
||||||
GET /api/:namespace_id/:id/simple
|
GET /api/:owner/:repo/simple
|
||||||
```
|
```
|
||||||
*示例*
|
*示例*
|
||||||
```bash
|
```bash
|
||||||
|
@ -513,7 +513,8 @@ curl -X GET http://localhost:3000/api/jasder/jasder_test/simple | jq
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|id |是|int |项目id |
|
|owner |是|string |用户登录名 |
|
||||||
|
|repo |是|string |项目标识identifier |
|
||||||
|
|
||||||
|
|
||||||
*返回参数说明:*
|
*返回参数说明:*
|
||||||
|
@ -876,7 +877,7 @@ curl -X POST http://localhost:3000/api/projects/3297/forks | jq
|
||||||
|
|
||||||
#### 获取代码目录列表
|
#### 获取代码目录列表
|
||||||
```
|
```
|
||||||
POST /api/:namespace_id/:project_id/repository/entries
|
POST /api/:owner/:repo/repository/entries
|
||||||
```
|
```
|
||||||
*示例*
|
*示例*
|
||||||
```bash
|
```bash
|
||||||
|
@ -888,7 +889,8 @@ http://localhost:3000//api/jasder/jasder_test/repository/entries | jq
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|id |是|int |项目id |
|
|owner |是|string |用户登录名 |
|
||||||
|
|repo |是|string |项目标识identifier |
|
||||||
|ref |否|string |分支名称、tag名称或是提交记录id,默认为master分支 |
|
|ref |否|string |分支名称、tag名称或是提交记录id,默认为master分支 |
|
||||||
|
|
||||||
|
|
||||||
|
@ -1378,7 +1380,7 @@ http://localhost:3000/api/projects/recommend | jq
|
||||||
|
|
||||||
#### 项目主页
|
#### 项目主页
|
||||||
```
|
```
|
||||||
GET api/:namespace_id/:id/about
|
GET api/:owner/:repo/about
|
||||||
```
|
```
|
||||||
|
|
||||||
*示例*
|
*示例*
|
||||||
|
@ -1391,8 +1393,8 @@ http://localhost:3000/api/:jason/forgeplus/about | jq
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|namespace_id |是|string |用户登录名 |
|
|owner |是|string |用户登录名 |
|
||||||
|id |是|string |项目标识identifier |
|
|repo |是|string |项目标识identifier |
|
||||||
|
|
||||||
*返回参数说明:*
|
*返回参数说明:*
|
||||||
|
|
||||||
|
@ -1419,7 +1421,7 @@ http://localhost:3000/api/:jason/forgeplus/about | jq
|
||||||
|
|
||||||
#### 修改项目主页内容
|
#### 修改项目主页内容
|
||||||
```
|
```
|
||||||
POST api/:namespace_id/:id/about
|
POST api/:owner/:repo/about
|
||||||
```
|
```
|
||||||
|
|
||||||
*示例*
|
*示例*
|
||||||
|
@ -1427,15 +1429,15 @@ POST api/:namespace_id/:id/about
|
||||||
curl -X POST \
|
curl -X POST \
|
||||||
-d "content=内容" \
|
-d "content=内容" \
|
||||||
-d "attachment_ids=[1, 2, 2]" \
|
-d "attachment_ids=[1, 2, 2]" \
|
||||||
http://localhost:3000/api/:jasder/forgeplus/about | jq
|
http://localhost:3000/api/jasder/forgeplus/about | jq
|
||||||
```
|
```
|
||||||
|
|
||||||
*请求参数说明:*
|
*请求参数说明:*
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|namespace_id |是|string |用户登录名 |
|
|owner |是|string |用户登录名 |
|
||||||
|id |是|string |项目标识identifier |
|
|repo |是|string |项目标识identifier |
|
||||||
|content |是|string |内容信息 |
|
|content |是|string |内容信息 |
|
||||||
|attachment_ids |是|array |附件id |
|
|attachment_ids |是|array |附件id |
|
||||||
|
|
||||||
|
@ -1463,7 +1465,7 @@ http://localhost:3000/api/:jasder/forgeplus/about | jq
|
||||||
|
|
||||||
### 获取分支列表
|
### 获取分支列表
|
||||||
```
|
```
|
||||||
GET /api/:namespace_id/:id/branches
|
GET /api/:owner/:repo/branches
|
||||||
```
|
```
|
||||||
*示例*
|
*示例*
|
||||||
```bash
|
```bash
|
||||||
|
@ -1473,7 +1475,8 @@ curl -X GET http://localhost:3000/api/jasder/jasder_test/branches | jq
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|id |是|id |项目id |
|
|owner |是|string |用户登录名 |
|
||||||
|
|repo |是|string |项目标识identifier |
|
||||||
|
|
||||||
|
|
||||||
*返回参数说明:*
|
*返回参数说明:*
|
||||||
|
@ -1630,7 +1633,7 @@ http://localhost:3000/api/repositories/5836/tags.json | jq
|
||||||
|
|
||||||
## 仓库详情
|
## 仓库详情
|
||||||
```
|
```
|
||||||
GET /api/:namespace_id/:project_id/repository
|
GET /api/:owner/:repo/repository
|
||||||
```
|
```
|
||||||
*示例*
|
*示例*
|
||||||
```bash
|
```bash
|
||||||
|
@ -1641,8 +1644,8 @@ http://192.168.2.230:3000/api/jasder/forgeplus/repository | jq
|
||||||
|
|
||||||
|参数名|必选|类型|说明|
|
|参数名|必选|类型|说明|
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|namespace_id |是|string |用户登录名 |
|
|owner |是|string |用户登录名 |
|
||||||
|project_id |是|string |项目标识identifier |
|
|repo |是|string |项目标识identifier |
|
||||||
|
|
||||||
|
|
||||||
*返回参数说明:*
|
*返回参数说明:*
|
||||||
|
@ -3096,6 +3099,78 @@ http://localhost:3000/api/trustie/truesite/protected_branches/master.json | jq
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### 获取仓库README文件
|
||||||
|
```
|
||||||
|
GET api/:owner/:repo/readme
|
||||||
|
```
|
||||||
|
*示例*
|
||||||
|
```bash
|
||||||
|
curl -X GET http://localhost:3000/api/trusite/trusite/readme | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
|参数名|类型|说明|
|
||||||
|
|-|-|-|
|
||||||
|
|owner |是|string |项目拥有者登录名 |
|
||||||
|
|repo |否|boolean |仓库名称 |
|
||||||
|
|ref |否|string |分支、tag或commit。默认: 仓库的默认分支(通常是master)|
|
||||||
|
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
|参数名|类型|说明|
|
||||||
|
|-|-|-|
|
||||||
|
|name |string|文件名称|
|
||||||
|
|path |string|文件相对路径|
|
||||||
|
|type |string|文件类型, file:文件|
|
||||||
|
|size |int|文件大小 单位KB|
|
||||||
|
|content |string|文件内容,base64加密|
|
||||||
|
|
||||||
|
返回值
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"encoding": "base64",
|
||||||
|
"size": 13544,
|
||||||
|
"name": "README.md",
|
||||||
|
"path": "README.md",
|
||||||
|
"content": "Q2hpbmVzZSAmbmJzcDsgfCAmbmJzcDsgW0VuZ7i9yZWFkbWUvaW5kZXgucG5"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 获库仓库的语言百分占比
|
||||||
|
```
|
||||||
|
GET api/:owner/:repo/languages
|
||||||
|
```
|
||||||
|
*示例*
|
||||||
|
```bash
|
||||||
|
curl -X GET http://localhost:3000/api/jasder/trusite/languages | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
|参数名|类型|说明|
|
||||||
|
|-|-|-|
|
||||||
|
|owner |是|string |项目拥有者登录名 |
|
||||||
|
|repo |否|boolean |仓库名称 |
|
||||||
|
|
||||||
|
|
||||||
|
返回值
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"JavaScript": "90.2%",
|
||||||
|
"CSS": "6.1%",
|
||||||
|
"Java": "2.9%",
|
||||||
|
"HTML": "0.8%"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### DevOps相关api
|
### DevOps相关api
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -3320,9 +3395,10 @@ http://localhost:3000/api/jasder/forge/get_trustie_pipeline.json | jq
|
||||||
PUT /api/:owner/:repo/update_trustie_pipeline
|
PUT /api/:owner/:repo/update_trustie_pipeline
|
||||||
```
|
```
|
||||||
*示例*
|
*示例*
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X GET \
|
curl -X GET \
|
||||||
http://localhost:3000/api/jasder/forge/update_trustie_pipeline.json | jq
|
http://localhost:3000/api/jasder/forge/update_trustie_pipeline.json?pipeline_id=1 | jq
|
||||||
```
|
```
|
||||||
*请求参数说明:*
|
*请求参数说明:*
|
||||||
|
|
||||||
|
@ -3899,6 +3975,48 @@ http://localhost:3000/api/users/ci/cloud_account | jq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 绑定CI服务器-Trustie提供服务器
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/users/ci/cloud_account/trustie_bind
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-d "account=xx" \
|
||||||
|
https://localhost:3000/api/users/ci/cloud_account/trustie_bind.json | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ------- | ---- | ------ | ---------- |
|
||||||
|
| account | 是 | string | 登录用户名 |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------------ | ------ | --------------------------------------- |
|
||||||
|
| step | int | 0: 未绑定;1: 未认证(已绑定),2: 已认证 |
|
||||||
|
| ip | string | ci服务器ip |
|
||||||
|
| redirect_url | string | 认证地址 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"step": 0,
|
||||||
|
"cloud_account": {
|
||||||
|
"ip": "xxx.xxx.xxx.x",
|
||||||
|
"redirect_url": "http://localhost:3000/login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### 绑定CI服务器
|
#### 绑定CI服务器
|
||||||
|
@ -3941,10 +4059,616 @@ https://localhost:3000/api/users/ci/cloud_account/bind.json | jq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线查询
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/ci/pipelines/list?identifier={identifier}
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET \
|
||||||
|
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 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### 流水线新增
|
||||||
|
|
||||||
### 解除CI服务器绑定
|
```
|
||||||
|
POST /api/ci/pipelines
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request POST 'http://localhost:3000/api/ci/pipelines' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw ' {
|
||||||
|
"pipeline_name": "流水线 2021-01-12",
|
||||||
|
"file_name": ".trustie.pipeline.yaml",
|
||||||
|
"identifier": "xxx"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ------------- | ---- | ------ | ---------------------------------------------- |
|
||||||
|
| pipeline_name | 是 | string | 流水线名称 |
|
||||||
|
| file_name | 是 | string | 文件名称(默认初始值:.trustie.pipeline.yaml) |
|
||||||
|
| identifier | 是 | string | 项目identifier |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | -------------- |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
| id | int | 新增流水线的id |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success",
|
||||||
|
"id": 18
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线更新
|
||||||
|
|
||||||
|
修改流水线名称时调用。
|
||||||
|
|
||||||
|
```
|
||||||
|
PUT /api/ci/pipelines/{id}
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request PUT 'http://localhost:3000/api/ci/pipelines/3' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw ' {
|
||||||
|
"pipeline_name": "2020-01-11 流水线"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ------------- | ---- | ------ | ---------- |
|
||||||
|
| id | 是 | id | 流水线id |
|
||||||
|
| pipeline_name | 是 | string | 流水线名称 |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线删除
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /api/ci/pipelines/{id}
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE \
|
||||||
|
https://localhost:3000/api/ci/pipelines/1 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ------ | ---- | ---- | -------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线的阶段查询
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/ci/pipelines/{id}/stages
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request GET 'http://localhost:3000/api/ci/pipelines/19/stages.json'
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ------ | ---- | ---- | -------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ----------- | ------ | -------- |
|
||||||
|
| stages | arr | 阶段数组 |
|
||||||
|
| stage_name | string | 阶段名称 |
|
||||||
|
| stage_type | string | 阶段类型 |
|
||||||
|
| pipeline_id | int | 流水线id |
|
||||||
|
| show_index | int | 排序 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"stages": [
|
||||||
|
{
|
||||||
|
"id": 37,
|
||||||
|
"stage_name": "初始化",
|
||||||
|
"stage_type": "init",
|
||||||
|
"pipeline_id": 19,
|
||||||
|
"show_index": 1,
|
||||||
|
"created_at": "2021-01-12T15:18:00.000+08:00",
|
||||||
|
"updated_at": "2021-01-12T15:18:00.000+08:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 38,
|
||||||
|
"stage_name": "编译构建",
|
||||||
|
"stage_type": "build",
|
||||||
|
"pipeline_id": 19,
|
||||||
|
"show_index": 2,
|
||||||
|
"created_at": "2021-01-12T15:18:00.000+08:00",
|
||||||
|
"updated_at": "2021-01-12T15:18:00.000+08:00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 确认阶段流水线完整内容查询
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/ci/pipelines/{id}/content?owner={owner}&repo={repo}
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET \
|
||||||
|
http://localhost:3000/api/ci/pipelines/1/content.json?owner=xx&repo=xx | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ---------------- |
|
||||||
|
| content | String | 流水线内容 |
|
||||||
|
| sync | int | 同步状态 |
|
||||||
|
| owner | string | 用户登录名 |
|
||||||
|
| repo | string | 项目的identifier |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content": "#pipeline \nkind: pipeline\r\nname: maven项目-镜像仓库\r\n\r\nplatform:\r\n os: linux\r\n arch: arm64\nsteps:\n- name: Maven编译\r\n image: arm64v8/maven\r\n commands:\r\n - mvn install\n- name: 编译镜像-推送到仓库\r\n image: plugins/docker\r\n settings:\r\n username: moshenglv\r\n password: RL9UB5P7Jtzukka\r\n repo: docker.io/moshenglv/demo\r\n tags: latest\n",
|
||||||
|
"sync": 1,
|
||||||
|
"sha":"xxxxx"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线阶段新增
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/ci/pipelines/{id}/create_stage
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request POST 'http://localhost:3000/api/ci/pipelines/19/create_stage.json' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw '{
|
||||||
|
"stage_name": "新阶段2",
|
||||||
|
"show_index": 2
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ---------- | ---- | ------ | -------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
| show_index | 是 | int | 阶段排序 |
|
||||||
|
| stage_name | 是 | string | 阶段名称 |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线阶段更新
|
||||||
|
|
||||||
|
```
|
||||||
|
PUT /api/ci/pipelines/{id}/{stage_id}/update_stage
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request PUT 'http://localhost:3000/api/ci/pipelines/1/5/update_stage.json' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw ' {
|
||||||
|
"stage_name": "新阶段-更新"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ---------- | ---- | ------ | -------------------------------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
| stage_name | 是 | string | 阶段名称(默认为 阶段名-模板名) |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线阶段删除
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /api/ci/pipelines/{id}/{stage_id}/delete_stage?show_index={index}
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request DELETE 'http://localhost:3000/api/ci/pipelines/19/42/delete_stage.json?show_index=2' \
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ---------- | ---- | ---- | ---------------------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
| stage_id | 是 | int | 阶段id |
|
||||||
|
| show_index | 是 | int | 被删除阶段的show_index |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线阶段步骤查询
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/ci/pipelines/{id}/{stage_id}/steps.json
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET \
|
||||||
|
http://localhost:3000/api/ci/pipelines/1/2/steps.json | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| -------- | ---- | ---- | -------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
| stage_id | 是 | int | 阶段id |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ---------- | ------ | ------------------ |
|
||||||
|
| id | int | 步骤id |
|
||||||
|
| step_name | string | 步骤名称 |
|
||||||
|
| stage_id | int | 所属阶段id |
|
||||||
|
| show_index | int | 显示顺序 |
|
||||||
|
| content | String | 步骤内容 |
|
||||||
|
| template | Object | 步骤对应的模板对象 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"step_name": "编译构建-maven",
|
||||||
|
"stage_id": 2,
|
||||||
|
"show_index": 0,
|
||||||
|
"content": "- name: Maven编译\r\n image: arm64v8/maven\r\n",
|
||||||
|
"created_at": "2021-01-11T09:57:17.000+08:00",
|
||||||
|
"updated_at": "2021-01-11T09:57:17.000+08:00",
|
||||||
|
"template": {
|
||||||
|
"id": 3,
|
||||||
|
"template_name": "maven",
|
||||||
|
"stage_type": "build",
|
||||||
|
"category": "java",
|
||||||
|
"content": "- name: maven\r\n image: maven:3-jdk-10\r\n",
|
||||||
|
"created_at": "2021-01-11T17:28:34.000+08:00",
|
||||||
|
"updated_at": "2021-01-11T17:28:36.000+08:00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线阶段步骤新增/更新
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/ci/pipelines/{id}/{stage_id}/stage_step
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request POST 'http://localhost:3000/api/ci/pipelines/1/2/stage_step.json' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw ' {"steps":[{
|
||||||
|
"id":7,
|
||||||
|
"step_name": "编译构建11-gradle",
|
||||||
|
"show_index": 1,
|
||||||
|
"content": "xxxxxxxxxxx",
|
||||||
|
"template_id":2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ---------------- | ---- | ------ | -------------------------------- |
|
||||||
|
| steps | 是 | arr | 需要更新step数组 |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
| stage_id | 是 | int | 阶段id |
|
||||||
|
| id(数组中的id) | 否 | int | 步骤id(存在则更新,不存在新增) |
|
||||||
|
| step_name | 是 | string | 阶段名称(阶段名-模板名) |
|
||||||
|
| content | 是 | string | 步骤内容 |
|
||||||
|
| template_id | 是 | int | 模板id |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 流水线阶段步骤删除
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /api/ci/pipelines/{id}/{stage_id}/{step_id}/delete_step
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE \
|
||||||
|
https://localhost:3000/api/ci/pipelines/1/6/2/delete_stage.json | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| -------- | ---- | ---- | -------- |
|
||||||
|
| id | 是 | int | 流水线id |
|
||||||
|
| stage_id | 是 | int | 阶段id |
|
||||||
|
| step_id | 是 | int | 步骤id |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------- | ------ | ------------ |
|
||||||
|
| status | int | 状态码 0成功 |
|
||||||
|
| message | string | 返回消息 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"message": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
#### 阶段模板查询
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/ci/templates/templates_by_stage?stage_type={stage_type}
|
||||||
|
```
|
||||||
|
|
||||||
|
*示例*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET \
|
||||||
|
http://localhost:3000/api/ci/templates/templates_by_stage.json?stage_type=build | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
*请求参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 必选 | 类型 | 说明 |
|
||||||
|
| ---------- | ---- | ------ | ------------------------------------- |
|
||||||
|
| stage_type | 是 | string | 阶段类型:init/build/deploy/customize |
|
||||||
|
|
||||||
|
*返回参数说明:*
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------------- | ------ | ---------------- |
|
||||||
|
| category | string | 分类名称 |
|
||||||
|
| templates | arr | 分类下的模板列表 |
|
||||||
|
| id | int | 模板id |
|
||||||
|
| template_name | string | 模板名称 |
|
||||||
|
| content | String | 模板内容 |
|
||||||
|
|
||||||
|
返回值
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"category": "java",
|
||||||
|
"templates": [
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"template_name": "maven",
|
||||||
|
"stage_type": "build",
|
||||||
|
"category": "java",
|
||||||
|
"content": "#maven",
|
||||||
|
"created_at": "2021-01-11T17:28:34.000+08:00",
|
||||||
|
"updated_at": "2021-01-11T17:28:36.000+08:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"template_name": "gradle",
|
||||||
|
"stage_type": "build",
|
||||||
|
"category": "java",
|
||||||
|
"content": "#gradle",
|
||||||
|
"created_at": "2021-01-11T17:28:34.000+08:00",
|
||||||
|
"updated_at": "2021-01-11T17:28:36.000+08:00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "c++",
|
||||||
|
"templates": [
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"template_name": "make",
|
||||||
|
"stage_type": "build",
|
||||||
|
"category": "c++",
|
||||||
|
"content": "#make",
|
||||||
|
"created_at": "2021-01-11T17:29:17.000+08:00",
|
||||||
|
"updated_at": "2021-01-11T17:29:18.000+08:00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
|
||||||
|
#### 解除CI服务器绑定
|
||||||
```
|
```
|
||||||
DELETE /api/users/ci/cloud_account/unbind
|
DELETE /api/users/ci/cloud_account/unbind
|
||||||
```
|
```
|
||||||
|
|
|
@ -46,7 +46,7 @@ class AttachmentsController < ApplicationController
|
||||||
uid_logger("#########################file_params####{params["#{params[:file_param_name]}"]}")
|
uid_logger("#########################file_params####{params["#{params[:file_param_name]}"]}")
|
||||||
raise "未上传文件" unless upload_file
|
raise "未上传文件" unless upload_file
|
||||||
|
|
||||||
folder = edu_setting('attachment_folder')
|
folder = file_storage_directory
|
||||||
raise "存储目录未定义" unless folder.present?
|
raise "存储目录未定义" unless folder.present?
|
||||||
|
|
||||||
month_folder = current_month_folder
|
month_folder = current_month_folder
|
||||||
|
|
|
@ -63,6 +63,7 @@ class Ci::BaseController < ApplicationController
|
||||||
if current.ci_cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_TRUSTIE
|
if current.ci_cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_TRUSTIE
|
||||||
connect_to_trustie_ci_database(options)
|
connect_to_trustie_ci_database(options)
|
||||||
else
|
else
|
||||||
|
options = options.merge(db_name: current.login)
|
||||||
connect_to_ci_database(options)
|
connect_to_ci_database(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
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]
|
||||||
|
|
||||||
|
# ======流水线相关接口========== #
|
||||||
|
def list
|
||||||
|
@pipelines = Ci::Pipeline.where('identifier=?', params[:identifier])
|
||||||
|
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])
|
||||||
|
pipeline.save!
|
||||||
|
|
||||||
|
# 默认创建四个初始阶段
|
||||||
|
init_stages = Ci::PipelineStage::INIT_STAGES
|
||||||
|
index = 1
|
||||||
|
init_stages.each do |type, name|
|
||||||
|
pipeline.pipeline_stages.build(
|
||||||
|
stage_name: name,
|
||||||
|
stage_type: type,
|
||||||
|
show_index: index
|
||||||
|
).save!
|
||||||
|
index += 1
|
||||||
|
end
|
||||||
|
render_ok({id: pipeline.id})
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
pipeline = Ci::Pipeline.find(params[:id])
|
||||||
|
if pipeline
|
||||||
|
pipeline.update!(pipeline_name: params[:pipeline_name])
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
pipeline = Ci::Pipeline.find(params[:id])
|
||||||
|
if pipeline
|
||||||
|
pipeline.destroy!
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def content
|
||||||
|
@yaml = "#pipeline \n"
|
||||||
|
pipeline = Ci::Pipeline.find(params[:id])
|
||||||
|
@sync = pipeline.sync
|
||||||
|
@sha = ''
|
||||||
|
stages = pipeline.pipeline_stages
|
||||||
|
if stages && !stages.empty?
|
||||||
|
init_step = stages.first.pipeline_stage_steps.first
|
||||||
|
@yaml += init_step.content + "\n" + "steps:\n"
|
||||||
|
stages = stages.slice(1, stages.size - 1)
|
||||||
|
unless stages.empty?
|
||||||
|
stages.each do |stage|
|
||||||
|
steps = stage.pipeline_stage_steps
|
||||||
|
next unless steps && !steps.empty?
|
||||||
|
steps.each do |step|
|
||||||
|
@yaml += step.content + "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @sync == 1
|
||||||
|
@sha = get_pipeline_file_sha(pipeline.file_name)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# =========阶段相关接口========= #
|
||||||
|
def stages
|
||||||
|
pipeline_id = params[:id]
|
||||||
|
@pipeline_name = Ci::Pipeline.find(pipeline_id).pipeline_name
|
||||||
|
@pipeline_stages = Ci::PipelineStage.where('pipeline_id=?', pipeline_id).order('show_index asc')
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_stage
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
# 修改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])
|
||||||
|
pipeline_stage.save!
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_stage
|
||||||
|
pipeline_stage = Ci::PipelineStage.find(params[:stage_id])
|
||||||
|
if pipeline_stage
|
||||||
|
pipeline_stage.update!(stage_name: params[:stage_name])
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_stage
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
update_stage_index(params[:id], params[:show_index].to_i, -1)
|
||||||
|
pipeline_stage = Ci::PipelineStage.find(params[:stage_id])
|
||||||
|
if pipeline_stage
|
||||||
|
pipeline_stage.destroy!
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_stage_index(pipeline_id, show_index, diff)
|
||||||
|
stages = Ci::Pipeline.find(pipeline_id).pipeline_stages
|
||||||
|
stages.each do |stage|
|
||||||
|
if stage.show_index >= show_index
|
||||||
|
stage.update!(show_index: stage.show_index + diff)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ========步骤相关接口========= #
|
||||||
|
def steps
|
||||||
|
@stage_type = Ci::PipelineStage.find(params[:stage_id]).stage_type
|
||||||
|
@pipeline_stage_steps = Ci::PipelineStageStep.where('stage_id=?', params[:stage_id]).order('show_index asc')
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_step
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
steps = params[:steps]
|
||||||
|
unless steps.empty?
|
||||||
|
steps.each do |step|
|
||||||
|
unless step[:template_id]
|
||||||
|
render_error("请选择模板!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if !step[:id]
|
||||||
|
step = Ci::PipelineStageStep.new(step_name: step[:step_name], stage_id: params[:stage_id],
|
||||||
|
template_id: step[:template_id], content: step[:content], show_index: step[:show_index])
|
||||||
|
step.save!
|
||||||
|
else
|
||||||
|
pipeline_stage_step = Ci::PipelineStageStep.find(step[:id])
|
||||||
|
pipeline_stage_step.update(step_name: step[:step_name], content: step[:content],
|
||||||
|
show_index: step[:show_index], template_id: step[:template_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_stage_step
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
steps = params[:steps]
|
||||||
|
unless steps.empty?
|
||||||
|
steps.each do |step|
|
||||||
|
step = Ci::PipelineStageStep.new(step_name: step[:step_name], stage_id: params[:stage_id],
|
||||||
|
template_id: step[:template_id], content: step[:content], show_index: step[:show_index])
|
||||||
|
step.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_stage_step
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
steps = params[:steps]
|
||||||
|
unless steps.empty?
|
||||||
|
steps.each do |step|
|
||||||
|
pipeline_stage_step = Ci::PipelineStageStep.find(step[:id])
|
||||||
|
if pipeline_stage_step
|
||||||
|
pipeline_stage_step.update(step_name: step[:step_name], content: step[:content], template_id: step[:template_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_stage_step
|
||||||
|
pipeline_stage_step = Ci::PipelineStageStep.find(params[:step_id])
|
||||||
|
if pipeline_stage_step
|
||||||
|
pipeline_stage_step.destroy!
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,56 @@
|
||||||
|
class Ci::TemplatesController < ApplicationController
|
||||||
|
|
||||||
|
def list
|
||||||
|
@templates = Ci::Template.all
|
||||||
|
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
|
||||||
|
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!
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
template = Ci::Template.find(params[:id])
|
||||||
|
template.update!(template_name: params[:template_name],
|
||||||
|
stage_type: params[:stage_type],
|
||||||
|
category: params[:category],
|
||||||
|
parent_category: params[:parent_category],
|
||||||
|
content: params[:content]
|
||||||
|
)
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
template = Ci::Template.find(params[:id])
|
||||||
|
if template
|
||||||
|
template.destroy!
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -17,7 +17,8 @@ module Ci::DbConnectable
|
||||||
password: db_config[:password],
|
password: db_config[:password],
|
||||||
port: db_config[:port]
|
port: db_config[:port]
|
||||||
}
|
}
|
||||||
req_params = req_params.merge(database: "#{current_user.login}_#{db_config[:database]}") unless master_db === true
|
db_name = options[:db_name].blank? ? current_user.login : options[:db_name]
|
||||||
|
req_params = req_params.merge(database: "#{db_name}_#{db_config[:database]}") unless master_db === true
|
||||||
|
|
||||||
db_params = Ci::Database.get_connection_params(req_params)
|
db_params = Ci::Database.get_connection_params(req_params)
|
||||||
@connection = Ci::Database.set_connection(db_params).connection
|
@connection = Ci::Database.set_connection(db_params).connection
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
module Repository::LanguagesPercentagable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def languages_precentagable
|
||||||
|
result = Gitea::Repository::Languages::ListService.call(@owner.login,
|
||||||
|
@repository.identifier, current_user&.gitea_token)
|
||||||
|
|
||||||
|
result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781}
|
||||||
|
def hash_transform_precentagable(hash)
|
||||||
|
total_byte_size = hash.values.sum
|
||||||
|
hash.transform_values { |v|
|
||||||
|
ActionController::Base.helpers
|
||||||
|
.number_to_percentage((v * 100.0 / total_byte_size), precision: 1)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
class RepositoriesController < ApplicationController
|
class RepositoriesController < ApplicationController
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include OperateProjectAbilityAble
|
include OperateProjectAbilityAble
|
||||||
|
include Repository::LanguagesPercentagable
|
||||||
|
|
||||||
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
||||||
before_action :load_repository
|
before_action :load_repository
|
||||||
|
@ -94,11 +95,22 @@ class RepositoriesController < ApplicationController
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
@file = interactor.result
|
@file = interactor.result
|
||||||
# create_new_pr(params)
|
# create_new_pr(params)
|
||||||
|
#如果是更新流水线文件
|
||||||
|
if params[:pipeline_id]
|
||||||
|
update_pipeline(params[:pipeline_id])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
render_error(interactor.error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_pipeline(pipeline_id)
|
||||||
|
pipeline = Ci::Pipeline.find(pipeline_id)
|
||||||
|
if pipeline
|
||||||
|
pipeline.update!(sync: 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update_file
|
def update_file
|
||||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
|
@ -133,6 +145,17 @@ class RepositoriesController < ApplicationController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def readme
|
||||||
|
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
|
||||||
|
|
||||||
|
@readme = result[:status] === :success ? result[:body] : nil
|
||||||
|
render json: @readme
|
||||||
|
end
|
||||||
|
|
||||||
|
def languages
|
||||||
|
render json: languages_precentagable
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_project
|
def find_project
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
|
include ApplicationHelper
|
||||||
include Ci::DbConnectable
|
include Ci::DbConnectable
|
||||||
|
|
||||||
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
|
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
|
||||||
|
@ -79,7 +80,7 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
def attachment_show
|
def attachment_show
|
||||||
file_name = params[:file_name]
|
file_name = params[:file_name]
|
||||||
path = params[:path] || edu_setting('attachment_folder')
|
path = params[:path] || file_storage_directory
|
||||||
send_file "#{path}/#{file_name}", :filename => "#{file_name}",
|
send_file "#{path}/#{file_name}", :filename => "#{file_name}",
|
||||||
:type => 'game',
|
:type => 'game',
|
||||||
:disposition => 'attachment' #inline can open in browser
|
:disposition => 'attachment' #inline can open in browser
|
||||||
|
|
|
@ -322,7 +322,15 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def absolute_path(file_path)
|
def absolute_path(file_path)
|
||||||
File.join(edu_setting('attachment_folder'), file_path)
|
file_root_directory + File.join(edu_setting('attachment_folder'), file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_root_directory
|
||||||
|
Rails.root.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_storage_directory
|
||||||
|
file_root_directory + edu_setting('attachment_folder')
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_path(file)
|
def local_path(file)
|
||||||
|
|
|
@ -11,7 +11,7 @@ module RepositoriesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def download_type(str)
|
def download_type(str)
|
||||||
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx)
|
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx dot)
|
||||||
default_type.include?(str&.downcase)
|
default_type.include?(str&.downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ module RepositoriesHelper
|
||||||
default_type.include?(str&.downcase)
|
default_type.include?(str&.downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_readme_type?(str)
|
def is_readme?(type, str)
|
||||||
return false if str.blank?
|
return false if type != 'file' || str.blank?
|
||||||
readme_types = ["readme.md", "readme", "readme_en.md", "readme_zh.md", "readme_en", "readme_zh"]
|
readme_types = ["readme.md", "readme", "readme_en.md", "readme_zh.md", "readme_en", "readme_zh"]
|
||||||
readme_types.include?(str.to_s.downcase)
|
readme_types.include?(str.to_s.downcase)
|
||||||
end
|
end
|
||||||
|
@ -72,4 +72,15 @@ module RepositoriesHelper
|
||||||
def render_format_time_with_date(date)
|
def render_format_time_with_date(date)
|
||||||
date.to_time.strftime("%Y-%m-%d %H:%M")
|
date.to_time.strftime("%Y-%m-%d %H:%M")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def decode64_content(entry, owner, repo, ref, path=nil)
|
||||||
|
if is_readme?(entry['type'], entry['name'])
|
||||||
|
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, entry['path'], ref: ref)['content']
|
||||||
|
readme_render_decode64_content(content, path)
|
||||||
|
else
|
||||||
|
file_type = entry['name'].to_s.split(".").last
|
||||||
|
return entry['content'] if download_type(file_type)
|
||||||
|
render_decode64_content(entry['content'])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,9 +11,9 @@ class SyncRepoUpdateTimeJob < ApplicationJob
|
||||||
private
|
private
|
||||||
def gitea_repo_updated_at(project)
|
def gitea_repo_updated_at(project)
|
||||||
admin = User.where(admin: true).select(:id, :gitea_token, :gitea_uid).last
|
admin = User.where(admin: true).select(:id, :gitea_token, :gitea_uid).last
|
||||||
|
puts "########## project id: #{project.id}"
|
||||||
|
|
||||||
return nil if project.gpid.blank?
|
return nil if project.gpid.blank?
|
||||||
|
|
||||||
result = Gitea::Repository::GetByIdService.call(project.gpid, admin.gitea_token)
|
result = Gitea::Repository::GetByIdService.call(project.gpid, admin.gitea_token)
|
||||||
|
|
||||||
result[:status] === :success ? result[:body]['updated_at'] : nil
|
result[:status] === :success ? result[:body]['updated_at'] : nil
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
class Base64ImageConverter
|
class Base64ImageConverter
|
||||||
BASE64_HEAD = 'data:image/jpeg;base64,'.freeze
|
# BASE64_HEAD = 'data:image/jpeg;base64,'.freeze
|
||||||
|
BASE64_HEAD_ARRAY = ['data:image/jpeg;base64,', 'data:image/jpg;base64,',
|
||||||
|
'data:image/png;base64,', 'data:image/gif;base64,']
|
||||||
|
|
||||||
Error = Class.new(StandardError)
|
Error = Class.new(StandardError)
|
||||||
OutLimit = Class.new(Error)
|
OutLimit = Class.new(Error)
|
||||||
|
@ -27,11 +29,20 @@ class Base64ImageConverter
|
||||||
private
|
private
|
||||||
|
|
||||||
def valid_base64?(data)
|
def valid_base64?(data)
|
||||||
data&.start_with?(BASE64_HEAD)
|
# data&.start_with?(BASE64_HEAD)
|
||||||
|
BASE64_HEAD_ARRAY.include? base64_head_data(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def base64_head_data(data)
|
||||||
|
data&.split(',')[0] + ','
|
||||||
|
end
|
||||||
|
|
||||||
|
def base64_head(data)
|
||||||
|
valid_base64?(data) ? base64_head_data(data) : ''
|
||||||
end
|
end
|
||||||
|
|
||||||
def image_data(data)
|
def image_data(data)
|
||||||
data[BASE64_HEAD.size..-1]
|
data[base64_head(data).size..-1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def size_limit
|
def size_limit
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ci_pipelines
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# pipeline_name :string(255) not null
|
||||||
|
# pipeline_status :string(255) default("unknown"), not null
|
||||||
|
# file_name :string(255) not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# login :string(255)
|
||||||
|
# sync :integer default("0"), not null
|
||||||
|
# identifier :string(255)
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::Pipeline < Ci::LocalBase
|
||||||
|
validates :pipeline_name, presence: {message: "流水线名称不能为空"}
|
||||||
|
validates :file_name, presence: {message: "流水线文件名称不能为空"}
|
||||||
|
validates :identifier, presence: {message: "项目identifier不能为空"}
|
||||||
|
|
||||||
|
has_many :pipeline_stages, -> { reorder(show_index: :asc) }, foreign_key: "pipeline_id", :class_name => 'Ci::PipelineStage', dependent: :destroy
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ci_pipeline_stages
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# stage_name :string(255) not null
|
||||||
|
# stage_type :string(255) not null
|
||||||
|
# pipeline_id :integer not null
|
||||||
|
# show_index :integer default("0"), not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::PipelineStage < Ci::LocalBase
|
||||||
|
|
||||||
|
validates :stage_name, presence: {message: "阶段名称不能为空"}
|
||||||
|
validates :stage_type, presence: {message: "阶段类型不能为空"}
|
||||||
|
|
||||||
|
belongs_to :pipeline, foreign_key: :pipeline_id, :class_name => 'Ci::Pipeline'
|
||||||
|
has_many :pipeline_stage_steps, -> { reorder(show_index: :asc) }, foreign_key: "stage_id", :class_name => 'Ci::PipelineStageStep', dependent: :destroy
|
||||||
|
|
||||||
|
INIT_STAGES = {init:"初始化", build:"编译构建", deploy:"部署", confirm:"确认"}.freeze
|
||||||
|
CUSTOMIZE_STAGE_TYPE = 'customize'
|
||||||
|
INIT_STAGE_TYPE = 'init'
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ci_pipeline_stage_steps
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# step_name :string(255) not null
|
||||||
|
# stage_id :integer not null
|
||||||
|
# template_id :integer
|
||||||
|
# content :text(65535)
|
||||||
|
# show_index :integer default("0"), not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::PipelineStageStep < Ci::LocalBase
|
||||||
|
|
||||||
|
validates :step_name, presence: {message: "步骤名称不能为空"}
|
||||||
|
validates :stage_id, presence: {message: "阶段id不能为空"}
|
||||||
|
|
||||||
|
belongs_to :pipeline_stage, foreign_key: :stage_id, :class_name => 'Ci::PipelineStage'
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ci_templates
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# template_name :string(255) not null
|
||||||
|
# stage_type :string(255) not null
|
||||||
|
# category :string(255) not null
|
||||||
|
# content :text(65535) not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# parent_category :string(255)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_ci_templates_on_stage_type (stage_type)
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::Template < Ci::LocalBase
|
||||||
|
validates :template_name, presence: {message: "模板名称不能为空"}
|
||||||
|
validates :stage_type, presence: {message: "阶段类型不能为空"}
|
||||||
|
validates :category, presence: {message: "模板类型不能为空"}
|
||||||
|
end
|
|
@ -128,7 +128,7 @@ class Project < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def members_user_infos
|
def members_user_infos
|
||||||
members.joins(:roles).where("roles.name in ('Manager', 'Developer')").joins("left join users on members.user_id = users.id ").includes(:user).where("users.type = ?", "User")
|
members.joins(:roles).where("roles.name in ('Manager', 'Developer', 'Reporter')").joins("left join users on members.user_id = users.id ").includes(:user).where("users.type = ?", "User")
|
||||||
# members.joins("left join users on members.user_id = users.id").select("users.id", "users.login","users.firstname","users.lastname")
|
# members.joins("left join users on members.user_id = users.id").select("users.id", "users.login","users.firstname","users.lastname")
|
||||||
# .pluck("users.id", "users.login","users.lastname", "users.firstname")
|
# .pluck("users.id", "users.login","users.lastname", "users.firstname")
|
||||||
end
|
end
|
||||||
|
|
|
@ -178,8 +178,10 @@ class Gitea::ClientService < ApplicationService
|
||||||
def get_body_by_status(status, body)
|
def get_body_by_status(status, body)
|
||||||
body, message =
|
body, message =
|
||||||
case status
|
case status
|
||||||
|
when 401 then [nil, "401"]
|
||||||
when 404 then [nil, "404"]
|
when 404 then [nil, "404"]
|
||||||
when 403 then [nil, "403"]
|
when 403 then [nil, "403"]
|
||||||
|
when 500 then [nil, "500"]
|
||||||
else
|
else
|
||||||
if body.present?
|
if body.present?
|
||||||
body = JSON.parse(body)
|
body = JSON.parse(body)
|
||||||
|
@ -198,7 +200,7 @@ class Gitea::ClientService < ApplicationService
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_body(body)
|
def fix_body(body)
|
||||||
return [body, nil] if body.is_a? Array
|
return [body, nil] if body.is_a?(Array) || body.is_a?(Hash)
|
||||||
|
|
||||||
body['message'].blank? ? [body, nil] : [nil, body['message']]
|
body['message'].blank? ? [body, nil] : [nil, body['message']]
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Get languages and number of bytes of code written
|
||||||
|
class Gitea::Repository::Languages::ListService < Gitea::ClientService
|
||||||
|
attr_reader :owner, :repo, :token
|
||||||
|
|
||||||
|
# owner: owner of the repo
|
||||||
|
# repo: the name of repository
|
||||||
|
# token: token of gitea user
|
||||||
|
# eq: Gitea::Repository::Languages::ListService.call(@owner.identifier,
|
||||||
|
# @project.identifier, current_user&.gitea_token)
|
||||||
|
def initialize(owner, repo, token)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
@args = token
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
response = get(url, params)
|
||||||
|
|
||||||
|
status, message, body = render_response(response)
|
||||||
|
json_format(status, message, body)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def params
|
||||||
|
{}.merge(token: token)
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
"/repos/#{owner}/#{repo}/languages".freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def json_format(status, message, body)
|
||||||
|
case status
|
||||||
|
when 200 then success(body)
|
||||||
|
else
|
||||||
|
error(message, status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Gets the preferred README for a repository.
|
||||||
|
class Gitea::Repository::Readme::GetService < Gitea::ClientService
|
||||||
|
attr_reader :owner, :repo, :ref, :token
|
||||||
|
|
||||||
|
# owner: owner of the repo
|
||||||
|
# repo: name of the repo
|
||||||
|
# name: The name of the commit/branch/tag. Default: the repository’s default branch (usually master)
|
||||||
|
# eg:
|
||||||
|
# Gitea::Repository::Readme::GetService.call(user.login, repo.identifier, ref, user.gitea_token)
|
||||||
|
def initialize(owner, repo, ref, token=nil)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
@ref = ref || 'master'
|
||||||
|
@token = token
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
response = get(url, params)
|
||||||
|
status, message, body = render_response(response)
|
||||||
|
json_format(status, message, body)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def params
|
||||||
|
Hash.new.merge(token: token, ref: ref)
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
"/repos/#{owner}/#{repo}/readme".freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def json_format(status, message, body)
|
||||||
|
case status
|
||||||
|
when 200 then success(body)
|
||||||
|
when 404 then error(message, 404)
|
||||||
|
else error(message, status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
json.id pipeline_stage_step.id
|
||||||
|
json.step_name pipeline_stage_step.step_name
|
||||||
|
json.stage_id pipeline_stage_step.stage_id
|
||||||
|
json.show_index pipeline_stage_step.show_index
|
||||||
|
json.content pipeline_stage_step.content
|
||||||
|
json.template_id pipeline_stage_step.template_id
|
||||||
|
json.category stage_type == 'customize' ? Ci::Template.find(pipeline_stage_step.template_id).parent_category : Ci::Template.find(pipeline_stage_step.template_id).category
|
||||||
|
json.created_at pipeline_stage_step.created_at
|
||||||
|
json.updated_at pipeline_stage_step.updated_at
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
json.id pipeline_stage.id
|
||||||
|
json.stage_name pipeline_stage.stage_name
|
||||||
|
json.stage_type pipeline_stage.stage_type
|
||||||
|
json.pipeline_id pipeline_stage.pipeline_id
|
||||||
|
json.pipeline_name pipeline_name
|
||||||
|
json.show_index pipeline_stage.show_index
|
||||||
|
json.created_at pipeline_stage.created_at
|
||||||
|
json.updated_at pipeline_stage.updated_at
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
json.id pipeline.id
|
||||||
|
json.pipeline_name pipeline.pipeline_name
|
||||||
|
json.pipeline_status pipeline.pipeline_status
|
||||||
|
json.file_name pipeline.file_name
|
||||||
|
json.sync pipeline.sync
|
||||||
|
json.identifier pipeline.identifier
|
||||||
|
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")
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.content @yaml
|
||||||
|
json.sync @sync
|
||||||
|
json.sha @sha
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.pipelines @pipelines do |pipeline|
|
||||||
|
json.partial! "/ci/pipelines/list", pipeline: pipeline
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.stages @pipeline_stages do |pipeline_stage|
|
||||||
|
json.partial! "/ci/pipeline_stages/list", pipeline_stage: pipeline_stage, pipeline_name: @pipeline_name
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.steps @pipeline_stage_steps do |pipeline_stage_step|
|
||||||
|
json.partial! "/ci/pipeline_stage_steps/list", pipeline_stage_step: pipeline_stage_step, stage_type: @stage_type
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
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.created_at template.created_at
|
||||||
|
json.updated_at template.updated_at
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
json.category category
|
||||||
|
json.templates templates do |template|
|
||||||
|
json.partial! "/ci/templates/list", template: template
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.templates @templates do |template|
|
||||||
|
json.partial! "/ci/templates/list", template: template
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.array! @category_templates do |category, templates|
|
||||||
|
json.partial! "/ci/templates/templates_by_stage", category: category, templates: templates
|
||||||
|
end
|
|
@ -1,7 +1,9 @@
|
||||||
json.commit do
|
if latest_commit.blank?
|
||||||
json.message entry['latest_commit']['message']
|
json.nil!
|
||||||
json.sha entry['latest_commit']['sha']
|
else
|
||||||
json.created_at render_format_time_with_unix(entry['latest_commit']['created_at'].to_i)
|
json.message latest_commit['message']
|
||||||
json.time_from_now time_from_now(render_format_time_with_unix(entry['latest_commit']['created_at'].to_i))
|
json.sha latest_commit['sha']
|
||||||
json.created_at_unix entry['latest_commit']['created_at']
|
json.created_at render_format_time_with_unix(latest_commit['created_at'].to_i)
|
||||||
|
json.time_from_now time_from_now(render_format_time_with_unix(latest_commit['created_at'].to_i))
|
||||||
|
json.created_at_unix latest_commit['created_at']
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,18 +8,15 @@ if @project.forge?
|
||||||
json.path entry['path']
|
json.path entry['path']
|
||||||
json.type entry['type']
|
json.type entry['type']
|
||||||
json.size entry['size']
|
json.size entry['size']
|
||||||
json.content entry['content'].present? && !direct_download ? render_decode64_content(entry['content']) : ""
|
|
||||||
|
json.content decode64_content(entry, @owner, @repository, @ref)
|
||||||
json.target entry['target']
|
json.target entry['target']
|
||||||
json.download_url entry['download_url']
|
json.download_url entry['download_url']
|
||||||
json.direct_download direct_download
|
json.direct_download direct_download
|
||||||
json.image_type image_type
|
json.image_type image_type
|
||||||
json.is_readme_file is_readme_type?(file_name)
|
json.is_readme_file is_readme?(entry['type'], entry['name'])
|
||||||
if entry['latest_commit']
|
json.commit do
|
||||||
if entry['type'] != 'file'
|
json.partial! 'last_commit', latest_commit: entry['latest_commit']
|
||||||
json.partial! 'last_commit', entry: entry
|
|
||||||
else
|
|
||||||
json.commit nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,8 +34,11 @@ if @project.educoder?
|
||||||
json.direct_download false
|
json.direct_download false
|
||||||
json.image_type false
|
json.image_type false
|
||||||
json.is_readme_file false
|
json.is_readme_file false
|
||||||
if entry['latest_commit']
|
json.commit do
|
||||||
# json.partial! 'last_commit', entry: entry
|
json.message entry['title']
|
||||||
json.partial! 'repositories/simple_entry', locals: { entry: entry }
|
json.time_from_now entry['time']
|
||||||
|
json.sha nil
|
||||||
|
json.created_at_unix nil
|
||||||
|
json.created_at nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,20 +51,11 @@ if @project.forge?
|
||||||
json.sha entry['sha']
|
json.sha entry['sha']
|
||||||
json.type entry['type']
|
json.type entry['type']
|
||||||
json.size entry['size']
|
json.size entry['size']
|
||||||
content =
|
json.is_readme_file is_readme?(entry['type'], entry['name'])
|
||||||
if is_readme_type?(entry['name'])
|
json.content decode64_content(entry, @owner, @repository, @ref, @path)
|
||||||
is_readme_file = true
|
|
||||||
content = Gitea::Repository::Entries::GetService.call(@owner, @project.identifier, entry['name'], ref: @ref)['content']
|
|
||||||
readme_render_decode64_content(content, @path)
|
|
||||||
else
|
|
||||||
is_readme_file = false
|
|
||||||
entry['content']
|
|
||||||
end
|
|
||||||
json.is_readme_file is_readme_file
|
|
||||||
json.content content
|
|
||||||
json.target entry['target']
|
json.target entry['target']
|
||||||
if entry['latest_commit']
|
json.commit do
|
||||||
json.partial! 'last_commit', entry: entry
|
json.partial! 'last_commit', latest_commit: entry['latest_commit']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,7 @@ module Educoderplus
|
||||||
allow do
|
allow do
|
||||||
origins '*'
|
origins '*'
|
||||||
# location of your api
|
# location of your api
|
||||||
resource '/*', :headers => :any, :methods => [:get, :post, :delete, :options, :put]
|
resource '/*', :headers => :any, :methods => [:get, :post, :delete, :options, :put, :patch]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,32 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources :templates, only: [:list,:templates_by_stage,:create,:update,:destroy] do
|
||||||
|
collection do
|
||||||
|
get :list
|
||||||
|
get :templates_by_stage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
resources :pipelines do
|
||||||
|
collection do
|
||||||
|
get :list
|
||||||
|
end
|
||||||
|
member do
|
||||||
|
get :content
|
||||||
|
get :stages
|
||||||
|
post :create_stage
|
||||||
|
post :create_trustie_pipeline
|
||||||
|
delete :delete_stage, :path => ":stage_id/delete_stage", to: 'pipelines#delete_stage'
|
||||||
|
put :update_stage, :path => ":stage_id/update_stage", to: 'pipelines#update_stage'
|
||||||
|
get :stage_steps, :path => ":stage_id/steps", to: 'pipelines#steps'
|
||||||
|
post :create_stage_step, :path => ":stage_id/create_step", to: 'pipelines#create_stage_step'
|
||||||
|
post :stage_step, :path => ":stage_id/stage_step", to: 'pipelines#stage_step'
|
||||||
|
delete :delete_stage_step, :path => ":stage_id/:step_id/delete_step", to: 'pipelines#delete_stage_step'
|
||||||
|
put :update_stage_step, :path => ":stage_id/update_step", to: 'pipelines#update_stage_step'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# resources :repos, only: :index do
|
# resources :repos, only: :index do
|
||||||
# collection do
|
# collection do
|
||||||
# get 'get_trustie_pipeline', to: 'builds#get_trustie_pipeline', as: 'get_trustie_pipeline'
|
# get 'get_trustie_pipeline', to: 'builds#get_trustie_pipeline', as: 'get_trustie_pipeline'
|
||||||
|
@ -332,6 +358,8 @@ Rails.application.routes.draw do
|
||||||
post :sync_mirror
|
post :sync_mirror
|
||||||
get :top_counts
|
get :top_counts
|
||||||
get 'commits/:sha', to: 'repositories#commit', as: 'commit'
|
get 'commits/:sha', to: 'repositories#commit', as: 'commit'
|
||||||
|
get 'readme'
|
||||||
|
get 'languages'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateCiTemplates < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :ci_templates do |t|
|
||||||
|
t.string :template_name, null: false, comment: '模板名称'
|
||||||
|
t.string :stage_type, null: false, comment: '模板所属阶段类型:init/build/deploy/customize/confirm'
|
||||||
|
t.string :category, null: false, comment: '模板分类'
|
||||||
|
t.text :content, null: false, comment: '模板yml内容'
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :ci_templates, [:stage_type]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
class CreateCiPipelines < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :ci_pipelines do |t|
|
||||||
|
t.string :pipeline_name, null: false, comment: '流水线名称'
|
||||||
|
t.string :pipeline_status, null: false, comment: 'successed/failed/running/errored/pending/killed/unknown' , default: 'unknown'
|
||||||
|
t.string :file_name, null: false, comment: '文件名称'
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
class CreateCiPipelineStages < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :ci_pipeline_stages do |t|
|
||||||
|
t.string :stage_name, null: false, comment: '阶段名称'
|
||||||
|
t.string :stage_type, null: false, comment: '阶段类型:init/build/deploy/customize/confirm'
|
||||||
|
t.integer :pipeline_id, null: false, comment: '阶段所属流水线id'
|
||||||
|
t.integer :show_index, null: false, comment: '阶段排序', default: 0
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
class CreateCiPipelineStageSteps < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :ci_pipeline_stage_steps do |t|
|
||||||
|
t.string :step_name, null: false, comment: '步骤名称'
|
||||||
|
t.integer :stage_id, null: false, comment: '阶段id'
|
||||||
|
t.integer :template_id, comment: '模板id'
|
||||||
|
t.text :content
|
||||||
|
t.integer :show_index, null: false, comment: '阶段排序', default: 0
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddParentCategoryToCiTemplates < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :ci_templates, :parent_category, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddLoginToCiPipelines < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :ci_pipelines, :login, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddSyncAndProjectIdToCiPipelines < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :ci_pipelines, :sync, :integer, null: false, comment: '0 未同步到gitea,1 已同步', default: 0
|
||||||
|
add_column :ci_pipelines, :identifier, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -3445,4 +3445,12 @@ INSERT INTO `roles` (`id`, `name`, `position`, `assignable`, `builtin`, `permiss
|
||||||
(15, 'Contestant', 13, 1, 0, '---\n- :add_project\n- :projects_attachments_download\n- :add_course\n- :course_attachments_download\n- :view_course_files\n- :select_contest_modules\n- :quote_project\n- :contest_attachments_download\n- :notificationcomment_contestnotifications\n- :add_messages\n- :edit_own_messages\n- :delete_own_messages\n- :view_calendar\n- :manage_files\n- :view_files\n- :view_gantt\n- :view_issues\n- :save_queries\n- :browse_repository\n- :view_changesets\n', 'default');
|
(15, 'Contestant', 13, 1, 0, '---\n- :add_project\n- :projects_attachments_download\n- :add_course\n- :course_attachments_download\n- :view_course_files\n- :select_contest_modules\n- :quote_project\n- :contest_attachments_download\n- :notificationcomment_contestnotifications\n- :add_messages\n- :edit_own_messages\n- :delete_own_messages\n- :view_calendar\n- :manage_files\n- :view_files\n- :view_gantt\n- :view_issues\n- :save_queries\n- :browse_repository\n- :view_changesets\n', 'default');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of ci_templates
|
||||||
|
-- ----------------------------
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO `ci_templates` VALUES (2,'linux/amd64','init','初始化','kind: pipeline\r\ntype: docker\r\nname: default\r\nplatform:\r\n os: linux\r\n arch: amd64','2021-01-12 02:44:23','2021-01-12 02:44:23',NULL),(3,'linux/arm64','init','初始化','kind: pipeline\r\ntype: docker\r\nname: default\r\nplatform:\r\n os: linux\r\n arch: arm64','2021-01-12 02:45:17','2021-01-12 02:45:17',NULL),(4,'maven','build','Java','- name: maven\r\n image: maven:3-jdk-10\r\n commands:\r\n - mvn install -DskipTests=true','2021-01-12 02:53:29','2021-01-12 02:53:29','编译构建'),(5,'maven单元测试','customize','Java','- name: maven\r\n image: maven:3-jdk-10\r\n commands:\r\n - mvn test','2021-01-12 02:53:29','2021-01-12 02:53:29','单元测试'),(6,'golang单元测试','customize','Golang','- name: golang单元测试\r\n image: golang\r\n commands:\r\n - go test','2021-01-12 03:03:35','2021-01-12 03:03:35','单元测试'),(9,'gradle单元测试','customize','Java','- name: gradle\r\n image: gradle:jdk10\r\n commands:\r\n - gradle test','2021-01-12 03:05:33','2021-01-12 03:05:33','单元测试'),(7,'golang编译','build','Golang','- name: golang编译\r\n image: golang\r\n commands:\r\n - go build','2021-01-12 03:03:35','2021-01-12 03:03:35','编译构建'),(8,'gradle','build','Java','- name: gradle\r\n image: gradle:jdk10\r\n commands:\r\n - gradle build -x test','2021-01-12 03:05:33','2021-01-12 03:05:33','编译构建'),(10,'远程主机部署','deploy','部署','# 根据实际情况修改主机ip、账号、密码\r\n# 需要将软件包与部署脚本提前上传到远程主机(见文件上传模板)\r\n\r\n- name: 远程主机部署\r\n image: appleboy/drone-ssh\r\n settings:\r\n host: 192.168.1.1\r\n username: username\r\n password: \'pasword\'\r\n port: 22\r\n commands:\r\n - chmod +x /home/deploy.sh\r\n - ./home/deploy.sh','2021-01-12 03:32:46','2021-01-12 03:32:46','部署'),(11,'远程命令','customize','工具','- name: 远程命令\r\n image: appleboy/drone-ssh\r\n settings:\r\n host: 192.168.0.1\r\n username: username\r\n password: \'pwd\'\r\n port: 22\r\n script:\r\n - echo \'hello world!\'','2021-01-12 03:40:38','2021-01-12 03:40:38','其他'),(12,'上传文件','customize','工具','# 修改目标服务器的ip、账号密码以及上传路径\r\n# 本模板示例为上传软件包和部署脚本到home目录\r\n\r\n- name: 上传文件\r\n image: appleboy/drone-scp\r\n settings:\r\n host: 192.168.1.1\r\n username: username\r\n password: \'password\'\r\n port: 22\r\n target: /home\r\n source: \r\n - target/*.jar\r\n - deploy.sh','2021-01-12 03:40:55','2021-01-12 03:40:55','其他'),(17,'make-c','build','C语言','- name: 编译\r\n image: gcc\r\n commands:\r\n - ./configure\r\n - make','2021-01-15 01:19:38','2021-01-15 01:19:38','编译构建'),(19,'make-c++','build','C++','- name: 编译构建\r\n image: gcc\r\n commands:\r\n - ./configure\r\n - make','2021-01-15 01:21:05','2021-01-15 01:21:05','编译构建'),(20,'python','build','Python','- name: 编译构建\r\n image: python\r\n commands:\r\n - pip install -r requirements.txt','2021-01-15 01:22:36','2021-01-15 01:22:36','编译构建'),(21,'Docker镜像构建','build','Docker镜像构建','# 构建Docker镜像并推送到仓库\r\n# 定义镜像Hub路径以及账号密码\r\n- name: Docker镜像构建\r\n image: plugins/docker\r\n settings:\r\n username: username\r\n password: pwd\r\n repo: repoUrl\r\n tags: latest','2021-01-15 01:23:16','2021-01-15 01:23:16','编译构建'),(22,'空白模板','customize','customize','','2021-01-15 02:53:02','2021-01-15 02:53:02','其他'),(23,'空白模板','build','自定义','','2021-01-15 03:27:33','2021-01-15 03:27:33','编译构建');
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|
Loading…
Reference in New Issue