最先期方式: 前端寫好代碼以後本地構建, 經過服務器xftp
或ftp
把文件上傳到服務器進行更新javascript
使用Git後: 服務器經過git clone
的項目, 在項目的根目錄執行 git pull origin [branch]
拉去倉庫中最新的代碼前端
自動化部署: 經過配置WebHook
及服務器後: 項目打包完成提交到代碼庫中, 服務器自動拉去git倉庫中最新的代碼vue
實現原理:java
使用環境: Centos7.*, Node, Git
代碼庫平臺: Gitee / Github
Tips: 不一樣的操做環境能夠進行不一樣的配置, 均可以實現
複製代碼
1.1 進入到代碼庫配置webhook界面git
這裏以github爲例github
登陸github -> 進入到repository中 -> 找到設置 -> 進入webhookweb
這是已經配置好的webhookjson
點擊新增webhookbash
參考web-hook服務器
server.js
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平臺的說明(中文的, 參數差很少) Gitee
./sh/*.sh
#!/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 持續集成完畢 ------"
複製代碼
自動部署效果圖: