作为一个前端,买了腾讯云服务器后,一直想尝试项目自动化打包部署,奈何jenkins体量太大,穷人买的低配服务器还玩不起来,还有gitHub的webhook,于是自己摸索用node.js结合webhook跑通了自动部署的流程。
前期准备:一个服务器(自己搭好node环境, 安装好git), 一个托管在github、部署在服务器上的前端项目。
- 在服务器上创建一个服务(我用node.js),用于监听gitHub的webhook触发的post请求,
请求所带的数据大概如下:
由此可区分出触发的事件(仅识别push触发)和分支(仅对master分支做了识别并自动部署),之后执行部署脚本。
服务代码deploy.js如下:
var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/', secret: '1qazxsw2' })
// 上面的 path 即是github中填写的url的path部分
// 上面的 secret 保持和 GitHub 后台设置的一致
function run_cmd(cmd, args, callback) {
var spawn = require('child_process').spawn; var child = spawn(cmd, args);
var resp = "";
child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
child.stdout.on('end', function() { callback (resp) });
}
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)
// listen(7777)指监听7777端口,可以根据实际情况改成你自己的
handler.on('error', function (err) {
console.error('Error:', err.message)
})// push事件触发
handler.on('push', function (event) {
var name=event.payload.repository.name;
console.log('Received a push event for %s to %s', event.payload.repository.name, event.payload.ref);
// 判断master分支变动时执行,可根据payload.ref区分分支
if (event.payload.ref === 'refs/heads/master') {
run_cmd('sh', ['./deploy.sh',name], function(text){ console.log(text) });
}
})
//这里为了实现不同仓库的自动部署,传了仓库名给shell脚本
handler.on('issues', function (event) {
console.log('Received an issue event for % action=%s: #%d %s', event.payload.repository.name, event.payload.action, event.payload.issue.number, event.payload.issue.title)
})
部署脚本所做的工作:服务器拉取并更新代码库(服务器要配置好git,生成公钥,并在gihub项目上添加公钥),打包生成dist,移动到对应的目录替换发版文件。
部署脚本代码deploy.sh如下
#!/bin/bash
WEB_NAME="$1"# 服务器上的项目代码库路径
PROJECT_PATH="/root/project/${WEB_NAME}/"
# 项目发布的地址,我用的nginx的静态目录DEPLOY_PATH="/usr/share/nginx/html/${WEB_NAME}/"
cd $PROJECT_PATH
MD5=`md5sum package.json | cut -d' ' -f1`
rm -rf dist
git pull
NEW_MD5=`md5sum package.json | cut -d' ' -f1`
# 利用前后package.json文件MD5值是否变化来决定是否重新npm install
if [ $MD5 == $NEW_MD5 ]; then
echo '未检测到依赖项改变'else
echo "change install"
npm installfi
npm run build
if [[ ! -d "dist" ]]; then
echo "build error" exit 1fi
rm -rf $DEPLOY_PATH*
cp -rf dist/* $DEPLOY_PATH
echo "build success $WEB_NAME"
可以用pm2管理此服务,此外,我根据package.json文件MD5值是否变化来选择是否重新安装依赖 npm install。
在github项目配置url和secert
测试,修改项目代码,提交、push。查看是否触发,gitHub面板会有触发记录,redeliver按钮也可以方便调试,不用每次都自己push触发。
如此实现了前端自动部署项目的流程,但是实际生产中,还是jenkin等有界面的ci系统更为可靠。