文档章节

通过 Github-Webhook 实现的轻量级自动化构建Nodejs微服务

DiamondFsd
 DiamondFsd
发布于 2017/02/13 21:43
字数 1042
阅读 384
收藏 8

我想要实现这样的功能,只要我 push 代码到 github仓库中,那么我的服务器就会自动执行预先写好的脚本。 类似于:

  1. 拉取最新代码
  2. 更新项目依赖
  3. 编译
  4. 重启项目

有很多持续集成工具都可以实现这样的功能,可是我的服务器内存小呀,没那么多资源去部署一个持续化集成工具了,只能自己写一个轻量级工具来完成这项工作。

Github Webhooks 详解

我们每个github仓库可以都在 Settings -> Webhooks -> Add webhooks 配置 Webhooks。配置这个的作用就是让代码库有某些动作的时候,将这些信息提交到我们指定的服务器地址上。

我个人代码库的配置信息如下 alt

Payload URL

用于接收 Webhook 请求的接口地址

Content type

请求时数据类型,有两种可选

  1. application/json,返回类似 { key1: value, key2: value ...} 的json串
  2. application/x-www-form-urlencoded, 返回类似 key1=value1&key2=value2... 的键值对

Secret

为了让我们自身服务器信任这次请求不是伪造的,我们会在配置 Webhooks 的时候填写一个 Secret 信息。Github 每次请求我们接口的时候,都会将请求的数据和我们配置的 Secret 来进行 HMAC-SHA1 签名,然后放入请求头 X-Hub-Signature 中,以便我们服务器进行签名验证。

Which events would you like to trigger this webhook?

选择需要触发 webhook 的事件,我这里就选默认,当有 push 事件的时候触发。更多其他事件可以参考官方文档 github-webhooks#evnets

配置好后,最后的请求信息如下:

Headers (请求头)

Request URL: http://42.96.203.79:9000/github/webhook
Request method: POST
content-type: application/json
Expect: 
User-Agent: GitHub-Hookshot/886c556
X-GitHub-Delivery: 5e4faa80-f1b6-11e6-82ca-b15a28b37514
X-GitHub-Event: push
X-Hub-Signature: sha1=******************************************

Payload (请求携带的数据)

{
  "ref": "refs/heads/master", // 属于哪个分支
  "before": "af93824edb56a00ce161ac66c90fe2e7390d3b05",
  "after": "ffe1d63eef115407bfb046de5b2fa9cb226bcfa9",
  "created": false,
  "deleted": false,
  "forced": false,
  "base_ref": null,
  "compare": "https://github.com/k55k32/cms-front/compare/af93824edb56...ffe1d63eef11",
  "repository": {
    "id": 74550213,
    "name": "cms-front",
    "full_name": "k55k32/cms-front",
    "owner": {
      "name": "k55k32",
      "email": "diamondfsd@gmail.com"
    },
    "private": false,
    "html_url": "https://github.com/k55k32/cms-front",
    "description": "my-blog",
    "fork": false,
    "url": "https://github.com/k55k32/cms-front",  // 项目的 url
    "forks_url": "https://api.github.com/repos/k55k32/cms-front/forks",
    "keys_url": "https://api.github.com/repos/k55k32/cms-front/keys{/key_id}",
    "collaborators_url": "https://api.github.com/repos/k55k32/cms-front/collaborators{/collaborator}",
    "teams_url": "https://api.github.com/repos/k55k32/cms-front/teams",
    "hooks_url": "https://api.github.com/repos/k55k32/cms-front/hooks"
  }
  ... 太长了,就不全部贴上了,大概有效的信息就这些
}

Githook-express Nodejs 服务

githook-express 这是我写的一个小服务,用于接收并解析webhook请求,并通过配置文件,执行指定的脚本,实现自动编译部署发布等功能。

而且这个服务在服务器上只占用了 33M 的内存,完全符合我目前的需求。 alt

核心代码

