From ebc4305ca88c543f15ccb8d0124ec11a31960b8c Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 26 Jul 2021 17:25:06 +0800 Subject: [PATCH 1/8] add: repository webhooks --- .../projects/webhooks_controller.rb | 24 ++++ .../slate/source/includes/_repositories.md | 85 +++++++++++ app/models/gitea/public_key.rb | 2 +- app/models/gitea/webhook.rb | 10 ++ app/models/project.rb | 1 + .../projects/webhooks/_detail.json.jbuilder | 4 + .../projects/webhooks/index.json.jbuilder | 4 + config/routes.rb | 2 + public/docs/api.html | 132 ++++++++++++++++++ 9 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 app/controllers/projects/webhooks_controller.rb create mode 100644 app/models/gitea/webhook.rb create mode 100644 app/views/projects/webhooks/_detail.json.jbuilder create mode 100644 app/views/projects/webhooks/index.json.jbuilder diff --git a/app/controllers/projects/webhooks_controller.rb b/app/controllers/projects/webhooks_controller.rb new file mode 100644 index 000000000..b450e4a20 --- /dev/null +++ b/app/controllers/projects/webhooks_controller.rb @@ -0,0 +1,24 @@ +class Projects::WebhooksController < Projects::BaseController + + def index + @webhooks = @project.webhooks + @webhooks = kaminari_paginate(@webhooks) + end + + def create + end + + def edit + end + + def update + end + + def destroy + end + + private + def find_webhook + @webhook = Gitea::Webhook.find_by_id(params[:id]) + 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 40d3ba2ff..350eb64fc 100644 --- a/app/docs/slate/source/includes/_repositories.md +++ b/app/docs/slate/source/includes/_repositories.md @@ -867,3 +867,88 @@ await octokit.request('GET /api/jasder/jasder_test/sub_entries.json') + +## 获取仓库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" + } + ] +} +``` + diff --git a/app/models/gitea/public_key.rb b/app/models/gitea/public_key.rb index bc37c3bc7..bb2192358 100644 --- a/app/models/gitea/public_key.rb +++ b/app/models/gitea/public_key.rb @@ -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 diff --git a/app/models/gitea/webhook.rb b/app/models/gitea/webhook.rb new file mode 100644 index 000000000..77b6f2e0f --- /dev/null +++ b/app/models/gitea/webhook.rb @@ -0,0 +1,10 @@ +class Gitea::Webhook < Gitea::Base + self.inheritance_column = nil + + self.table_name = 'webhook' + + 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} +end \ No newline at end of file diff --git a/app/models/project.rb b/app/models/project.rb index 6d4922a73..ff285f179 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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 diff --git a/app/views/projects/webhooks/_detail.json.jbuilder b/app/views/projects/webhooks/_detail.json.jbuilder new file mode 100644 index 000000000..2497e5c64 --- /dev/null +++ b/app/views/projects/webhooks/_detail.json.jbuilder @@ -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") \ No newline at end of file diff --git a/app/views/projects/webhooks/index.json.jbuilder b/app/views/projects/webhooks/index.json.jbuilder new file mode 100644 index 000000000..62722acbe --- /dev/null +++ b/app/views/projects/webhooks/index.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @webhooks.total_count +json.webhooks @webhooks.each do |webhook| + json.partial! 'detail', webhook: webhook +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 0cc16406c..88f9aceb5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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,7 @@ Rails.application.routes.draw do post :cancel end end + resources :webhooks, except: [:show, :new] scope do get( '/blob/*id/diff', diff --git a/public/docs/api.html b/public/docs/api.html index 47e51427b..b4fe40935 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -487,6 +487,9 @@
  • 获取仓库代码子目录或者文件
  • +
  • + 获取仓库webhooks列表 +
  • @@ -6752,6 +6755,135 @@ http://localhost:3000//api/jasder/jasder_test/sub_entries.json +

    获取仓库webhooks列表

    +

    获取仓库webhooks列表

    + +
    +

    示例:

    +
    +
    curl -X GET \
    +http://localhost:3000/api/yystopf/ceshi/webhooks.json
    +
    await octokit.request('GET /api/yystopf/ceshi/webhooks.json')
    +

    HTTP 请求

    +

    GET /api/:owner/:repo/webhooks.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    +

    返回字段说明:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    idintid
    urlstring地址
    http_methodstring请求方式
    is_activebool是否激活
    typestring类型
    last_statusstring最后一次推送的状态
    create_timestring创建时间
    + +
    +

    返回的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"
    +        }
    +    ]
    +}
    +
    +

    Pulls

    Issues

    Organizations

    Teams

    Errors

  • @@ -6884,6 +6887,248 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json +

    添加仓库webhook

    +

    添加仓库webhook

    + +
    +

    示例:

    +
    +
    curl -X POST \
    +http://localhost:3000/api/yystopf/ceshi/webhooks.json
    +
    await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
    +

    HTTP 请求

    +

    POST /api/:owner/:repo/webhooks.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    webhook.urlstring目标url
    webhook.typestring类型
    webhook.http_methodstringhttp方法, POST和GET
    webhook.content_typestringPOST Content Type
    webhook.secretstring密钥文本
    webhook.activebool是否激活
    webhook.branch_filterstring分支过滤
    webhook.eventsarray触发事件
    + +

    触发事件字段说明

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数含义
    create仓库创建
    delete分支或标签删除
    fork仓库被fork
    pushgit仓库推送
    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"]
    +}
    +

    返回字段说明:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    idintid
    urlstring地址
    content_typestringPOST Content Type
    is_activebool是否激活
    typestring类型
    eventsarray触发事件
    create_timestring创建时间
    + +
    +

    返回的JSON示例:

    +
    +
    {
    +    "id": 18,
    +    "type": "gitea",
    +    "content_type": "json",
    +    "url": "http://localhost:10000",
    +    "events": [
    +        "push"
    +    ],
    +    "active": true,
    +    "create_time": "2021-07-26 18:53:43"
    +}
    +
    +

    Pulls

    Issues

    Organizations

    Teams

    Errors

  • @@ -6990,7 +6996,7 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json create -仓库创建 +创建分支或标签 delete @@ -7005,6 +7011,10 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json git仓库推送 +issue +易修已打开、已关闭、已重新打开或编辑 + + issue_assign 易修被指派 @@ -7021,6 +7031,10 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json 易修评论 +pull_request +合并请求 + + pull_request_assign 合并请求被指派 @@ -7052,6 +7066,14 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json pull_request_sync 合并请求被同步 + +repository +创建或删除仓库 + + +release +版本发布 +
    @@ -7129,6 +7151,275 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json +

    更新仓库webhook

    +

    更新仓库webhook

    + +
    +

    示例:

    +
    +
    curl -X PATCH \
    +http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
    +
    await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
    +

    HTTP 请求

    +

    PATCH /api/:owner/:repo/webhooks/:id.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    idstringwebhook id
    webhook.urlstring目标url
    webhook.typestring类型
    webhook.http_methodstringhttp方法, POST和GET
    webhook.content_typestringPOST Content Type
    webhook.secretstring密钥文本
    webhook.activebool是否激活
    webhook.branch_filterstring分支过滤
    webhook.eventsarray触发事件
    + +

    触发事件字段说明

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数含义
    create创建分支或标签
    delete分支或标签删除
    fork仓库被fork
    pushgit仓库推送
    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示例:

    +
    +
    {
    +    "active": true, 
    +    "content_type": "json",
    +    "http_method": "GET",
    +    "secret": "123456",
    +    "url": "http://localhost:10000",
    +    "branch_filter": "*",
    +    "events": ["push"]
    +}
    +

    返回字段说明:

    +
    +

    返回的JSON示例:

    +
    +
    {
    +    "status": 0,
    +    "message": "success"
    +}
    +
    + +

    删除仓库webhook

    +

    删除仓库webhook

    + +
    +

    示例:

    +
    +
    curl -X DELETE \
    +http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
    +
    await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json')
    +

    HTTP 请求

    +

    DELETE /api/:owner/:repo/webhooks/:id.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    idstringwebhook id
    +

    返回字段说明:

    +
    +

    返回的JSON示例:

    +
    +
    {
    +    "status": 0,
    +    "message": "success"
    +}
    +
    +

    Pulls

    Issues

    Organizations

    Teams

    Errors

    +## 获取仓库单个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" + ] +} +``` + + ## 添加仓库webhook 添加仓库webhook @@ -1179,3 +1284,257 @@ await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json') + +## 获取仓库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": "
    \n" + }, + "delivered_time": "2021-07-28 11:47:29" + } + ] +} +``` + + +## 仓库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" +} +``` + \ No newline at end of file diff --git a/app/models/gitea/webhook.rb b/app/models/gitea/webhook.rb index 597272cd2..f60f56788 100644 --- a/app/models/gitea/webhook.rb +++ b/app/models/gitea/webhook.rb @@ -1,8 +1,10 @@ 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} diff --git a/app/models/gitea/webhook_task.rb b/app/models/gitea/webhook_task.rb new file mode 100644 index 000000000..d19a163aa --- /dev/null +++ b/app/models/gitea/webhook_task.rb @@ -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 \ No newline at end of file diff --git a/app/services/gitea/repository/webhooks/tasks_service.rb b/app/services/gitea/repository/webhooks/tasks_service.rb new file mode 100644 index 000000000..e4c62edb4 --- /dev/null +++ b/app/services/gitea/repository/webhooks/tasks_service.rb @@ -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 diff --git a/app/services/gitea/repository/webhooks/test_service.rb b/app/services/gitea/repository/webhooks/test_service.rb new file mode 100644 index 000000000..7f1837611 --- /dev/null +++ b/app/services/gitea/repository/webhooks/test_service.rb @@ -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 \ No newline at end of file diff --git a/app/views/projects/webhooks/edit.json.jbuilder b/app/views/projects/webhooks/edit.json.jbuilder index 97686b55f..8d5922ded 100644 --- a/app/views/projects/webhooks/edit.json.jbuilder +++ b/app/views/projects/webhooks/edit.json.jbuilder @@ -2,7 +2,7 @@ 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 = JSON.parse(@webhook.events) +event = @webhook.events json.branch_filter event["branch_filter"] if event["send_everything"] json.events event["events"].keys diff --git a/app/views/projects/webhooks/tasks.json.jbuilder b/app/views/projects/webhooks/tasks.json.jbuilder new file mode 100644 index 000000000..b8aef99f5 --- /dev/null +++ b/app/views/projects/webhooks/tasks.json.jbuilder @@ -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 \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 88f9aceb5..a3cc196ec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -572,7 +572,12 @@ Rails.application.routes.draw do post :cancel end end - resources :webhooks, except: [:show, :new] + resources :webhooks, except: [:show, :new] do + member do + get :tasks + post :test + end + end scope do get( '/blob/*id/diff', diff --git a/public/docs/api.html b/public/docs/api.html index 8033891a4..35099a4e8 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -491,13 +491,22 @@ 获取仓库webhooks列表
  • - 添加仓库webhook + 获取仓库单个webhook
  • - 更新仓库webhook + 添加仓库webhook
  • - 删除仓库webhook + 更新仓库webhook +
  • +
  • + 删除仓库webhook +
  • +
  • + 获取仓库webhook的历史推送列表 +
  • +
  • + 仓库webhook测试推送
  • @@ -6893,17 +6902,17 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json -

    添加仓库webhook

    -

    添加仓库webhook

    +

    获取仓库单个webhook

    +

    获取仓库单个webhook

    示例:

    -
    curl -X POST \
    -http://localhost:3000/api/yystopf/ceshi/webhooks.json
    -
    await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
    +
    curl -X GET \
    +http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json
    +
    await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json')
     

    HTTP 请求

    -

    POST /api/:owner/:repo/webhooks.json

    +

    GET /api/:owner/:repo/webhooks/:id/edit.json

    请求参数:

    @@ -6929,65 +6938,78 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json - + - - + + + +
    项目标识identifier
    webhook.urlid string目标urlintegerwebhook ID
    +

    返回字段说明:

    + + + + + + + + + + + - - - + - + - - - - - - - - - - + - - - + - + - - + + + + + - - - + + + + + + + + + + + - - - - - + + + + + + + +
    参数类型字段说明
    idintid
    webhook.typeurl string类型地址
    webhook.http_methodstringhttp方法, POST和GET
    webhook.content_typecontent_type string POST Content Type
    webhook.secrethttp_method string密钥文本请求方式
    webhook.activesecret string
    is_active bool 是否激活
    webhook.branch_filtertypestring类型
    last_statusstring最后一次推送的状态, waiting 等待,fail 失败,succeed 成功
    branch_filter string 分支过滤
    webhook.eventsarray触发事件eventsstring触发条件
    create_timestring创建时间
    -

    触发事件字段说明

    - @@ -7076,92 +7098,56 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json
    参数
    -
    -

    请求的JSON示例:

    -
    -
    {
    -    "active": true, 
    -    "content_type": "json",
    -    "http_method": "GET",
    -    "secret": "123456",
    -    "url": "http://localhost:10000",
    -    "branch_filter": "*",
    -    "events": ["push"]
    -}
    -

    返回字段说明:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    参数类型字段说明
    idintid
    urlstring地址
    content_typestringPOST Content Type
    is_activebool是否激活
    typestring类型
    eventsarray触发事件
    create_timestring创建时间
    -

    返回的JSON示例:

    {
    -    "id": 18,
    +    "id": 3,
    +    "http_method": "GET",
    +    "content_type": "form",
    +    "url": "http://localhost:3000",
    +    "secret": "123456",
    +    "last_status": "succeed",
    +    "is_active": true,
         "type": "gitea",
    -    "content_type": "json",
    -    "url": "http://localhost:10000",
    +    "create_time": "2021-07-26 10:03:45",
    +    "branch_filter": "*",
         "events": [
    -        "push"
    -    ],
    -    "active": true,
    -    "create_time": "2021-07-26 18:53:43"
    +        "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"
    +    ]
     }
     
    -

    更新仓库webhook

    -

    更新仓库webhook

    +

    添加仓库webhook

    +

    添加仓库webhook

    示例:

    -
    curl -X PATCH \
    -http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
    -
    await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
    +
    curl -X POST \
    +http://localhost:3000/api/yystopf/ceshi/webhooks.json
    +
    await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
     

    HTTP 请求

    -

    PATCH /api/:owner/:repo/webhooks/:id.json

    +

    POST /api/:owner/:repo/webhooks.json

    请求参数:

    @@ -7187,13 +7173,6 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json - - - - - - - @@ -7354,28 +7333,79 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json "events": ["push"] }

    返回字段说明:

    +
    项目标识identifier
    idstringwebhook id
    webhook.url
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    idintid
    urlstring地址
    content_typestringPOST Content Type
    is_activebool是否激活
    typestring类型
    eventsarray触发事件
    create_timestring创建时间
    +

    返回的JSON示例:

    {
    -    "status": 0,
    -    "message": "success"
    +    "id": 18,
    +    "type": "gitea",
    +    "content_type": "json",
    +    "url": "http://localhost:10000",
    +    "events": [
    +        "push"
    +    ],
    +    "active": true,
    +    "create_time": "2021-07-26 18:53:43"
     }
     
    -

    删除仓库webhook

    -

    删除仓库webhook

    +

    更新仓库webhook

    +

    更新仓库webhook

    示例:

    -
    curl -X DELETE \
    +
    curl -X PATCH \
     http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
    -
    await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json')
    +
    await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
     

    HTTP 请求

    -

    DELETE /api/:owner/:repo/webhooks/:id.json

    +

    PATCH /api/:owner/:repo/webhooks/:id.json

    请求参数:

    @@ -7407,8 +7437,548 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    string webhook id
    webhook.urlstring目标url
    webhook.typestring类型
    webhook.http_methodstringhttp方法, POST和GET
    webhook.content_typestringPOST Content Type
    webhook.secretstring密钥文本
    webhook.activebool是否激活
    webhook.branch_filterstring分支过滤
    webhook.eventsarray触发事件
    -

    返回字段说明:

    + +

    触发事件字段说明

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数含义
    create创建分支或标签
    delete分支或标签删除
    fork仓库被fork
    pushgit仓库推送
    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示例:

    +
    +
    {
    +    "active": true, 
    +    "content_type": "json",
    +    "http_method": "GET",
    +    "secret": "123456",
    +    "url": "http://localhost:10000",
    +    "branch_filter": "*",
    +    "events": ["push"]
    +}
    +

    返回字段说明:

    +
    +

    返回的JSON示例:

    +
    +
    {
    +    "status": 0,
    +    "message": "success"
    +}
    +
    + +

    删除仓库webhook

    +

    删除仓库webhook

    + +
    +

    示例:

    +
    +
    curl -X DELETE \
    +http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
    +
    await octokit.request('DELETE /api/yystopf/ceshi/webhooks/7.json')
    +

    HTTP 请求

    +

    DELETE /api/:owner/:repo/webhooks/:id.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    idstringwebhook id
    +

    返回字段说明:

    +
    +

    返回的JSON示例:

    +
    +
    {
    +    "status": 0,
    +    "message": "success"
    +}
    +
    + +

    获取仓库webhook的历史推送列表

    +

    获取仓库webhook的历史推送列表

    + +
    +

    示例:

    +
    +
    curl -X GET \
    +http://localhost:3000/api/yystopf/ceshi/webhooks/3/tasks.json
    +
    await octokit.request('GET /api/yystopf/ceshi/webhooks/3/tasks.json')
    +

    HTTP 请求

    +

    GET /api/:owner/:repo/webhooks/:id/tasks.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    idintegerwebhook ID
    +

    返回字段说明:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数类型字段说明
    idintid
    uuidstring推送uuid
    typestring类型
    is_succeedbool是否推送成功
    is_deliveredbool是否完成推送
    payload_contentjson请求主体内容
    request_contentjson请求内容,头部等等
    reponse_contentjson响应内容,状态,头部,主体等等
    delivered_timestring推送时间
    + +
    +

    返回的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"
    +    }
    +  ]
    +}
    +
    + +

    仓库webhook测试推送

    +

    仓库webhook测试推送

    + +
    +

    示例:

    +
    +
    curl -X POST \
    +http://localhost:3000/api/yystopf/ceshi/webhooks/3/test.json
    +
    await octokit.request('POST /api/yystopf/ceshi/webhooks/3/test.json')
    +

    HTTP 请求

    +

    POST /api/:owner/:repo/webhooks/:id/test.json

    +

    请求参数:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数必选默认类型字段说明
    ownerstring用户登录名
    repostring项目标识identifier
    idintegerwebhook ID
    +

    返回字段说明:

    返回的JSON示例:

    From 4d6ec8088a23856252aa19d3b0b25daf560166a5 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jul 2021 17:30:32 +0800 Subject: [PATCH 5/8] fix: webhookparams include secret --- app/controllers/projects/webhooks_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/projects/webhooks_controller.rb b/app/controllers/projects/webhooks_controller.rb index c9ebb19c7..2152e96d7 100644 --- a/app/controllers/projects/webhooks_controller.rb +++ b/app/controllers/projects/webhooks_controller.rb @@ -102,6 +102,7 @@ class Projects::WebhooksController < Projects::BaseController 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, From 4b8bb8a65f3dcb84d793e274e4dffa92904fc21e Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 29 Jul 2021 16:17:30 +0800 Subject: [PATCH 6/8] fix: pullrequest name --- app/controllers/projects/webhooks_controller.rb | 1 + app/views/projects/webhooks/edit.json.jbuilder | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/webhooks_controller.rb b/app/controllers/projects/webhooks_controller.rb index 2152e96d7..c73f43c89 100644 --- a/app/controllers/projects/webhooks_controller.rb +++ b/app/controllers/projects/webhooks_controller.rb @@ -80,6 +80,7 @@ class Projects::WebhooksController < Projects::BaseController private def find_webhook @webhook = Gitea::Webhook.find_by_id(params[:id]) + return render_not_found if @webhook.nil? end def webhook_params diff --git a/app/views/projects/webhooks/edit.json.jbuilder b/app/views/projects/webhooks/edit.json.jbuilder index 8d5922ded..2ee6d24e8 100644 --- a/app/views/projects/webhooks/edit.json.jbuilder +++ b/app/views/projects/webhooks/edit.json.jbuilder @@ -5,7 +5,7 @@ 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 + json.events event["events"].keys.collect{|i| i == "pull_request" ? i + "_only" : i} else - json.events event["events"].select{|k, v| v}.keys + json.events event["events"].select{|k, v| v}.keys.collect{|i| i == "pull_request" ? i + "_only" : i} end From eeb69daff1b2d1bc0845ca5fb0236200f20730e3 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 30 Jul 2021 09:39:54 +0800 Subject: [PATCH 7/8] fix: some user admin but not have gitea authorize --- app/controllers/projects/webhooks_controller.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/controllers/projects/webhooks_controller.rb b/app/controllers/projects/webhooks_controller.rb index c73f43c89..2ef5ba5fc 100644 --- a/app/controllers/projects/webhooks_controller.rb +++ b/app/controllers/projects/webhooks_controller.rb @@ -13,7 +13,7 @@ class Projects::WebhooksController < Projects::BaseController 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 + 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 @@ -33,7 +33,7 @@ class Projects::WebhooksController < Projects::BaseController 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(current_user.gitea_token, @project&.owner&.login, @project&.identifier, @webhook.id, gitea_webhooks_params) + 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 @@ -46,7 +46,7 @@ class Projects::WebhooksController < Projects::BaseController end def destroy - response = Gitea::Repository::Webhooks::DeleteService.call(current_user.gitea_token, @project&.owner&.login, @project&.identifier, @webhook.id) + response = Gitea::Repository::Webhooks::DeleteService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id) if response[0] == 204 @webhook = response[2] render_ok @@ -65,7 +65,7 @@ class Projects::WebhooksController < Projects::BaseController def test ActiveRecord::Base.transaction do - response = Gitea::Repository::Webhooks::TestService.call(current_user.gitea_token, @project&.owner&.login, @project&.identifier, @webhook.id) + response = Gitea::Repository::Webhooks::TestService.call(operating_token, @project&.owner&.login, @project&.identifier, @webhook.id) if response[0] == 204 render_ok else @@ -79,7 +79,7 @@ class Projects::WebhooksController < Projects::BaseController private def find_webhook - @webhook = Gitea::Webhook.find_by_id(params[:id]) + @webhook = @project.webhooks.find_by_id(params[:id]) return render_not_found if @webhook.nil? end @@ -109,4 +109,8 @@ class Projects::WebhooksController < Projects::BaseController type: webhook_type, } end + + def operating_token + @project.member?(current_user) ? current_user.gitea_token : @project&.owner&.gitea_token + end end \ No newline at end of file From bfef459b7557419f262881bba6749e3a80087d89 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 30 Jul 2021 16:24:34 +0800 Subject: [PATCH 8/8] fix: hook tasks use is delivered data --- app/controllers/projects/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects/webhooks_controller.rb b/app/controllers/projects/webhooks_controller.rb index 2ef5ba5fc..9f36da206 100644 --- a/app/controllers/projects/webhooks_controller.rb +++ b/app/controllers/projects/webhooks_controller.rb @@ -59,7 +59,7 @@ class Projects::WebhooksController < Projects::BaseController end def tasks - @tasks = @webhook.tasks.order("delivered desc") + @tasks = @webhook.tasks.where(is_delivered: true).order("delivered desc") @tasks = kaminari_paginate(@tasks) end