- 最先期方式: 前端寫好代碼以後本地構建, 經過服務器
xftp
或ftp
把文件上傳到服務器進行更新- 使用Git後: 服務器經過
git clone
的項目, 在項目的根目錄執行git pull origin [branch]
拉去倉庫中最新的代碼- 自動化部署: 經過配置
WebHook
及服務器後: 項目打包完成提交到代碼庫中, 服務器自動拉去git倉庫中最新的代碼
底層實現原理:javascript
- 在github配置webhook的地方填寫服務端的url, 每次push代碼到github上, github都會向webhook中的url發送一條請求
- 服務端接收到請求後, 通過驗證後執行本地的bash腳本, 腳本中編寫從github拉去代碼的命令。
Centos7.*
, Node
, Git
Gitee
/ Github
1.1 進入到代碼庫配置webhook界面前端
這裏以github爲例
登陸github -> 進入到repository中 -> 找到設置 -> 進入webhookvue
參考 web-hook
server.jsjava
const http = require('http') // http模塊 const { spawn } = require('child_process') // 子進程, 用來執行腳本 const { PORT, SECRET } = require('./src/config') // 配置文件 const { sign } = require('./src/utils') // 工具文件 const { resultString } = require('./src/resModel') // 服務端返回JSON const server = http.createServer((req, res) => { // 打印進來的請求 console.log(`--- ${req.method} --- ${req.url} ---`) // 設置header爲json格式 res.setHeader('Content-Type', 'application/json') if (req.method === 'POST' && req.url === '/webhook') { // post /webhook 都爲github發來的請求 console.log('--- 命中webhook ---') // 獲取body let buffers = [] req.on('data', buffer => { buffers.push(buffer) }) req.on('end', () => { let body = Buffer.concat(buffers) // 獲取header中event的字段, github 爲push, gitee爲 Push Hook let event = req.headers['x-github-event'] || req.headers['x-gitee-event'] console.log(`--- Event 名字: ${event} ---`) if (req.headers['user-agent'] === 'git-oschina-hook') { // gitee console.log('--- Gitee 平臺 ---') // SECRET是在config.js中配置了 if (req.headers['x-gitee-token'] === SECRET) { if (event === 'Push Hook') { console.log('--- push 任務命中 ---') let payload = JSON.parse(body) console.log( `--- 任務名稱: ${payload.repository.name}, 路徑: ${payload.repository.path} ---` ) // 開啓子進程執行對應的腳本 // payload.repository.path 是gitee/github傳來的repo的路徑 // 經過path的值執行sh目錄下對應的腳本 // 好比項目名字叫web_hook path的值就是web_hook // 執行的腳本就是./sh/web_hook.sh let child = spawn('sh', [`./sh/${payload.repository.path}.sh`]) // 接收子進程傳來的數據 let buffers = [] child.stdout.on('data', buffer => { console.log(`--- 接受data ${buffer.toString()} ---`) buffers.push(buffer) }) child.stdout.on('end', () => { let log = Buffer.concat(buffers) console.log(log.toString()) console.log('自動化拉取完畢') }) } // 返回的json, 配置在./src/resModel中 res.end(resultString('success', 0)) } else { // 其餘的請求返回不容許 return res.end(resultString('Not Allowed', 1)) } } else { // github // 基本和上面的gitee同樣, 多一個校驗身份的步驟 console.log('--- Github 平臺 ---') let signature = req.headers['x-hub-signature'] // sign 方法配置在utils.js中 if (signature !== sign(body, SECRET)) { return res.end(resultString('Not Allowed', 1)) } if (event === 'push') { console.log('--- push 任務命中 ---') let payload = JSON.parse(body) console.log(payload.repository.name) let child = spawn('sh', [`./sh/${payload.repository.name}.sh`]) let buffers = [] child.stdout.on('data', buffer => { buffers.push(buffer) }) child.stdout.on('end', () => { let log = Buffer.concat(buffers) console.log(log.toString()) console.log('自動化拉取完畢') }) } res.end(resultString('success', 0)) } }) } res.end(resultString('Not Found', 1)) }) // 監聽端口, PORT配置在config.js中 server.listen(PORT, () => { console.log(`web-hook listen on http://localhost:${PORT}`) })
Tips: 接收github發送來的post參數: Webhooks | GitHub Developer Guide建議看gitee平臺的說明(中文的, 參數差很少) Giteegit
./sh/*.shgithub
#!/bin/bash WORK_PATH="/home/wwwroot/tools/vue-back" echo "------ 進入項目目錄 ------" cd $WORK_PATH echo "------ 已進項目目錄 ------" echo "------ 開始清理代碼 防止衝突 ------" git reset --hard origin/master git clean -f echo "------ 清理代碼完畢 ------" echo "------ 拉取master分支代碼 ------" git pull origin master echo "------ vue-back 持續集成完畢 ------"
自動部署效果圖: