node實(shí)現(xiàn)github自動(dòng)部署到云服務(wù)器

點(diǎn)擊查看源碼

目的

通過github管理的項(xiàng)目嫌褪,每次push后都需要到服務(wù)器pull代碼嵌言,然后手動(dòng)打包梯浪,重復(fù)的操作挺糟心的涂屁。但是github提供了Webhooks,可以實(shí)現(xiàn)本地push代碼到遠(yuǎn)程后,服務(wù)器自動(dòng)拉取遠(yuǎn)程代碼洁桌,自動(dòng)打包部署尸折,節(jié)省大量時(shí)間。

原理

github的Webhooks允許用戶設(shè)置post請求的接口地址庆冕,當(dāng)本地代碼推送到遠(yuǎn)程分支后康吵,github將主動(dòng)調(diào)用設(shè)置的接口,并將當(dāng)前修改相關(guān)信息作為請求參數(shù)給到接口访递。接口在服務(wù)器上被調(diào)用的時(shí)候晦嵌,就知道當(dāng)前遠(yuǎn)程代碼庫有更新,此時(shí)可以調(diào)用腳本執(zhí)行更新拷姿、打包等操作惭载。

用到的技術(shù)

接下來我會(huì)通過nodejs (opens new window)github-webhook-handler (opens new window)模塊實(shí)現(xiàn)監(jiān)聽github代碼push的事件,然后通過shell (opens new window)腳本實(shí)現(xiàn)代碼更新打包的操作响巢。

前提條件

  • 具有公網(wǎng)ip的云服務(wù)器
  • github倉庫

提供接口給github

接口的地址path通過github-webhook-handler模塊配置產(chǎn)生描滔,不需要自己額外的定義路由地址;同時(shí)需要設(shè)置secret踪古,用于github校驗(yàn)含长。

github的webhooks

1靶衍、通過createHandler方法,可以配置path和secret茎芋,這兩個(gè)參數(shù)自己隨便定義就可以。

const createHandler = require('github-webhook-handler')
const handler = createHandler({ path: '/webhook', secret: 'sdsdfssdfsdf' })

2蜈出、監(jiān)聽push事件

handler.on('push', event=> {
   // github推送通知到接口后田弥,會(huì)觸發(fā)該方法,并拿到github請求的參數(shù)
});

3铡原、監(jiān)聽error事件

handler.on('error', function (err) {
    console.error('Error:', err.message)
});

4偷厦、通過node的http模塊啟動(dòng)服務(wù)

http.createServer( (req, res)=> {
    handler(req, res, function (err) {
        console.log('err',err);
        res.statusCode = 404
        res.end('api 404')
    });
}).listen(3001,()=>{
    console.log('running in http://127.0.0.1:3001/');
});

5、編寫名為pull.sh的腳本

我的文章通過vuepress編寫燕刻,所以我需要做的有三個(gè)步驟:

  • 進(jìn)入到服務(wù)器上的vuepress項(xiàng)目
  • 通過git pull更新代碼
  • 通過npm run docs:build打包代碼
    當(dāng)然只泼,如果還有其他腳本也可以方進(jìn)入,完整腳本如下:
#!/bin/bash 
# 更新代碼
cd /xxx/xxx/項(xiàng)目名
git pull
npm run docs:build

6卵洗、監(jiān)聽到push事件后的處理

當(dāng)監(jiān)聽到push事件后请唱,event的payload參數(shù)中包含了github請求接口時(shí)的參數(shù),而我只想處理master分支代碼更新后过蹂,服務(wù)器自動(dòng)拉取代碼十绑,因此只判斷了event.payload.ref === 'refs/heads/master'時(shí)運(yùn)行腳本;

通過node的require('child_process').spawn方法可以運(yùn)行腳本酷勺,具體使用方法可見:child_process spawn(opens new window)

指定運(yùn)行'sh'腳本本橙,腳本路徑為./bin/pull.sh,即可上面寫的腳本文件。

