Webhook究竟是個啥?

服務器:Jenkins Server Git Server App Server
關鍵詞:nodejs ngrok github webhook前端

在配置Jenkins實現前端自動化構建的過程當中,對於自動化的過程理解很模糊,只是知道Jenkins服務器,Git倉庫和後端應用服務器這三個概念。vue

  • git push以後,Git如何通知Jenkins對應Job的工做區實時構建

答案就是:Git webhook機制發出請求,告知Jenkins服務器你要自動構建了。node

webhook與異步編程中"訂閱-發佈模型"很是相似,一端觸發事件,一端監聽執行。git

若是僅僅想學習webhook,能夠直接閱讀。可是必定要注意,知識點是"異步編程模型",webhook僅僅是它的一個實現。github

開啓正文!web

以github webhook,koa,ngrok學習Webhook。

維基百科:算法

在web開發過程當中的webhook,是一種經過一般的callback,去增長或者改變web page或者web app行爲的方法。這些callback能夠由第三方用戶和開發者維持當前,修改,管理,而這些使用者與網站或者應用的原始開發沒有關聯。 webhook這個詞是由Jeff Lindsay在2007年在計算機科學hook項目第一次提出的。
  • Webhooks是"user-defined HTTP回調"。它們一般由一些事件觸發,例如"push 代碼到repo",或者"post 一個評論到博客"。
  • 當事件發生時,源網站能夠發起一個HTTP請求到webhook配置的URL。配置以後,用戶能夠經過在一個站點觸發事件,以後再調用另外一個站點的行爲。能夠是任何操做。
  • 普通用戶可使用CI系統或者通知bug追蹤系統觸發build。
  • 因爲webhook使用HTTP協議,所以能夠直接被集成到web service。因此他們有時會被用來構建消息隊列服務,例如一些RESTful的例子:IronMQ和RestMS。
以Github Webhook爲例,學習webhook。

1、基礎部分

Webhook 容許咱們經過在Github.com訂閱事件後構建後或者安裝Github應用。當其中之一的事件被觸發時,咱們能夠發送HTTP POST請求到webhook的配置URL。Webhook能夠用做升級一個issue追蹤,觸發CI構建,升級一個後端鏡像,或者甚至是部署你的生產服務器。只有想不到,沒有作不到。vuex

事件

在配置webhook的時候,你能夠選擇本身想要接收的事件。你甚至能夠選擇參加觸發全部事件。只有訂閱特殊的須要的事件,能夠有效限制服務器HTTP請求數。能夠經過API或者UR隨時訂閱事件。默認狀況下,webhook只訂閱push事件。編程

每一個事件與一個動做集合聯繫,這些動做能夠在你的組織或者repo中發生。例如,若是你訂閱了issues事件,你將在issue open,close以及labeled時接收到detailed payload。json

下面是一些可用的事件:

Name Description
* Any time any event is triggered (Wildcard Event).
check_run Any time a check run is created, requested, or rerequested.
check_suite Any time a check suite is completed, requested, or rerequested.
commit_comment Any time a Commit is commented on.
push Any Git push to a Repository, including editing tags or branches. Commits via API actions that update references are also counted. This is the default event.

......

載荷

每個事件類型都有一個指定的與相關事件信息有關的payload格式。全部的事件載荷都是事件類型的載荷鏡像,push除外,由於他有更加詳細的webhook負載。

除了每一個事件的documented字段,webhook負載包含了執行事件的用戶以及組織和或repo,對於一個Github App的webhook來講,它包含installation。在PullRequestEvent payload中有示例。

發送報文頭

發送到webhook配置URL的HTTP POST負載會包含幾個指定的報文頭。

Header Description
X-GitHub-Event 觸發分發的事件類型。
X-GitHub-Delivery 惟一識別分發的GUID。
X-Hub-Signature HMAC十六進制的響應體。若是secret配置了,這個頭信息將被髮送。HMAC十六進制由sha1哈希算法生成,secret做爲HMAC的key。

User-Agent也將會加上前綴GitHub-Hookshot/.
示例:

POST /payload HTTP/1.1
Host: localhost:4567
X-Github-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature: sha1=7d38cdd689735b008b3c702edd92eea23791c5f6
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
Content-Length: 6615
X-GitHub-Event: issues
{
  "action": "opened",
  "issue": {
    "url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
    "number": 1347,
    ...
  },
  "repository" : {
    "id": 1296269,
    "full_name": "octocat/Hello-World",
    "owner": {
      "login": "octocat",
      "id": 1,
      ...
    },
    ...
  },
  "sender": {
    "login": "octocat",
    "id": 1,
    ...
  }
}

Ping 事件
ping事件負載

