1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
| const fs = require('fs') const path = require('path') const { NodeSSH } = require('node-ssh') const archiver = require('archiver') const inquirer = require('inquirer') const exec = require('child_process').exec const ssh = new NodeSSH() const uploadFun = require('../upload.js')
let objName = process.argv[2] let startTime = null
let config = uploadFun(objName) const verifyList = [ { type: 'input', message: '您正在更新到线上环境,请确认接口域名', name: 'objName', }, ] inquirer.prompt(verifyList).then(() => { uploadBuild() })
function uploadBuild() { startTime = new Date() console.log(`${objName}开始更新`) let buildcmd = exec(config.buildScript, (error, stdout, stderr) => { if (!error) { console.log('打包完成', stdout) app() } else { console.error('打包出现错误', stderr) process.exit(0) } }) buildcmd.stdout.on('data', (data) => { console.log(data.toString()) }) }
function app() { ssh .connect({ host: config.host, username: config.username, password: config.password, }) .then((res) => { uploadData() }) .catch((err) => { console.log(err) }) }
function uploadData() { let output = fs.createWriteStream(`${path.join(__dirname, '../')}${config.buildPath}/${config.objname}.zip`) let archive = archiver('zip', { zlib: { level: 8, }, }) archive.on('warning', function(err) { if (err.code === 'ENOENT') { console.warn('stat故障和其他非阻塞错误') } else { throw err } }) archive.on('error', function(err) { throw err }) archive.pipe(output) archive.directory(`${path.join(__dirname, '../')}${config.buildPath}/${config.buildobj}`, '/') archive.finalize() output.on('close', function() { console.log(`总共 ${(archive.pointer() / 1024 / 1024).toFixed(2)} MB,完成源代码压缩`) ssh .putFile( `${path.join(__dirname, '../')}${config.buildPath}/${config.objname}.zip`, `${config.uploadDir}/${config.objname}.zip` ) .then(() => { console.log('程序zip上传成功,判断线上是否需要备份') runcmd() }) .catch((err) => { console.log(err) }) }) }
function runcmd() { ssh .execCommand('ls', { cwd: config.uploadDir, }) .then((res) => { if (res.stdout) { let fileList = res.stdout.split('\n') if (config.objname == config.backObject) { if (fileList.includes(config.objname)) { console.log('当前更新为线上正常环境,开始进行备份') backupData() } else { console.log('当前更新为线上正常环境,并且是第一次,将跳过备份') cmdunzip() } } else { console.log('当前为测试环境,无需备份,直接解压上传压缩包') cmdunzip() } } else if (res.stderr) { console.log('查询指定目录失败') } else { console.log('ssh链接发生了错误') } }) }
function backupData() { ssh .execCommand(`mv ${config.objname} backup/${config.objname}_backup${new Date().getTime()}`, { cwd: config.uploadDir, }) .then((res) => { if (res.stderr) { console.log('备份发生错误', res.stderr) } else { console.log('完成备份,解压最新代码') cmdunzip() } }) .catch((err) => { console.log('备份发生未知链接错误', err) }) }
function cmdunzip() { ssh .execCommand( `rm -rf ${config.objname} && unzip -o -d ${config.uploadDir}/${config.objname} ${config.objname}.zip && rm -f ${config.objname}.zip`, { cwd: config.uploadDir, } ) .then(() => { console.log(`项目包完成解压,${config.objname}项目部署成功了!`) console.log(`项目更新时长${(new Date().getTime() - startTime.getTime()) / 1000}s`) return deletelocalFile().then(() => { console.log('本地缓存zip清除完毕') }) }) .then(() => { ssh .execCommand(`rm -rf ${config.objname}/static/.DS_Store`, { cwd: config.uploadDir, }) .then(() => { console.log('线上项目.DS_Store删除完成') ssh.dispose() process.exit(0) }) .catch((err) => { console.log(err) }) })
.catch((err) => { console.log('解压出现错误', err) }) }
function deletelocalFile() { return new Promise((resolve, reject) => { fs.unlink(`${path.join(__dirname, '../')}${config.buildPath}/${config.objname}.zip`, (err) => { if (err) { reject(err) throw err } else { resolve() } }) }) }
|