使用Nodejs设计自动化部署工具

作者:admin / 时间:8个月前 (02/26) / 分类:后端测试 / 阅读:1231 / 评论:0

使用Nodejs设计自动化部署工具

兔子人开源 2017-11-14 10:23:01

以下内容可能会造成其它语言用户的不适,敬请读者注意。

这是一个用于Nodejs项目的热部署实例,其它语言用户也可以看看,因为文中会有其它语言用到的东西。

导包

//全局命令行

require('shelljs/global');

//SSH工具

let Client = require('ssh2').Client;

//tar.gz压缩工具

let targz = require('tar.gz');

//文件模糊匹配工具

let glob = require('glob');

//文件操作类,fs的封装

let fs = require('fs-extra');

其它语言可能用到的东西

//执行命令行

exec('cd abc' , (code, stdout, stderr) => {

});

//以使用gradle编译项目为例

exec('gradle xxxx' , (code, stdout, stderr) => {

if (stderr) {

console.error(stderr);

} else {

//下一步

}

});

删除并重新创建临时归档文件夹

const ROOT = './compress';

const ROOT_TAR_GZ = `${ROOT}.tar.gz`;

rm('-rf', ROOT);

mkdir('-p', ROOT);

定义要规定的目标列表

//以下以我官网源码为例

//https://github.com/ChangedenCZD/www.changeden.net/tree/v3

let targetList = [

'./bin',

'./build',

'./config',

'./routes',

'./src',

'./utils',

'./views',

'./*.js',

'./package.json'

];

创建计时器

//由于过程中过多异步的嵌套,不想用计数器,所以用一个计时器去控制执行下一步

let tickerId = null;

function resetTicker () {

if (tickerId) {

clearTimeout(tickerId);

}

tickerId = null;

}

function startTicker () {

resetTicker();

tickerId = setTimeout(() => {

startToCompress();

}, 10000); //延时10s,一般2s足够了,按需调整

}

定义文件复制方法

//用于复制目标到临时归档文件夹

function startToCopyFile () {

console.log('Start to copy file');

targetList.forEach((filePath) => {

//glob.sync('./*.*')会返回所有文件夹及文件,结果为一个字符串数组

//glob.sync('./*.js')会提取出当前文件夹中的所有js后缀文件,不包括子文件夹

//glob.sync('./**/*.js')会提取出当前文件夹中的所有js后缀文件,包括子文件夹

glob.sync(filePath).forEach((file) => {

let target = `${ROOT}/${file}`;

//复制文件到目标到临时归档文件夹

fs.copy(file, target, err => {

startTicker();

if (err) {

rm('-rf', target);

console.error(err);

} else {

console.log(`${file} had move.`);

}

});

});

});

}

定义压缩方法

//将临时归档文件夹压缩为归档文件

function startToCompress () {

console.log('Start to compress');

resetTicker();

targz().compress(ROOT, ROOT_TAR_GZ)

.then(function () {

console.log(`${ROOT} had compress.`);

startToSendFilesBySSH();

rm('-rf', ROOT);

})

.catch(function (err) {

console.error(err);

rm('-rf', ROOT);

});

}

定义部署到远程服务器的方法

let connect = new Client();

function startToSendFilesBySSH () {

console.log('Start to send files by SSH');

connect.on('ready', function () {

//获取sftp客户端,用于传输文件

connect.sftp(function (err, sftp) {

if (err) throw err;

//sftp.fastPut(本地要传输的文件路径,远程服务器的文件路径,额外选项,回调)

sftp.fastPut(ROOT_TAR_GZ, `/root/${ROOT_TAR_GZ}`, {}, (err) => {

if (err) {

console.error(err);

end();

} else {

console.log(`${ROOT_TAR_GZ} had send to remote server.`);

//定义项目最终文件路径

const TARGET = '/www.changeden.net';

//定义要在远程服务器执行的命令,如重启Tomcat等等

//解压 tar -xvf xxx.tar.gz

//覆盖旧项目 cp -f xxx/* /www.changeden.net

//CentOs中的 cp -f 用于忽略确认覆盖提示,Ubuntu 用 cp -rf

//重新编译运行 npm install && npm up -save && pm2 restart all

const shellText = `

cd /root && tar -xvf ${ROOT_TAR_GZ}

rm -f ${ROOT_TAR_GZ} && \cp -f ${ROOT}/* ${TARGET}

rm -rf ${ROOT}

cd ${TARGET} && npm install && npm up -save && npm run fixAndMove

pm2 restart official

exit

`;

connect.shell((err, stream) => {

if (err) throw err;

stream.on('close', () => {

console.log('Finish.');

end();

}).on('data', (data) => {

console.log('Progress: ' + data);

}).stderr.on('data', (data) => {

console.log('Error: ' + data);

});

stream.end(shellText);

});

}

});

});

});

//创建SSH连接

connect.connect({

host: '远程服务器公网IP',

port: 22,

username: '远程服务器用户名',

password: '远程服务器登录密码',

readyTimeout: 60000

});

}

//关闭SSH连接

function end () {

connect.end();

}


没有评论,留下你的印记,证明你来过。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。