| Key | Value |
| --- | --- |
| zen | Random string of GitHub zen |
| hook_id | The ID of the webhook that triggered the ping |
| hook | The [webhook configuration](https://developer.github.com/v3/repos/hooks/#get-single-hook) |

GitHub App
當你註冊一個新的GitHub App時,GitHub發送一個ping事件到webhook URL。事件的包含app_id。

{
  "hook":{
    "type":"App",
    "id":11,
    "active":true,
    "events":["pull_request"],
    "app_id":37,
    ...
  }
}

2、實驗開始

1. 配置並建立Webhook

  • 配置Github監聽事件類型

    • Payload URL接收webhook POST請求的服務器端口。
    • Content類型

      • application/json會將JSON payload直接放置POST的body中。
      • application/x-www-form-urlencoded類型將JSON payload做爲payload參數發送。
      • Secret

        • 使得webhooks更加安全的一個配置。
      • Events

        • Events是webhook的核心。只要對存儲庫執行某項操做,就會觸發這些webhook,服務器的有效負載URL會攔截並執行操做。

2. 配置接收和管理負載的服務器

  • 安裝ngrok而且作公網映射
./ngrok http 4567

將生成的只有8小時有效時間的url複製到Payload URL。

http://785902b9.ngrok.io/payload
  • 寫接收/payload路徑的nodejs服務
var Koa = require('koa');
var Router = require('koa-router');

var app = new Koa();
var router = new Router();

router
    .post('/payload', (ctx, next) => {
        console.log(ctx);
    })

app
    .use(router.routes())
    .use(router.allowedMethods());

app.listen(4567);

運行如下命令啓動服務:

node server.js
  • 在Issues new 一個Issue。

  • 本地的服務監聽到issue事件以後,會打印出webhook的信息
{ request: 
   { method: 'POST',
     url: '/payload',
     header: 
      { host: '785902b9.ngrok.io',
        accept: '*/*',
        'user-agent': 'GitHub-Hookshot/22e0d92',
        'x-github-event': 'issues',
        'x-github-delivery': 'cde0a020-7c48-11e8-9c35-c1d90e4891c8',
        'content-type': 'application/x-www-form-urlencoded',
        'x-hub-signature': 'sha1=9f4873803f9615615e02f7dec856778ebfc201be',
        'content-length': '10929',
        'x-forwarded-for': '192.30.252.44' } },
  response: { status: 404, message: 'Not Found', header: {} },
  app: { subdomainOffset: 2, proxy: false, env: 'development' },
  originalUrl: '/payload',
  req: '<original node req>',
  res: '<original node res>',
  socket: '<original node socket>' }

3.測試Webhooks

在每個Webhook下都有一個觸發事件記錄列表。

單擊後會展開webhook的請求和響應。

4.在Github和server設置token

  • 不要硬編碼,使用安全隨機的方式生成十六進制hash token
  • 將生成的token複製到webhook的secret配置處,再將其保存到服務器專門的本地變量中
  • token hash在請求報文頭的X-Hub-Signature
  • 能夠設置服務端token校驗,若本地保存的token與Github傳來的token不一致,報500

3、實驗分析

  • 訂閱: github repo訂閱issue webhook event
  • 發佈: 由來自世界各地的開發者創建issue後,觸發trigger,發請求到Payload URL,發請求到服務器
  • 處理: URL對應的服務器,解析請求,作出響應

4、引伸分析Jenkins CI

  • git push以後,Git如何通知Jenkins對應Job的工做區實時自動構建?

    • 訂閱: Git倉庫訂閱push webhook event
    • 發佈: 某個開發人員本地git push後,觸發Git repo的trigger,發請求Jenkins服務器
    • 處理: Jenkins服務器解析請求,進行自動構建
  • 核心知識點是什麼?

"發佈-訂閱" 事件異步編程模型,要注意這個模型是只針對Git repo自身的,它訂閱了來自local的push事件,觸發者則是某一個開發者的git push操做。

5、發佈訂閱者模型引伸

  • vue組件通訊 $emit $on
  • vue異步優先隊列,$nextTick()自身訂閱發佈
  • vuex全局狀態樹 提交mutation commit() 隱式監聽
  • webhook event 新增請求報文頭
  • nodejs middleware next
  • child_process.fork 多線程通訊
  • ARP協議 私有局域網內的機器間通訊
  • MQTT協議 消息的訂閱與發佈
  • nodejs EventEmitter
  • vuex plugin subscribe
  • 基於Dijkstra算法的鏈路狀態路由 動態更新路由表
  • ZooKeeper動態服務發現和服務路由功能

若是仍是不懂,建議先閱讀樸靈大神的《深刻淺出nodejs》的異步章節,而且涉獵大量的非前端技術,並實踐。

不過對於這篇博文來講,webhook是Git的一種機制,可用於前端自動化構建是關鍵知識點。

固然,關於這篇博文,其實有些流程還不是很清晰,文章內容可能在我作完一次完整的Jenkins自動化構建實驗後更新。

參考:
https://www.wikiwand.com/en/W...
https://developer.github.com/...
https://developer.github.com/...
https://developer.github.com/...
https://developer.github.com/...
https://blog.csdn.net/boling_...

That it !

相關文章
相關標籤/搜索