git鉤子與自動化部署(下)

1340.640.jpg


接着上篇文章git鉤子與自動化部署(上)繼續說html

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請求,並攜帶一些參數vue

自動部署過程

此次咱們玩的正規一點node

目標:本地一行命令npm run dp 實現項目自動打包上傳部署git

過程:
1.本地命令觸發本地shell腳本,自動打包和git add commit push
2.git push會使github發一個post請求給目標服務
3.當服務被觸發的時候,執行相關腳本
4.腳本確定使目標展現目錄從github拉文件
5.拉完就完成自動部署了github

webhook配置

設置github

進入github 建立一個新項目helloworld,在該項目的setting裏面的webhooks裏面addwebhooks
image.pngweb

咱們還能夠配置密碼,觸發事件等等行爲vue-cli

這裏咱們的content-type 選擇 application/jsonshell

palyload

咱們看下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

本地腳本配置

流程

  • vue-cli初始化項目
  • 添加遠程庫爲github中hello-world源
  • npm sript裏面配置
"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 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/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服務文件

實操

  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郵箱
WX20191118-181529@2x.png
若是qq郵箱裏沒有郵件
在服務器 pm2 log 查看下日誌看哪出問題了,有post請求信息嗎? 是否是webhook.js沒啓動?是否是沒有git push上去(網很差的時候會遇到,再push一次便可),是否是post請求發出去了可是服務沒接受到,查看github的webhook的delivery記錄
image.png

注意事項

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 就自動連上騰訊雲服務器了
image.png

3.本地項目和github的ssh鏈接
~/.ssh/id_rsa.pub放到github公鑰裏面
4.實操各類bug
見實操,還有其餘問題請評論區指出

總結

介紹了webhook鉤子以及利用它進行簡單自動化部署的實例。並對其中各類可能遇到的問題作了說明。但願能給你們帶來一些幫助。

最近老大讓我研究把這一套包括部署和eslint同jeckins結合,造成固定流程。壓力山大,等研究出來了,再過來叨叨下吧


題外話,寫文章真的很辛苦,寫了這麼久了,居然一個打賞也沒收到,已哭暈。有沒有哪位大哥能給個打賞,讓我開開葷,支持支持我唄......

相關文章
相關標籤/搜索