webhook

定义

Webhooks allow you to build or set up integrations, such as GitHub Apps , which subscribe to certain events on GitHub.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You're only limited by your imagination.

留神要害语句,当咱们触发一个事件(比方git push)的时候,github会给我配置的url发一个post申请,并携带一些参数

主动部署过程

这次咱们玩的正规一点

指标:本地一行命令npm run dp 实现我的项目主动打包上传部署

过程:
1.本地命令触发本地shell脚本,主动打包和git add commit push
2.git push会使github发一个post申请给指标服务
3.当服务被触发的时候,执行相干脚本
4.脚本必定使指标展现目录从github拉文件
5.拉完就实现主动部署了

webhook配置

设置github

进入github 创立一个新我的项目helloworld,在该项目标setting外面的webhooks外面addwebhooks

咱们还能够配置明码,触发事件等等行为

这里咱们的content-type 抉择 application/json

palyload

咱们看下palyload模式

POST /payload HTTP/1.1Host: localhost:4567X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958X-Hub-Signature: sha1=7d38cdd689735b008b3c702edd92eea23791c5f6User-Agent: GitHub-Hookshot/044aaddContent-Type: application/jsonContent-Length: 6615X-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,    ...  }}

这个post申请会有独特的申请头,会有和仓库相干的参数repository,会有和提交人相干的参数sender,前面发邮件的时候会用的到

本地脚本配置

流程

  • vue-cli初始化我的项目
  • 增加近程库为github中hello-world源
  • npm sript外面配置
"dp": "npm run build && sh dp.sh"

-编写dp.sh脚本

#!/bin/shecho '增加'git add .echo 'commit'git commit -m 'dp'echo '推送中..'git push origin master

这一套下来,咱们就能够实现 npm run dp实现主动打包和上传啦

npm scipt

说到npm script,插一嘴,其实这个就是shell脚本
npm 脚本的原理非常简单。每当执行npm run,就会主动新建一个 Shell,在这个 Shell 外面执行指定的脚本命令。因而,只有是 Shell(个别是 Bash)能够运行的命令,就能够写在 npm 脚本外面。

比拟特地的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录退出PATH变量,执行完结后,再将PATH变量复原原样。

这意味着,当前目录的node_modules/.bin子目录外面的所有脚本,都能够间接用脚本名调用,而不用加上门路。比方,以后我的项目的依赖外面有 Mocha,只有间接写mocha test就能够了。

"test": "mocha test"

而不必写成上面这样。

"test": "./node_modules/.bin/mocha test"

因为 npm 脚本的惟一要求就是能够在 Shell 执行,因而它不肯定是 Node 脚本,任何可执行文件都能够写在外面。

npm 脚本的退出码,也恪守 Shell 脚本规定。如果退出码不是0,npm 就认为这个脚本执行失败。

服务器脚本配置

webhook.js

首先服务器装node,pm2。用pm2治理webhook.js服务
编写webhook.js服务,用于对github的那个post申请作出相应
webhook.js