app.post('/github/webhook', function (req, res) {
    // 获取当前服务配置
    var config = utils.getConfig(configPath) 
    console.log('read config file:', config)
    // 获取事件名称
    var eventName = req.get('X-GitHub-Event')
    // 获取签名信息
    var sign = req.get('X-Hub-Signature')
    var delivery = req.get('X-GitHub-Delivery')
    console.log(new Date(), ' [HOOK REQUEST]')
    console.log('event:', eventName)
    console.log('sign:', sign)
    console.log('delivery:', delivery)
    // 获取仓库地址
    var repositoryUrl = req.body.repository.url
    // 获取分支信息
    var refHead = req.body.ref
    console.log('push head', refHead)
    console.log('repositoryUrl: ', repositoryUrl)
    // 查找配置文件中,是否有该仓库的配置
    var executer = config[repositoryUrl]
    console.log('executer: ', executer)
    // 如果有配置,并且分支为 `master` 分支,就继续执行
    if (executer && refHead === 'refs/heads/master') { 
      var secret = executer.secret
      var shell = executer.events[eventName] // 获取仓库事件需要执行的代码
      if (shell) {
        if (vaildHMAC(secret, req._body, sign)) { // 验证签名
          setTimeout(() => {
            console.log('new thread execute shell', shell)
            exec(shell, (err,stdout,stderr) => { // 执行配置文件中对应的脚本
              if (stdout) {
                console.log('stdout out >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
                console.log(stdout) // 输出脚本执行结果
                console.log('stdout over >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
              }

              err && console.log('hasErr: ', err)
              stderr && console.log('stderr: ', stderr)
            })
          }, 500)
        } else {
          console.log('vaild sha1 error: ',secret , sign);
        }
      } else {
        console.log('not event target: ', eventName)
      }
    }
    res.end()
})  

配置文件

是一个 json 数据文件,以仓库名称作为key,然后存放着 webhook 上配置的 secret,还有对应事件需要执行的脚本文件。

{
  "https://github.com/k55k32/MessageWar": {
    "secret": "github-hook-message-**********************",
    "events": {
      "push": "/root/msg-war-deply.sh"
    }
  },
  "https://github.com/k55k32/MessageWar-Websocket": {
    "secret": "oh-no-i'm-so-**********************",
    "events": {
      "push": "/root/websocket-msg-deply.sh"
    }
  },
  "https://github.com/k55k32/cms-admin-end": {
    "secret": "we-are-both-y**********************",
    "events": {
      "push": "/root/repositories/cms-admin-end/start.sh"
    }
  },
  "https://github.com/k55k32/cms-front": {
    "secret": "ihave-no-idea-**********************",
    "events": {
      "push": "/root/repositories/cms-front/start.sh"
    }
  }
}

这里就是介绍了一下 Webhooks 在实际当中的一个简单应用,有更多想法,大家可以交流交流。


我的个人博客

© 著作权归作者所有

共有 人打赏支持
DiamondFsd
粉丝 87
博文 15
码字总数 16372
作品 0
深圳
程序员
三个分享——异步流程控制 / Modern Node.js/Java项目如何与Node.js共存

分享1《深入浅出js(Node.js)异步流程控制》 StuQ分享专题《深入浅出js(Node.js)异步流程控制》 InfoQ 前端之巅分享 精简版 摘要 目前在js流程控制领域越来越乱,各种派系。。。比如promi...

i5ting
2016/07/18
1K
6
你应该学会的Postman用法(2)-自动化测试

前言 之前的一篇文章《你应该学会的Postman用法》,主要介绍了postman的一些高级的用法,便于日常开发和调试使用,本文的基础是对postman的基本使用以及一些高级用法有一定的了解,如对此不太...

IT米粉
06/14
0
0
Nest.js 5.4.0 发布,支持微服务的 AOP 风格 Node.js 框架

Nest.js 是用于构建高效且可伸缩 Web 应用程序的渐进式 Node.js 框架。 完美支持 Typescript 面向 AOP 编程 支持 typeorm Node.js 版的 spring 构建微服务应用 本次更新如下: 特征 common:...

左华栋
昨天
0
0
Nest.js 5.3.11,支持微服务的 AOP 风格 Node.js 框架

Nest.js 是用于构建高效且可伸缩 Web 应用程序的渐进式 Node.js 框架。 完美支持 Typescript 面向 AOP 编程 支持 typeorm Node.js 版的 spring 构建微服务应用 本次更新如下: Bug 修复 核心...

左华栋
10/08
0
0
Oracle推出轻量级Java微服务框架Helidon

近日,Oracle 推出 了一个新的开源框架 Helidon ,该项目是一个用于创建基于微服务的应用程序的Java库集合。和 Payara Micro 、 Thorntail (之前的 WildFly Swarm )、 OpenLiberty 、TomEE...

小刀爱编程
10/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

微信小程序开发系列六:微信框架API的调用

微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发...

JerryWang_SAP
33分钟前
1
0
5 个用 Python 编写 web 爬虫的方法

大家在读爬虫系列的帖子时常常问我怎样写出不阻塞的爬虫,这很难,但可行。通过实现一些小策略可以让你的网页爬虫活得更久。那么今天我就将和大家讨论这方面的话题。 我刚整理了一套2018最新...

糖宝lsh
33分钟前
1
0
docker安装redis、mongodb、mysql等

一、启动docker服务,设置镜像: systemctl start dockervi /etc/docker/daemon.json{ "registry-mirrors": ["https://registry.docker-cn.com"]} 二、下拉镜像: 在镜像中心h...

狼王黄师傅
今天
5
0
deepin系统使用deepin-wine安装exe程序

deepin自带原生deepin-wine使用命令如下: deepin-wine QQBrowser.exedeepin-wine QQMusicSetup.exe 默认安装的快捷方式位置: /root/.wine/drive_c/'Program Files'/Tencent/QQBrowser/......

临江仙卜算子
今天
4
0
快速get到学习Linux操作系统的点

快速get到学习Linux操作系统的点 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。Linux能够运行主要的UNIX工具软件...

linuxCool
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部