GitHub 的网络钩子(webhook)功能,可以很方便的实现自动化部署。本文记录了使用 Node.js 的开发部署过程,当项目的 master 分支被推时,将在服务器进行自动部署,完整代码见 GitHub

添加网络钩子

  1. 在 GitHub 的相应项目首页,点击右上角菜单 Setting, 点击左侧菜单 Webhooks,点击右上角按钮 Add webhook

  2. 设置 Payload URL 为接收事件的地址,Content type 建议选择 applicaiton/jsonSecret 可选填任意字符串,Which events would you like to trigger this webhook? 设为 Just the push event.,勾选 Active,点击下方的 Add webhook 按钮

开发处理请求

接收请求

使用 Node.js 建立一个 http 服务器,接收 POST 请求并处理其提交数据

const { createServer } = require('http');
const port = process.env.GITHUB_WEBHOOK_PORT || '3000'; const server = createServer((req, res) => {
if('POST' === req.method){
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
});
}
}) server.listen(port, () => {
console.log(`Listening on ${port}`);
});

如果需要更改默认端口 3000,可以先运行以下命令添加环境变量(NUMBER 为任意端口)

export GITHUB_WEBHOOK_PORT=NUMBER

解析 Body

在 req 的 end 事件处理器中,把字符串 body 解析成对象

    req.on('end', () => {
try{
body = JSON.parse(decodeURIComponent(body).replace(/^payload=/, ''));
}catch(e){
console.log(e)
}

如果 Content type 设置为 applicaiton/json,只需要 body = JSON.parse(body) 即可,以上代码兼容了 Content type 设置为 application/x-www-form-urlencoded 的情况

拉取更新

根据 body 的 push 负载,提取项目和分支信息,如果是 master 分支,则执行进入对应项目,拉取分支的命令

      if('object' === typeof body){
if('refs/heads/master' === body.ref){
const { exec } = require('child_process');
const command = `cd ../${body.repository.name} && git pull origin master`;
exec(command, (error, stdout, stderr) => {
});

注意这里的项目所在的目录,与此应用所在的目录,是在同一个父目录下的,如果不是可以相应调整命令的进入路径

验证密钥

以上步骤已经实现了自动拉取更新,不过存在安全性的问题,因为不仅仅 GitHub 可以发送这样的请求,所以最好设置 Secret 以进行安全验证

const secret = process.env.GITHUB_WEBHOOK_SECRET || '';
...
req.on('end', () => {
if('' !== secret){
const { createHmac } = require('crypto');
let signature = createHmac('sha1', secret).update(body).digest('hex');
if(req.headers['x-hub-signature'] !== `sha1=${signature}`){
console.log('Signature Error');
res.statusCode = 403;
res.end();
return;
}
}

运行应用前,先运行以下命令增加密钥变量(STRING 为任意字符串)

export GITHUB_WEBHOOK_SECRET=STRING

  • 设置了 Secret 后,GitHub 在发送请求时,会在请求头增加 x-hub-signature 为 sha1=SIGNATURE, 其中 SIGNATURE 为 body 的 密钥为 Secret,算法为 sha1 的 HMAC 16 进制值
  • 通过对 Secret 的检验,可以确保只有知道了 Secret,才能发送正确的带 x-hub-signature 头的请求,否则将拒绝请求
  • 以上代码兼容了不设置 Secret 的情况,即如果没有增加变量 GITHUB_WEBHOOK_SECRET,则按原有逻辑处理,不会进行检验

本地钩子构建

如果项目在拉取更新后需要构建,那么可以 command 变量后面加上构建命令,例如 && npm run build,但是不同项目的构建命令有可能是不一样的,而且有的项目的构建命令可能还比较复杂,这些情况下可以通过设置 git 的本地钩子进行处理

cd /PATH/TO/PROJECT/.git/hooks

nano post-merge

#!/bin/sh
SHELL_SCRIPT

chmod +x post-merge

  • 其中 /PATH/TO/PROJECT/ 为项目的目录位置,SHELL_SCRIPT 可以为任意 Shell 脚本
  • 因为 git pull 是 git fetch 和 git merge 的组合,所以拉取更新会触发 post-merge 钩子
  • 默认新增的文件是没有执行权限的,所以需要通过 chmod 增加 x

部署应用上线

应用部署上线需要实现持久化和自动化,即项目应该一直在运行,如果服务器重启,项目应该自动启动

变量自动创建

/etc/profile.d/ 里的变量创建脚本会在服务器重启时自动运行,所以添加一个设置脚本进去

nono /etc/profile.d/github-webhook.sh

export GITHUB_WEBHOOK_PORT=NUMBER
export GITHUB_WEBHOOK_SECRET=STRING

运行以下命令可以使变量创建马上生效

source /etc/profile

pm2 运行应用

pm2 可以确保 Node 应用的持续运行,并可通过配置实现监控和热更新等功能

npm install pm2 -g

pm2 start app.js --name github-webhook

重启自动运行

pm2 还内置支持配置自启动原有应用,通过以下命令实现

pm2 startup

pm2 save

pm2 startup 会创建并开启开机自动运行的服务, pm2 save 会保存当前的 pm2 运行应用,作为重启后的恢复内容

总结

在基于 GitHub webhook 的自动化部署中,主要使用了以下技术:

  • Node.js 的 http,child_process 和 crypto 模块
  • Git 的 post-merge Shell 钩子
  • profile 的自动变量设置和 pm2 工具

利用 Github 网络钩子实现自动化部署的更多相关文章

  1. 利用github的webhook进行自动部署

    利用github的webhook进行自动部署 github提供了webhook功能,大概意思就是,当你提交了代码,git检测到你进行了push,可以调起你一个你知道的url. 这个功能有什么用了?比如 ...

  2. 利用jenkins做项目的自动化部署

    最近领导要求上海本地的项目需要使用进jenkins实现自动化部署,以便可以直接将项目移交给运维的同学,减轻开发的工作量.记录下这次爬坑的过程. 一.前言 Jenkins是基于Java开发的一种持续集成 ...

  3. 服务器(三):利用github的webhooks实现自动部署

    实现自动部署的关键就是利用github的webhooks,我们在github建立一个项目之后,在项目主页点击Settings,看到Webhooks点击打开可以添加一个链接,这里的意思是,github可 ...

  4. 编写自己的 GitHub Action,体验自动化部署

    本文将介绍如何使用 GitHub Actions 部署前端静态页面,以及如何自己创建一个 Docker 容器 Action. 简介 Actions GitHub Actions 是 GitHub 官方 ...

  5. 利用Powershell在IIS上自动化部署网站

    本文主要讲如何通过Powershell在IIS上自动化部署ASP.NET网站,而不涉及Powershell的基本语法,如果没有Powershell基础的同学也可以把本文作为学习Powershell的基 ...

  6. Centos7.6上利用docker搭建Jenkins来自动化部署Django项目

    一般情况下,将一个项目部署到生产环境的流程如下: 需求分析-原型设计-开发代码-内网部署-提交测试-确认上线-备份数据-外网更新-最终测试,如果发现外网部署的代码有异常,需要及时回滚. 整个过程相当复 ...

  7. 在阿里云Centos7.6上利用docker搭建Jenkins来自动化部署Django项目

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_84 一般情况下,将一个项目部署到生产环境的流程如下: 需求分析-原型设计-开发代码-内网部署-提交测试-确认上线-备份数据-外网更 ...

  8. github使用Webhooks实现自动化部署

    参考: https://blog.csdn.net/u013764814/article/details/85240752 -------------------------------------- ...

  9. 如何用Github钩子做自动部署

    最近机缘巧合的购置了域名和服务器,不用实在是浪费,再加上一直没有属于自己的个人网站,所以打算用hexo在服务器上玩一下,这样也就不用再纠结用Github pages还是Gitee pages了.当然, ...

随机推荐

  1. git 更换push 提交地址

    git 删除远程地址 1.找到对应项目 右键点击 GIT Bash Here 2.输入命令 git remote rm origin 3.对应项目 右键点击 GIT Sync..... 4.点击Man ...

  2. Java循环和数组练习题:打印素数升级版

    前两天一个小伙伴问了我一个数组的练习题,我一看思路很清晰,就是打印素数加了个数组.没想到写的时候啪啪打脸,终究还是没逃过眼高手低.本来不打算发出来了,因为发出来愈发显得我很菜,最后还是打算分享出来,一 ...

  3. 安装RationalRose的问题解决

    列出大问题:在这一步无法进行下一步,直接就只能退出. 翻译过来的意思是:IBM安装程序被完全下载之前就终止了,大概是这个意思. 然后我就直接进了IBM的官网看了一下产品支持,上面解释说是组件clear ...

  4. 动态网站项目(Dynamic Web Project)CRUD(增删改查)功能的实现(mvc(五层架构)+jdbc+servlet+tomcat7.0+jdk1.8),前端使用JSP+JSTL+EL组合

    代码分享链接 https://pan.baidu.com/s/1UM0grvpttHW9idisiqa6rA    提取码:hx7c 图示           项目结构 1.SelectAllUser ...

  5. 使用PyTorch进行迁移学习

    概述 迁移学习可以改变你建立机器学习和深度学习模型的方式 了解如何使用PyTorch进行迁移学习,以及如何将其与使用预训练的模型联系起来 我们将使用真实世界的数据集,并比较使用卷积神经网络(CNNs) ...

  6. POJ 1797 最短路变形所有路径最小边的最大值

    题意:卡车从路上经过,给出顶点 n , 边数 m,然后是a点到b点的权值w(a到b路段的承重),求卡车最重的重量是多少可以从上面经过. 思路:求所有路径中的最小的边的最大值.可以用迪杰斯特拉算法,只需 ...

  7. LeetCode46 回溯算法求全排列,这次是真全排列

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写 ...

  8. Ubuntu在Anaconda中安装TensorFlow GPU,Keras,Pytorch

    安装TensorFlow GPU pip install --ignore-installed --upgrade tensorflow-gpu 安装测试: $ source activate tf ...

  9. 一个基于深度学习回环检测模块的简单双目 SLAM 系统

    转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12634631.html 写在前面 最近在搞本科毕设,关于基于深度学 ...

  10. python使用镜像源安装库

    pip install django -i http://pypi.douban.com/simple --trusted-host pypi.douban.com 豆瓣 :http://pypi.d ...