接着上篇文章git钩子与自动化部署(上)继续说html
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请求,并携带一些参数vue
此次咱们玩的正规一点node
目标:本地一行命令npm run dp
实现项目自动打包上传部署git
过程:
1.本地命令触发本地shell脚本,自动打包和git add commit push
2.git push会使github发一个post请求给目标服务
3.当服务被触发的时候,执行相关脚本
4.脚本确定使目标展现目录从github拉文件
5.拉完就完成自动部署了github
进入github 建立一个新项目helloworld,在该项目的setting里面的webhooks里面addwebhooksweb
咱们还能够配置密码,触发事件等等行为vue-cli
这里咱们的content-type 选择 application/jsonshell
咱们看下palyload形式npm
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, ... } }
这个post请求会有独特的请求头,会有和仓库相关的参数repository,会有和提交人相关的参数sender,后面发邮件的时候会用的到json
"dp": "npm run build && sh dp.sh"
-编写dp.sh脚本
#!/bin/sh echo '添加' git add . echo 'commit' git commit -m 'dp' echo '推送中..' git push origin master
这一套下来,咱们就能够实现 npm run dp完成自动打包和上传啦
说到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 就认为这个脚本执行失败。
首先服务器装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脚本,注意这个名字不是乱取的,是你github仓库的名字,由于在webhook.js里面我是这么执行的脚本
let child = spawn('sh', [`${payload.repository.name}`]); //这里虽然我touch helloworld.sh 可是好像ls的时候没有扩展名,因此这里执行的时候也就没有写
helloworld.sh里面这么写
#!/bin/sh echo '开始执行webhook钩子' unset GIT_DIR DIR_ONE=/home/user/www/ #此目录为服务器页面展现目录 cd $DIR_ONE echo '清除git缓存' git clean -df echo '拉取远程代码' git pull origin master echo '部署完成'
此时/home/user下会有 www文件夹,hellowrold可执行文件,webhook.js服务文件
若是不成功,咱们就须要查看下日志了,打开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 qq HostName 你的腾讯云服务器ip Port 22 (ssh默认端口,==括号里面的不要填上去==) User root IdentityFile ~/.ssh/id_rsa
大功告成,当在控制台输入ssh qq 就自动连上腾讯云服务器了
3.本地项目和github的ssh链接
~/.ssh/id_rsa.pub放到github公钥里面
4.实操各类bug
见实操,还有其余问题请评论区指出
介绍了webhook钩子以及利用它进行简单自动化部署的实例。并对其中各类可能遇到的问题作了说明。但愿能给你们带来一些帮助。
最近老大让我研究把这一套包括部署和eslint同jeckins结合,造成固定流程。压力山大,等研究出来了,再过来叨叨下吧
题外话,写文章真的很辛苦,写了这么久了,居然一个打赏也没收到,已哭晕。有没有哪位大哥能给个打赏,让我开开荤,支持支持我呗......