接着上篇文章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結合,造成固定流程。壓力山大,等研究出來了,再過來叨叨下吧
題外話,寫文章真的很辛苦,寫了這麼久了,居然一個打賞也沒收到,已哭暈。有沒有哪位大哥能給個打賞,讓我開開葷,支持支持我唄......