spawn('sh', ['./bin/pull.sh']);
handler.on('push', event=> {
    try {
        const {repository,ref} = event.payload;
        const {full_name,name,private,size} = repository;
        const autoRun = ref === 'refs/heads/master';
        console.info(`
            - 接收到倉庫:【${full_name}】的推送消息脆诉;
            - 修改分支:【${ref}】;
            - 倉庫是否私有:${private};
            - 大猩跬ぁ:【${size}】
            - 是否需要自動(dòng)部署:${autoRun}】;
        `);

        // 判斷是否需要自動(dòng)部署
        if (!autoRun) {
            return
        }

        console.log('開始執(zhí)行腳本');
        const s = spawn('sh', ['./bin/pull.sh']);
        s.stdout.on('data', (data) => {
          console.log(`${name}:${data}`);
        });
        s.stderr.on('data', (data) => {
          console.log(`${name}: ${data}`);
        });
        console.log('has rebuild');
    } catch (e) {
        console.log('build error',e)
    }
});

7、使用pm2運(yùn)行項(xiàng)目

通過pm2可以讓項(xiàng)目在服務(wù)器上一直運(yùn)行击胜,不會(huì)關(guān)閉服務(wù)器后項(xiàng)目就停亏狰。 在此,通過腳本實(shí)現(xiàn)接口項(xiàng)目的啟動(dòng)潜的,在源碼的bin/prod.sh (opens new window)中有如下腳本:

pm2 start npm -i 1 --name 'auto-run-github' -- run start

8骚揍、在github的webhooks中配置接口

如下圖所示

  • Payload URL為你的接口地址,結(jié)尾應(yīng)該是github-webhook-handler設(shè)置的path參數(shù)結(jié)尾啰挪;
  • Content type選擇application/json;
  • Secret要和github配置保持一致信不;


完整代碼如下:

const http = require('http')
const createHandler = require('github-webhook-handler')
const handler = createHandler({ path: '/webhook', secret: 'sdsdfssdfsdf' })
const spawn = require('child_process').spawn;

handler.on('error', function (err) {
    console.error('Error:', err.message)
});

handler.on('push', event=> {
    try {
        const {repository,ref} = event.payload;
        const {full_name,name,private,size} = repository;
        const autoRun = ref === 'refs/heads/master';
        console.info(`
            - 接收到倉庫:【${full_name}】的推送消息;
            - 修改分支:【${ref}】;
            - 倉庫是否私有:${private};
            - 大型龊恰:【${size}】
            - 是否需要自動(dòng)部署:${autoRun}】;
        `);

        // 判斷是否需要自動(dòng)部署
        if (!autoRun) {
            return
        }

        console.log('開始執(zhí)行腳本');
        const s = spawn('sh', ['./bin/pull.sh']);
        s.stdout.on('data', (data) => {
          console.log(`${name}:${data}`);
        });
        s.stderr.on('data', (data) => {
          console.log(`${name}: ${data}`);
        });
        console.log('has rebuild');
    } catch (e) {
        console.log('build error',e)
    }
});

http.createServer( (req, res)=> {
    handler(req, res, function (err) {
        console.log('err',err);
        res.statusCode = 404
        res.end('api 404')
    });
}).listen(3001,()=>{
    console.log('running in http://127.0.0.1:3001/');
});
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抽活,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锰什,更是在濱河造成了極大的恐慌下硕,老刑警劉巖丁逝,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梭姓,居然都是意外死亡霜幼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門誉尖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罪既,“玉大人,你說我怎么就攤上這事铡恕∽粮校” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵探熔,是天一觀的道長驹针。 經(jīng)常有香客問我,道長诀艰,這世上最難降的妖魔是什么柬甥? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮涡驮,結(jié)果婚禮上暗甥,老公的妹妹穿的比我還像新娘。我一直安慰自己捉捅,他們只是感情好撤防,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棒口,像睡著了一般寄月。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上无牵,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天漾肮,我揣著相機(jī)與錄音,去河邊找鬼茎毁。 笑死克懊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的七蜘。 我是一名探鬼主播谭溉,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼橡卤!你這毒婦竟也來了扮念?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤碧库,失蹤者是張志新(化名)和其女友劉穎柜与,沒想到半個(gè)月后巧勤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弄匕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年颅悉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迁匠。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡签舞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柒瓣,到底是詐尸還是另有隱情,我是刑警寧澤吠架,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布芙贫,位于F島的核電站,受9級特大地震影響傍药,放射性物質(zhì)發(fā)生泄漏磺平。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一拐辽、第九天 我趴在偏房一處隱蔽的房頂上張望拣挪。 院中可真熱鬧,春花似錦俱诸、人聲如沸菠劝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赶诊。三九已至,卻和暖如春园骆,著一層夾襖步出監(jiān)牢的瞬間舔痪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工锌唾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锄码,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓晌涕,卻偏偏與公主長得像滋捶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子渐排,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容