let http = require('http');var spawn = require('child_process').spawn;let sendMail = require('./sendMail.js');let server = http.createServer(function(req,res){    console.log(req.method,req.url);    if(req.url == '/webhook' && req.method =='POST'){        let buffers = [];        req.on('data',function(data){            buffers.push(data);        });        req.on('end',function(){            //获取webhook申请的payload,也是            let payload = JSON.parse(Buffer.concat(buffers));            console.log(payload.pusher,payload.head_commit)            let event = req.headers['x-github-event'];                        console.log(payload.repository)            res.setHeader('Content-Type','application/json');            res.end(JSON.stringify({"ok":true}));//这个是github约定的,如果是这个,delivery记录就是绿色胜利态,否者就是红色,各种错误信息            if(event === 'push'){                //执行相应的shell                let child = spawn('sh', [`${payload.repository.name}`]);                let buffers = [];                child.stdout.on('data', function (buffer) { buffers.push(buffer)});                child.stdout.on('end', function () {                    //获取子过程日志信息                    let logs = Buffer.concat(buffers).toString();                    //发邮件                    sendMail(`            <h1>部署日期: ${new Date()}</h1>            <h2>部署人: ${payload.pusher.name}</h2>            <h2>部署邮箱: ${payload.pusher.email}</h2>            <h2>提交信息: ${payload.head_commit.message}</h2>            <h2>布署日志:<br/> ${logs.replace(/n/,'<br/>')}</h2>                `);                });            }        });    }else{        res.end('Now Found!!!!');    }});server.listen(4000,()=>{    console.log('服务正在4000端口上启动!');}); 

sendmail.js

const nodemailer = require('nodemailer');let transporter = nodemailer.createTransport({    // host: 'smtp.ethereal.email',    service: 'qq', // 应用了内置传输发送邮件 查看反对列表:https://nodemailer.com/smtp/well-known/    port: 465, // SMTP 端口    secureConnection: true, // 应用了 SSL    auth: {        user: '250351xxxx@qq.com',        // 这里明码不是qq明码,是你设置的smtp受权码        pass: '你的受权码',    }});function sendMail(message){    let mailOptions = {        from: '"250351xxxx" <250351xxxx@qq.com>', // 发送地址        to: '250351xxxx@qq.com', // 接收者        subject: '部署告诉', // 主题        html:message // 内容主体    };    // send mail with defined transport object    transporter.sendMail(mailOptions, (error, info) => {        if (error) {            return console.log(error);        }        console.log('Message sent: %s', info.messageId);    });}module.exports = sendMail; 

helloworld.sh

编写helloworld.sh脚本,留神这个名字不是乱取的,是你github仓库的名字,因为在webhook.js外面我是这么执行的脚本

let child = spawn('sh', [`${payload.repository.name}`]); //这里尽管我touch helloworld.sh 然而如同ls的时候没有扩展名,所以这里执行的时候也就没有写

helloworld.sh外面这么写

#!/bin/shecho '开始执行webhook钩子'unset GIT_DIR DIR_ONE=/home/user/www/  #此目录为服务器页面展现目录 cd $DIR_ONEecho '革除git缓存'git clean -dfecho '拉取近程代码'git pull origin masterecho '部署实现' 

此时/home/user下会有 www文件夹,hellowrold可执行文件,webhook.js服务文件

实操

  1. 本地增加近程github库 helloworld
  2. 近程服务器/home/user/www/ 增加近程github库 helloworld
  3. 编写每个局部脚本
  4. pm2 启动webhook.js
  5. 本地npm run dp 实现首次上传
  6. 关上浏览器,此时页面能失常显示为首次内容
  7. 扭转组件的内容,从新npm run dp
  8. 关上浏览器,此时页面能失常显示为第二次内容,部署胜利

如果不胜利,咱们就须要查看下日志了,关上qq邮箱

如果qq邮箱里没有邮件
在服务器 pm2 log 查看下日志看哪出问题了,有post申请信息吗? 是不是webhook.js没启动?是不是没有git push下来(网不好的时候会遇到,再push一次即可),是不是post申请收回去了然而服务没承受到,查看github的webhook的delivery记录

注意事项

1.服务器权限的问题,我倡议还是集体领有集体的服务器比拟好,root权限,想怎么整就怎么整。如果用公司的服务器,ningx拜访的时候跨目录可能出问题,ssh配置也可能出问题
这里强烈推荐一下腾讯云,最近做流动,88玩一年,平安耐操
0.1折服务器链接。买了不会玩的能够私聊我,三陪政策,包教包会.....

2.ssh怎么配

首先登录近程服务器,命令行输出 ssh-keygen,生成ssh公钥私钥

其次本地首先看有没有~/.ssh目录,没有的化也执行下面的操作

而后 scp ~/.ssh/id_rsa.pub username@hostname.com:~/.ssh/authorized_keys (把本地共钥复制到近程服务器authorized_keys这个文件中)

再在本地的~/.ssh中增加一个config文件,外面这么写

Host           qqHostName      你的腾讯云服务器ipPort          22   (ssh默认端口,==括号外面的不要填上去==)User              rootIdentityFile    ~/.ssh/id_rsa

功败垂成,当在控制台输出ssh qq 就主动连上腾讯云服务器了

3.本地我的项目和github的ssh连贯
~/.ssh/id_rsa.pub放到github公钥外面
4.实操各种bug
见实操,还有其余问题请评论区指出