forked from Gitlink/forgeplus
add webhook
This commit is contained in:
commit
c748f4eaed
|
@ -4,4 +4,7 @@ class Projects::BaseController < ApplicationController
|
|||
before_action :load_project
|
||||
before_action :load_repository
|
||||
|
||||
def require_manager!
|
||||
return render_forbidden('你没有权限操作') unless current_user.admin? || @project.manager?(current_user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
class Projects::WebhooksController < Projects::BaseController
|
||||
before_action :require_manager!
|
||||
before_action :find_webhook, only:[:edit, :update, :destroy, :tasks, :test]
|
||||
|
||||
def index
|
||||
@webhooks = @project.webhooks
|
||||
@webhooks = kaminari_paginate(@webhooks)
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
return render_error("webhooks数量已到上限!请删除暂不使用的webhooks以进行添加操作") if @project.webhooks.size > 19
|
||||
return render_error("参数错误.") unless webhook_params.present?
|
||||
form = Projects::Webhooks::CreateForm.new(webhook_params)
|
||||
return render json: {status: -1, message: form.errors} unless form.validate!
|
||||
response = Gitea::Repository::Webhooks::CreateService.new(operating_token, @project&.owner&.login, @project&.identifier, gitea_webhooks_params).call
|
||||
if response[0] == 201
|
||||
@webhook = response[2]
|
||||
else
|
||||
render_error("创建失败.")
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def edit
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
return render_error("参数错误.") unless webhook_params.present?
|
||||
form = Projects::Webhooks::CreateForm.new(webhook_params)
|
||||
return render json: {status: -1, message: form.errors} unless form.validate!
|
||||
response = Gitea::Repository::Webhooks::UpdateService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id, gitea_webhooks_params)
|
||||
if response[0] == 200
|
||||
@webhook = response[2]
|
||||
render_ok
|
||||
else
|
||||
render_error("更新失败.")
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
response = Gitea::Repository::Webhooks::DeleteService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id)
|
||||
if response[0] == 204
|
||||
@webhook = response[2]
|
||||
render_ok
|
||||
else
|
||||
render_error("删除失败.")
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def tasks
|
||||
@tasks = @webhook.tasks.where(is_delivered: true).order("delivered desc")
|
||||
@tasks = kaminari_paginate(@tasks)
|
||||
end
|
||||
|
||||
def test
|
||||
ActiveRecord::Base.transaction do
|
||||
response = Gitea::Repository::Webhooks::TestService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id)
|
||||
if response[0] == 204
|
||||
render_ok
|
||||
else
|
||||
render_error("测试推送失败.")
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
def find_webhook
|
||||
@webhook = @project.webhooks.find_by_id(params[:id])
|
||||
return render_not_found if @webhook.nil?
|
||||
end
|
||||
|
||||
def webhook_params
|
||||
params.require(:webhook).permit(:url, :type, :http_method, :content_type, :secret, :active, :branch_filter, events: [])
|
||||
end
|
||||
|
||||
def webhook_type
|
||||
webhook_params.fetch(:type, "gitea")
|
||||
end
|
||||
|
||||
def webhook_branch_filter
|
||||
webhook_params.fetch(:branch_filter, "*")
|
||||
end
|
||||
|
||||
def gitea_webhooks_params
|
||||
{
|
||||
active: webhook_params[:active],
|
||||
branch_filter: webhook_branch_filter,
|
||||
config: {
|
||||
content_type: webhook_params[:content_type],
|
||||
url: webhook_params[:url],
|
||||
http_method: webhook_params[:http_method],
|
||||
secret: webhook_params[:secret]
|
||||
},
|
||||
events: webhook_params[:events],
|
||||
type: webhook_type,
|
||||
}
|
||||
end
|
||||
|
||||
def operating_token
|
||||
@project.member?(current_user) ? current_user.gitea_token : @project&.owner&.gitea_token
|
||||
end
|
||||
end
|
|
@ -867,3 +867,674 @@ await octokit.request('GET /api/jasder/jasder_test/sub_entries.json')
|
|||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 获取仓库webhooks列表
|
||||
获取仓库webhooks列表
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/webhooks.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET /api/:owner/:repo/webhooks.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|url |string|地址|
|
||||
|http_method |string|请求方式|
|
||||
|is_active |bool |是否激活|
|
||||
|type |string|类型|
|
||||
|last_status |string|最后一次推送的状态|
|
||||
|create_time |string|创建时间|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"total_count": 4,
|
||||
"webhooks": [
|
||||
{
|
||||
"id": 2,
|
||||
"url": "https://oapi.dingtalk.com/robot/send?access_token=7e1e19d0eddb6a5e33c5c2c4e66f4c88f9437184b9ed2c2653194c6374c7d513",
|
||||
"http_method": "",
|
||||
"is_active": true,
|
||||
"type": "dingtalk",
|
||||
"last_status": "succeed",
|
||||
"create_time": "2021-07-12 10:50:07"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"url": "http://localhost:3000",
|
||||
"http_method": "GET",
|
||||
"is_active": true,
|
||||
"type": "gitea",
|
||||
"last_status": "succeed",
|
||||
"create_time": "2021-07-26 10:03:45"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"url": "http://localhost:10081",
|
||||
"http_method": "POST",
|
||||
"is_active": true,
|
||||
"type": "gitea",
|
||||
"last_status": "waiting",
|
||||
"create_time": "2021-07-26 16:56:53"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"url": "http://localhost:3001",
|
||||
"http_method": "POST",
|
||||
"is_active": true,
|
||||
"type": "gitea",
|
||||
"last_status": "fail",
|
||||
"create_time": "2021-07-26 16:58:23"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 获取仓库单个webhook
|
||||
获取仓库单个webhook
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET /api/:owner/:repo/webhooks/:id/edit.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|id |是||integer|webhook ID|
|
||||
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|url |string|地址|
|
||||
|content_type |string|POST Content Type|
|
||||
|http_method |string|请求方式|
|
||||
|secret| |string|密钥|
|
||||
|is_active |bool |是否激活|
|
||||
|type |string|类型|
|
||||
|last_status |string|最后一次推送的状态, waiting 等待,fail 失败,succeed 成功|
|
||||
|branch_filter |string|分支过滤|
|
||||
|events |string|触发条件|
|
||||
|create_time |string|创建时间|
|
||||
|
||||
|
||||
参数| 含义|
|
||||
--------- | ------- | ------- |
|
||||
|create|创建分支或标签|
|
||||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|pull_request_milestone|合并请求被记录于里程碑中|
|
||||
|pull_request_comment|合并请求被评论|
|
||||
|pull_request_review_approved|合并请求被批准|
|
||||
|pull_request_review_rejected|合并请求被拒绝|
|
||||
|pull_request_review_comment|合并请求被提出审查意见|
|
||||
|pull_request_sync|合并请求被同步|
|
||||
|repository|创建或删除仓库|
|
||||
|release|版本发布|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3,
|
||||
"http_method": "GET",
|
||||
"content_type": "form",
|
||||
"url": "http://localhost:3000",
|
||||
"secret": "123456",
|
||||
"last_status": "succeed",
|
||||
"is_active": true,
|
||||
"type": "gitea",
|
||||
"create_time": "2021-07-26 10:03:45",
|
||||
"branch_filter": "*",
|
||||
"events": [
|
||||
"create",
|
||||
"delete",
|
||||
"fork",
|
||||
"issues",
|
||||
"issue_assign",
|
||||
"issue_label",
|
||||
"issue_milestone",
|
||||
"issue_comment",
|
||||
"push",
|
||||
"pull_request",
|
||||
"pull_request_assign",
|
||||
"pull_request_label",
|
||||
"pull_request_milestone",
|
||||
"pull_request_comment",
|
||||
"pull_request_review",
|
||||
"pull_request_sync",
|
||||
"repository",
|
||||
"release"
|
||||
]
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 添加仓库webhook
|
||||
添加仓库webhook
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/:owner/:repo/webhooks.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| | string |用户登录名 |
|
||||
|repo |是| | string |项目标识identifier |
|
||||
|webhook.url |是| | string |目标url |
|
||||
|webhook.type |否| | string |类型|
|
||||
|webhook.http_method |是| | string | http方法, POST和GET |
|
||||
|webhook.content_type |是| | string | POST Content Type |
|
||||
|webhook.secret |否| | string |密钥文本|
|
||||
|webhook.active |是| | bool | 是否激活|
|
||||
|webhook.branch_filter|否| |string|分支过滤|
|
||||
|webhook.events |否| |array|触发事件|
|
||||
|
||||
触发事件字段说明
|
||||
|
||||
参数| 含义|
|
||||
--------- | ------- | ------- |
|
||||
|create|创建分支或标签|
|
||||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|pull_request_milestone|合并请求被记录于里程碑中|
|
||||
|pull_request_comment|合并请求被评论|
|
||||
|pull_request_review_approved|合并请求被批准|
|
||||
|pull_request_review_rejected|合并请求被拒绝|
|
||||
|pull_request_review_comment|合并请求被提出审查意见|
|
||||
|pull_request_sync|合并请求被同步|
|
||||
|repository|创建或删除仓库|
|
||||
|release|版本发布|
|
||||
|
||||
|
||||
> 请求的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"active": true,
|
||||
"content_type": "json",
|
||||
"http_method": "GET",
|
||||
"secret": "123456",
|
||||
"url": "http://localhost:10000",
|
||||
"branch_filter": "*",
|
||||
"events": ["push"]
|
||||
}
|
||||
```
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|url |string|地址|
|
||||
|content_type |string|POST Content Type|
|
||||
|is_active |bool |是否激活|
|
||||
|type |string|类型|
|
||||
|events | array|触发事件 |
|
||||
|create_time |string|创建时间|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 18,
|
||||
"type": "gitea",
|
||||
"content_type": "json",
|
||||
"url": "http://localhost:10000",
|
||||
"events": [
|
||||
"push"
|
||||
],
|
||||
"active": true,
|
||||
"create_time": "2021-07-26 18:53:43"
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 更新仓库webhook
|
||||
更新仓库webhook
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X PATCH \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`PATCH /api/:owner/:repo/webhooks/:id.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| | string |用户登录名 |
|
||||
|repo |是| | string |项目标识identifier |
|
||||
|id |是| | string |webhook id |
|
||||
|webhook.url |是| | string |目标url |
|
||||
|webhook.type |否| | string |类型|
|
||||
|webhook.http_method |是| | string | http方法, POST和GET |
|
||||
|webhook.content_type |是| | string | POST Content Type |
|
||||
|webhook.secret |否| | string |密钥文本|
|
||||
|webhook.active |是| | bool | 是否激活|
|
||||
|webhook.branch_filter|否| |string|分支过滤|
|
||||
|webhook.events |否| |array|触发事件|
|
||||
|
||||
触发事件字段说明
|
||||
|
||||
参数| 含义|
|
||||
--------- | ------- | ------- |
|
||||
|create|创建分支或标签|
|
||||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|pull_request_milestone|合并请求被记录于里程碑中|
|
||||
|pull_request_comment|合并请求被评论|
|
||||
|pull_request_review_approved|合并请求被批准|
|
||||
|pull_request_review_rejected|合并请求被拒绝|
|
||||
|pull_request_review_comment|合并请求被提出审查意见|
|
||||
|pull_request_sync|合并请求被同步|
|
||||
|repository|创建或删除仓库|
|
||||
|release|版本发布|
|
||||
|
||||
|
||||
> 请求的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"active": true,
|
||||
"content_type": "json",
|
||||
"http_method": "GET",
|
||||
"secret": "123456",
|
||||
"url": "http://localhost:10000",
|
||||
"branch_filter": "*",
|
||||
"events": ["push"]
|
||||
}
|
||||
```
|
||||
|
||||
### 返回字段说明:
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
|
||||
## 删除仓库webhook
|
||||
删除仓库webhook
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X DELETE \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`DELETE /api/:owner/:repo/webhooks/:id.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| | string |用户登录名 |
|
||||
|repo |是| | string |项目标识identifier |
|
||||
|id |是| | string |webhook id |
|
||||
|
||||
### 返回字段说明:
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 获取仓库webhook的历史推送列表
|
||||
获取仓库webhook的历史推送列表
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET /api/:owner/:repo/webhooks/:id/tasks.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|id |是| |integer |webhook ID|
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|uuid |string|推送uuid|
|
||||
|type |string|类型|
|
||||
|is_succeed |bool|是否推送成功|
|
||||
|is_delivered |bool|是否完成推送|
|
||||
|payload_content |json|请求主体内容|
|
||||
|request_content |json|请求内容,头部等等|
|
||||
|reponse_content |json|响应内容,状态,头部,主体等等|
|
||||
|delivered_time |string|推送时间|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"total_count": 6,
|
||||
"tasks": [
|
||||
{
|
||||
"id": 20,
|
||||
"type": "gitea",
|
||||
"uuid": "99aa2c23-6884-4c44-9020-5469320aa408",
|
||||
"is_succeed": true,
|
||||
"is_delivered": true,
|
||||
"payload_content": {
|
||||
"secret": "123456",
|
||||
"ref": "refs/heads/master",
|
||||
"before": "feb48e31362787a7620b53d4df3c4effddbb6f0b",
|
||||
"after": "feb48e31362787a7620b53d4df3c4effddbb6f0b",
|
||||
"compare_url": "",
|
||||
"commits": [
|
||||
{
|
||||
"id": "feb48e31362787a7620b53d4df3c4effddbb6f0b",
|
||||
"message": "fix\n",
|
||||
"url": "http://localhost:10081/yystopf/ceshi/commit/feb48e31362787a7620b53d4df3c4effddbb6f0b",
|
||||
"author": {
|
||||
"name": "viletyy",
|
||||
"email": "yystopf@163.com",
|
||||
"username": "root"
|
||||
},
|
||||
"committer": {
|
||||
"name": "viletyy",
|
||||
"email": "yystopf@163.com",
|
||||
"username": "root"
|
||||
},
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "gpg.error.not_signed_commit",
|
||||
"signature": "",
|
||||
"signer": null,
|
||||
"payload": ""
|
||||
},
|
||||
"timestamp": "2021-07-26T13:52:13+08:00",
|
||||
"added": null,
|
||||
"removed": null,
|
||||
"modified": null
|
||||
}
|
||||
],
|
||||
"head_commit": null,
|
||||
"repository": {
|
||||
"id": 2,
|
||||
"owner": {
|
||||
"id": 3,
|
||||
"login": "yystopf",
|
||||
"full_name": "",
|
||||
"email": "yystopf@forge.com",
|
||||
"avatar_url": "http://localhost:10081/user/avatar/yystopf/-1",
|
||||
"language": "zh-CN",
|
||||
"is_admin": true,
|
||||
"last_login": "2021-07-21T18:38:21+08:00",
|
||||
"created": "2021-06-03T14:50:25+08:00",
|
||||
"username": "yystopf"
|
||||
},
|
||||
"name": "ceshi",
|
||||
"full_name": "yystopf/ceshi",
|
||||
"description": "",
|
||||
"empty": false,
|
||||
"private": false,
|
||||
"fork": false,
|
||||
"template": false,
|
||||
"parent": null,
|
||||
"mirror": false,
|
||||
"size": 3846,
|
||||
"html_url": "http://localhost:10081/yystopf/ceshi",
|
||||
"ssh_url": "virus@localhost:10081:yystopf/ceshi.git",
|
||||
"clone_url": "http://localhost:10081/yystopf/ceshi.git",
|
||||
"original_url": "",
|
||||
"website": "",
|
||||
"stars_count": 0,
|
||||
"forks_count": 1,
|
||||
"watchers_count": 1,
|
||||
"open_issues_count": 0,
|
||||
"open_pr_counter": 0,
|
||||
"release_counter": 0,
|
||||
"default_branch": "master",
|
||||
"archived": false,
|
||||
"created_at": "2021-06-03T15:15:30+08:00",
|
||||
"updated_at": "2021-07-26T13:52:16+08:00",
|
||||
"permissions": {
|
||||
"admin": false,
|
||||
"push": false,
|
||||
"pull": false
|
||||
},
|
||||
"has_issues": true,
|
||||
"internal_tracker": {
|
||||
"enable_time_tracker": true,
|
||||
"allow_only_contributors_to_track_time": true,
|
||||
"enable_issue_dependencies": true
|
||||
},
|
||||
"has_wiki": true,
|
||||
"has_pull_requests": true,
|
||||
"ignore_whitespace_conflicts": false,
|
||||
"allow_merge_commits": true,
|
||||
"allow_rebase": true,
|
||||
"allow_rebase_explicit": true,
|
||||
"allow_squash_merge": true,
|
||||
"avatar_url": "",
|
||||
"internal": false
|
||||
},
|
||||
"pusher": {
|
||||
"id": 0,
|
||||
"login": "yystopf",
|
||||
"full_name": "",
|
||||
"email": "yystopf@forge.com",
|
||||
"avatar_url": "http://localhost:10081/user/avatar/yystopf/-1",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "0001-01-01T00:00:00Z",
|
||||
"created": "2021-06-03T14:50:25+08:00",
|
||||
"username": "yystopf"
|
||||
},
|
||||
"sender": {
|
||||
"id": 0,
|
||||
"login": "yystopf",
|
||||
"full_name": "",
|
||||
"email": "yystopf@forge.com",
|
||||
"avatar_url": "http://localhost:10081/user/avatar/yystopf/-1",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "0001-01-01T00:00:00Z",
|
||||
"created": "2021-06-03T14:50:25+08:00",
|
||||
"username": "yystopf"
|
||||
}
|
||||
},
|
||||
"request_content": {
|
||||
"headers": {
|
||||
"X-GitHub-Delivery": "99aa2c23-6884-4c44-9020-5469320aa408",
|
||||
"X-GitHub-Event": "push",
|
||||
"X-Gitea-Delivery": "99aa2c23-6884-4c44-9020-5469320aa408",
|
||||
"X-Gitea-Event": "push",
|
||||
"X-Gitea-Signature": "34a01edcd952ff6410ff6ebc946471161bde74aff86171f21621d2c2c4130f66",
|
||||
"X-Gogs-Delivery": "99aa2c23-6884-4c44-9020-5469320aa408",
|
||||
"X-Gogs-Event": "push",
|
||||
"X-Gogs-Signature": "34a01edcd952ff6410ff6ebc946471161bde74aff86171f21621d2c2c4130f66"
|
||||
}
|
||||
},
|
||||
"response_content": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Cache-Control": "no-store, must-revalidate, private, max-age=0",
|
||||
"Content-Length": "2556",
|
||||
"Content-Type": "text/html; charset=utf-8",
|
||||
"Referrer-Policy": "strict-origin-when-cross-origin",
|
||||
"Set-Cookie": "__profilin=p%3Dt; path=/; HttpOnly",
|
||||
"Vary": "Origin",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-Download-Options": "noopen",
|
||||
"X-Frame-Options": "SAMEORIGIN",
|
||||
"X-Miniprofiler-Ids": "9ynvpncz5xm0rpgorb5y,hgggd9mv6lr4a9drcrlr,j7zqlx2vy5aji2vtgoba,f1ktsmh3jxvq0z2hf612,mih3dvgvlqhi3zy8lf2x,5k1qbkvbnru8mye9cest,tj6ern8w6awqf2zsimbr,9isaehvubivd52wo5p9v,1rzfhtq1nhuwbgy9p76g,z0xzidzyywna0y7a69m0,hzoklky92ycjqt42gi0s,y0ai7y0t28mcn8x0py2x,322il7nadinp51mw2r5m,m6dukftfsh6tjcxzp1gq,667wlqbytfwbrirnmma1,jcehj3dl8lkw8gk510cr",
|
||||
"X-Miniprofiler-Original-Cache-Control": "max-age=0, private, must-revalidate",
|
||||
"X-Permitted-Cross-Domain-Policies": "none",
|
||||
"X-Request-Id": "08bff080-bbb5-4183-b845-81de3d47120a",
|
||||
"X-Runtime": "0.394766",
|
||||
"X-Xss-Protection": "1; mode=block"
|
||||
},
|
||||
"body": "<!doctype html><html lang=\"zh-CN\" class=\"notranslate translated-ltr\" translate=\"no\"><head><meta charset=\"utf-8\"><meta name=\"”Keywords”\" content=\"”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″\"><meta name=\"”Keywords”\" content=\"”TrustieOpenSourceProject″\"><meta name=\"”Keywords”\" content=\"”issue,bug,tracker,软件工程,课程实践″\"><meta name=\"”Description”\" content=\"”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”\"><meta name=\"theme-color\" content=\"#000000\"><link rel=\"manifest\" href=\"/react/build//manifest.json\"><link rel=\"stylesheet\" href=\"/react/build/css/iconfont.css\"><link rel=\"stylesheet\" href=\"/react/build/css/edu-purge.css\"><link rel=\"stylesheet\" href=\"/react/build/css/editormd.min.css\"><link rel=\"stylesheet\" href=\"/react/build/css/merge.css\"><link href=\"/react/build/static/css/main.07f7e90c.chunk.css\" rel=\"stylesheet\"></head><body><div id=\"md_div\" style=\"display:none\"></div><div id=\"root\" class=\"page -layout-v -fit widthunit\"></div><div id=\"picture_display\" style=\"display:none\"></div><script src=\"/react/build/js/jquery-1.8.3.min.js\"></script><script src=\"/react/build/js/js_min_all.js\"></script><script src=\"/react/build/js/codemirror/codemirror.js\"></script><script src=\"/react/build/js/editormd/editormd.min.js\"></script><script src=\"/react/build/js/codemirror/merge/merge.js\"></script><script src=\"/react/build/./static/js/runtime~main.3d644966.js\"></script><script src=\"/react/build/./static/js/main.e46872e3.chunk.js\"></script><script async type=\"text/javascript\" id=\"mini-profiler\" src=\"/mini-profiler-resources/includes.js?v=67dd1c2571ced7fc74ae7f1813e47bdf\" data-version=\"67dd1c2571ced7fc74ae7f1813e47bdf\" data-path=\"/mini-profiler-resources/\" data-current-id=\"9ynvpncz5xm0rpgorb5y\" data-ids=\"9ynvpncz5xm0rpgorb5y,hgggd9mv6lr4a9drcrlr,j7zqlx2vy5aji2vtgoba,f1ktsmh3jxvq0z2hf612,mih3dvgvlqhi3zy8lf2x,5k1qbkvbnru8mye9cest,tj6ern8w6awqf2zsimbr,9isaehvubivd52wo5p9v,1rzfhtq1nhuwbgy9p76g,z0xzidzyywna0y7a69m0,hzoklky92ycjqt42gi0s,y0ai7y0t28mcn8x0py2x,322il7nadinp51mw2r5m,m6dukftfsh6tjcxzp1gq,667wlqbytfwbrirnmma1,jcehj3dl8lkw8gk510cr\" data-horizontal-position=\"left\" data-vertical-position=\"top\" data-trivial=\"false\" data-children=\"false\" data-max-traces=\"20\" data-controls=\"false\" data-total-sql-count=\"false\" data-authorized=\"true\" data-toggle-shortcut=\"alt+p\" data-start-hidden=\"false\" data-collapse-results=\"true\" data-html-container=\"body\"></script>\n</body></html>"
|
||||
},
|
||||
"delivered_time": "2021-07-28 11:47:29"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 仓库webhook测试推送
|
||||
仓库webhook测试推送
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/yystopf/ceshi/webhooks/3/test.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/:owner/:repo/webhooks/:id/test.json`
|
||||
|
||||
### 请求参数:
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| | string |用户登录名 |
|
||||
|repo |是| | string |项目标识identifier |
|
||||
|id |是| | integer|webhook ID|
|
||||
|
||||
|
||||
|
||||
|
||||
### 返回字段说明:
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Success Data.
|
||||
</aside>
|
|
@ -0,0 +1,8 @@
|
|||
class Projects::Webhooks::CreateForm < BaseForm
|
||||
attr_accessor :type, :url, :http_method, :content_type, :secret, :events, :active, :branch_filter
|
||||
|
||||
validates :url, format: { with: URI::regexp(%w[http https]), message: "请输入正确的地址" }
|
||||
validates :active, inclusion: {in: [true, false]}
|
||||
validates :http_method, inclusion: { in: %w(POST GET), message: "请输入正确的请求方式"}
|
||||
validates :content_type, inclusion: { in: %w(json form), message: "请输入正确的Content Type"}
|
||||
end
|
|
@ -4,6 +4,6 @@ class Gitea::PublicKey < Gitea::Base
|
|||
|
||||
self.table_name = "public_key"
|
||||
|
||||
belongs_to :user, class_name: '::User', foreign_key: :gitea_uid, primary_key: :owner_id, optional: true
|
||||
belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
class Gitea::Webhook < Gitea::Base
|
||||
serialize :events, JSON
|
||||
self.inheritance_column = nil
|
||||
|
||||
self.table_name = 'webhook'
|
||||
|
||||
has_many :tasks, class_name: "Gitea::WebhookTask", foreign_key: :hook_id
|
||||
belongs_to :project, class_name: "::Project", primary_key: :gpid, foreign_key: :repo_id, optional: true
|
||||
|
||||
enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9}
|
||||
enum last_status: {waiting: 0, succeed: 1, fail: 2}
|
||||
enum content_type: {json: 1, form: 2}
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
class Gitea::WebhookTask < Gitea::Base
|
||||
serialize :payload_content, JSON
|
||||
serialize :request_content, JSON
|
||||
serialize :response_content, JSON
|
||||
|
||||
self.inheritance_column = nil
|
||||
|
||||
self.table_name = 'hook_task'
|
||||
|
||||
belongs_to :webhook, class_name: "Gitea::Webhook", foreign_key: :hook_id
|
||||
|
||||
enum type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9}
|
||||
end
|
|
@ -125,6 +125,7 @@ class Project < ApplicationRecord
|
|||
has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy
|
||||
has_many :pinned_projects, dependent: :destroy
|
||||
has_many :has_pinned_users, through: :pinned_projects, source: :user
|
||||
has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id
|
||||
|
||||
after_save :check_project_members, :reset_cache_data
|
||||
before_save :set_invite_code
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
class Gitea::Repository::Webhooks::CreateService < Gitea::ClientService
|
||||
attr_reader :token, :owner, :repo, :params
|
||||
def initialize(token, owner, repo, params)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo = repo
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
response = post(url, request_params)
|
||||
render_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
def request_params
|
||||
Hash.new.merge({token: token, data: params})
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{owner}/#{repo}/hooks".freeze
|
||||
end
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
class Gitea::Repository::Webhooks::DeleteService < Gitea::ClientService
|
||||
attr_reader :token, :owner, :repo, :id
|
||||
|
||||
def initialize(token, owner, repo, id)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo = repo
|
||||
@id = id
|
||||
end
|
||||
|
||||
def call
|
||||
response = delete(url, params)
|
||||
render_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: token)
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{owner}/#{repo}/hooks/#{id}".freeze
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
class Gitea::Repository::Webhooks::TasksService < Gitea::ClientService
|
||||
attr_reader :token, :owner, :repo, :webhook_id
|
||||
|
||||
# ref: The name of the commit/branch/tag. Default the repository’s default branch (usually master)
|
||||
# repo_name: the name of repository
|
||||
def initialize(token, owner, repo, webhook_id)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo = repo
|
||||
@webhook_id = webhook_id
|
||||
end
|
||||
|
||||
def call
|
||||
response = get(url, params)
|
||||
render_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: user.gitea_token)
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{owner}/#{repo}/hooks/#{webhook_id}/hook_tasks".freeze
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
class Gitea::Repository::Webhooks::TestService < Gitea::ClientService
|
||||
attr_reader :token, :owner, :repo, :webhook_id
|
||||
|
||||
def initialize(token, owner, repo, webhook_id)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo = repo
|
||||
@webhook_id = webhook_id
|
||||
end
|
||||
|
||||
def call
|
||||
response = post(url, request_params)
|
||||
render_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
def request_params
|
||||
Hash.new.merge({token: token})
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{owner}/#{repo}/hooks/#{webhook_id}/tests".freeze
|
||||
end
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
class Gitea::Repository::Webhooks::UpdateService < Gitea::ClientService
|
||||
attr_reader :token, :owner, :repo, :id, :params
|
||||
def initialize(token, owner, repo, id, params)
|
||||
@token = token
|
||||
@owner = owner
|
||||
@repo = repo
|
||||
@id = id
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
response = patch(url, data_params)
|
||||
render_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
def url
|
||||
"/repos/#{owner}/#{repo}/hooks/#{id}"
|
||||
end
|
||||
|
||||
def data_params
|
||||
Hash.new.merge(token: token, data: params).compact
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
json.(webhook, :id, :url, :http_method, :is_active)
|
||||
json.type webhook.hook_task_type
|
||||
json.last_status webhook.last_status
|
||||
json.create_time Time.at(webhook.created_unix).strftime("%Y-%m-%d %H:%M:%S")
|
|
@ -0,0 +1,7 @@
|
|||
json.id @webhook["id"]
|
||||
json.type @webhook["type"]
|
||||
json.content_type @webhook["config"]["content_type"]
|
||||
json.url @webhook["config"]["url"]
|
||||
json.events @webhook["events"]
|
||||
json.active @webhook["active"]
|
||||
json.create_time @webhook["created_at"].to_time.strftime("%Y-%m-%d %H:%M:%S")
|
|
@ -0,0 +1,11 @@
|
|||
json.id @webhook.id
|
||||
json.(@webhook, :id, :http_method, :content_type, :url, :secret, :last_status, :is_active)
|
||||
json.type @webhook.hook_task_type
|
||||
json.create_time Time.at(@webhook.created_unix).strftime("%Y-%m-%d %H:%M:%S")
|
||||
event = @webhook.events
|
||||
json.branch_filter event["branch_filter"]
|
||||
if event["send_everything"]
|
||||
json.events event["events"].keys.collect{|i| i == "pull_request" ? i + "_only" : i}
|
||||
else
|
||||
json.events event["events"].select{|k, v| v}.keys.collect{|i| i == "pull_request" ? i + "_only" : i}
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
json.total_count @webhooks.total_count
|
||||
json.webhooks @webhooks.each do |webhook|
|
||||
json.partial! 'detail', webhook: webhook
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
json.total_count @tasks.total_count
|
||||
json.tasks @tasks.each do |task|
|
||||
json.(task, :id, :type, :uuid, :is_succeed, :is_delivered, :payload_content, :request_content, :response_content)
|
||||
json.delivered_time Time.at(task.delivered*10**-9).strftime("%Y-%m-%d %H:%M:%S")
|
||||
end
|
|
@ -348,6 +348,7 @@ Rails.application.routes.draw do
|
|||
|
||||
get '/auth/qq/callback', to: 'oauth/qq#create'
|
||||
get '/auth/wechat/callback', to: 'oauth/wechat#create'
|
||||
get '/auth/educoder/callback', to: 'oauth/educoder#create'
|
||||
resource :bind_user, only: [:create]
|
||||
|
||||
resources :hot_keywords, only: [:index]
|
||||
|
@ -571,6 +572,12 @@ Rails.application.routes.draw do
|
|||
post :cancel
|
||||
end
|
||||
end
|
||||
resources :webhooks, except: [:show, :new] do
|
||||
member do
|
||||
get :tasks
|
||||
post :test
|
||||
end
|
||||
end
|
||||
scope do
|
||||
get(
|
||||
'/blob/*id/diff',
|
||||
|
|
1238
public/docs/api.html
1238
public/docs/api.html
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue