diff --git a/app/controllers/projects/base_controller.rb b/app/controllers/projects/base_controller.rb index 9811a2136..240bc91f1 100644 --- a/app/controllers/projects/base_controller.rb +++ b/app/controllers/projects/base_controller.rb @@ -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 diff --git a/app/controllers/projects/webhooks_controller.rb b/app/controllers/projects/webhooks_controller.rb index b450e4a20..144082f56 100644 --- a/app/controllers/projects/webhooks_controller.rb +++ b/app/controllers/projects/webhooks_controller.rb @@ -1,4 +1,5 @@ class Projects::WebhooksController < Projects::BaseController + before_action :require_manager! def index @webhooks = @project.webhooks @@ -6,6 +7,21 @@ class Projects::WebhooksController < Projects::BaseController end def create + ActiveRecord::Base.transaction do + 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(current_user.gitea_token, @project&.owner&.login, @project&.identifier, gitea_webhooks_params).call + if response[0] == 201 + @webhook = response[2] + puts @webhook + else + render_error("创建失败.") + end + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) end def edit @@ -21,4 +37,30 @@ class Projects::WebhooksController < Projects::BaseController def find_webhook @webhook = Gitea::Webhook.find_by_id(params[:id]) 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], + }, + events: webhook_params[:events], + type: webhook_type, + } + end end \ No newline at end of file diff --git a/app/docs/slate/source/includes/_repositories.md b/app/docs/slate/source/includes/_repositories.md index 350eb64fc..04b232522 100644 --- a/app/docs/slate/source/includes/_repositories.md +++ b/app/docs/slate/source/includes/_repositories.md @@ -952,3 +952,102 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks.json') + +## 添加仓库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_assign|易修被指派| +|issue_label|易修标签被更新或删除| +|issue_milestone|易修被收入里程碑| +|issue_comment|易修评论| +|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|合并请求被同步| + + + +> 请求的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" +} +``` + diff --git a/app/forms/projects/webhooks/create_form.rb b/app/forms/projects/webhooks/create_form.rb new file mode 100644 index 000000000..75b07b1bd --- /dev/null +++ b/app/forms/projects/webhooks/create_form.rb @@ -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 \ No newline at end of file diff --git a/app/services/gitea/repository/webhooks/create_service.rb b/app/services/gitea/repository/webhooks/create_service.rb new file mode 100644 index 000000000..33c9a9b0c --- /dev/null +++ b/app/services/gitea/repository/webhooks/create_service.rb @@ -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 \ No newline at end of file diff --git a/app/views/projects/webhooks/create.json.jbuilder b/app/views/projects/webhooks/create.json.jbuilder new file mode 100644 index 000000000..6d6dde31f --- /dev/null +++ b/app/views/projects/webhooks/create.json.jbuilder @@ -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") \ No newline at end of file diff --git a/public/docs/api.html b/public/docs/api.html index b4fe40935..59d7574c3 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -490,6 +490,9 @@
添加仓库webhook
+ +++示例:
+
curl -X POST \
+http://localhost:3000/api/yystopf/ceshi/webhooks.json
+
await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
+
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_assign | +易修被指派 | +
issue_label | +易修标签被更新或删除 | +
issue_milestone | +易修被收入里程碑 | +
issue_comment | +易修评论 | +
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 | +合并请求被同步 | +
++请求的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示例:
+
{
+ "id": 18,
+ "type": "gitea",
+ "content_type": "json",
+ "url": "http://localhost:10000",
+ "events": [
+ "push"
+ ],
+ "active": true,
+ "create_time": "2021-07-26 18:53:43"
+}
+