From 6f59f1dfc6bc62e5395162edce94d74d9424849e Mon Sep 17 00:00:00 2001 From: "luk.lu" Date: Tue, 8 Jan 2019 15:43:24 +0800 Subject: [PATCH] =?UTF-8?q?[deploy.js,=20ConfigBasic.js]=20=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E9=83=A8=E7=BD=B2=E6=9C=BA=E5=88=B6=EF=BC=8C=E6=8A=8A?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=8F=82=E6=95=B0=E5=AD=98=E6=94=BE=E5=9C=A8?= =?UTF-8?q?=20ConfigBasic.js=20=E9=87=8C=E3=80=82=20[package.json]=20?= =?UTF-8?q?=E8=A1=A5=E5=85=85=20cross-env=20=E4=BB=A5=E6=94=AF=E6=8C=81=20?= =?UTF-8?q?npm=20run=20daemon=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ConfigBasic.js | 10 ++++++++ deploy.js | 65 ++++++++++++++++++++++++++++++++++---------------- package.json | 4 +++- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/ConfigBasic.js b/ConfigBasic.js index 1d9a922..5b2606a 100644 --- a/ConfigBasic.js +++ b/ConfigBasic.js @@ -6,4 +6,14 @@ module.exports={ // sslKey: '/etc/letsencrypt/live/bittic.org/privkey.pem', // ssl key file, // sslCert: '/etc/letsencrypt/live/bittic.org/cert.pem', // ssl cert file, // sslCA: '../SSL/ca_bundle.crt', // ssl ca file, + + deploy:{ + host:'', // 待部署到的主机 + port:'22', // 带部署到的主机的 SSH 端口 + root:'/home/tic/node.console.web', // 待部署到的目录路径 + dist:'dist', // 待部署到的文件夹 + user:'tic', // 登录用户名 + password:'', // 登录用户密码 + key:`${process.env.HOME}/.ssh/id_rsa`, // 登录用户私钥文件 + }, } \ No newline at end of file diff --git a/deploy.js b/deploy.js index f3b04b6..341af93 100644 --- a/deploy.js +++ b/deploy.js @@ -1,31 +1,55 @@ const fs = require('fs') const path = require('path') const ssh = new (require('node-ssh'))() + +/********************* 读取命令行以及配置文件里的参数 **********************/ const commander = require('commander') +const deepmerge = require('deepmerge') + +var Config={} + +// 读取配置文件 +try { + if (fs.existsSync('./ConfigBasic.js')) { + Config=require('./ConfigBasic.js') + console.info('ConfigBasic loaded') + } + if (fs.existsSync('./ConfigCustom.js')) { // 如果存在,覆盖掉 ConfigBasic 里的默认参数 + Config=deepmerge(Config, require('./ConfigCustom.js')) // 注意,objectMerge后,产生了一个新的对象,而不是在原来的Config里添加 + console.info('ConfigCustom loaded') + } + if (fs.existsSync('./ConfigSecret.js')) { // 如果存在,覆盖掉 ConfigBasic 和 ConfigCustom 里的参数 + Config=deepmerge(Config, require('./ConfigSecret.js')) + console.info('ConfigSecret loaded') + } +}catch(err){ + console.error('Loading config files failed: '+err.message) +} commander .version('1.0', '-v, --version') // 默认是 -V。如果要 -v,就要加 '-v --version' -.option('-H, --host ', 'domain name or ip address of the target server') -.option('-P, --port ', 'ssh port number of the target server') -.option('-r, --root ', 'root directory to deploy on the target server') -.option('-d, --dist ', 'dist folder to deploy on the target server') -.option('-u, --user ', 'user id to login the target server') -.option('-k, --key ', 'user key file to login the target server') -.option('-p, --password ', 'user password to login the target server. You may have to enclose the password in ""') +.option('-H, --host ', `Host IP or domain name of the target server. Default to ${Config.deploy.host}`) +.option('-P, --port ', `Ssh port number of the target server. Default to ${Config.deploy.port}`) +.option('-r, --root ', `Path to deploy on the target server. Default to ${Config.deploy.root}`) +.option('-d, --dist ', `Folder to deploy on the target server. Default to ${Config.deploy.dist}`) +.option('-u, --user ', `User id to login the target server. Default to ${Config.deploy.user}`) +.option('-k, --key ', `User private key file to login the target server. Default to ${Config.deploy.key}`) +.option('-p, --password ', `User password to login the target server. You may have to enclose it in "". Default to ${Config.deploy.password}`) .parse(process.argv) -const root=commander.root // 本地的项目目录。似乎该目录必须已经存在于服务器上 -const dist=commander.dist||'dist' // 新系统将发布在这个目录里。建议为dist,和npm run build产生的目录一致,这样既可以远程自动部署,也可以直接登录服务器手动部署。 +const root=commander.root||Config.deploy.root // 本地的项目目录。似乎该目录必须已经存在于服务器上 console.log(` root = ${root} `) +const dist=commander.dist||Config.deploy.dist||'dist' // 新系统将发布在这个目录里。建议为dist,和npm run build产生的目录一致,这样既可以远程自动部署,也可以直接登录服务器手动部署。 console.log(` dist = ${dist} `) +const privateKeyFile=commander.key||Config.deploy.key||`${process.env.HOME}/.ssh/id_rsa` +console.log(` privateKeyFile = ${privateKeyFile}`) -const privateKeyFile=commander.key||`${process.env.HOME}/.ssh/id_rsa` const connection = { - host: commander.host, - port: commander.port||22, - username: commander.user||'tic', + host: commander.host||Config.deploy.host, + port: commander.port||Config.deploy.port||22, + username: commander.user||Config.deploy.user, privateKey: fs.existsSync(privateKeyFile)?privateKeyFile:undefined, - password: commander.password, + password: commander.password||Config.deploy.password, tryKeyboard: true, onKeyboardInteractive: (name, instructions, instructionsLang, prompts, finish) => { // 不起作用 if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) { @@ -33,8 +57,9 @@ const connection = { } }, } -console.log(connection) +console.log(` connection = ${JSON.stringify(connection)}`) +/************************ 连接到待部署的主机,拷贝文件到指定路径 ***************/ function subDirs(path) { const dirs = [path] if (fs.statSync(path).isFile()) { @@ -57,13 +82,13 @@ const necessaryPath = (path) => { } ssh.connect(connection).then(async () => { - console.log(`[ ${root} > mv ${dist} ${dist}-backup-${new Date().toISOString()} ... ]`) + console.log(`[ mv ${dist} ${dist}-backup-${new Date().toISOString()} ... ]`) await ssh.execCommand(`mv ${dist} ${dist}-backup-${new Date().toISOString()}`, { cwd:root }) - console.log(`[ ${root} > mkdir ${dist} ... ]`) + console.log(`[ mkdir ${dist} ... ]`) await ssh.execCommand(`mkdir ${dist}`, { cwd:root }) const toCreate = necessaryPath('./dist') for (const name of toCreate) { - console.log(`[ ${root} > mkdir ${dist}/${name.join('/')} ... ]`) + console.log(`[ mkdir ${dist}/${name.join('/')} ... ]`) await ssh.execCommand(`mkdir ${dist}/${name.join('/')}`, { cwd:root }) } @@ -77,13 +102,13 @@ ssh.connect(connection).then(async () => { return !baseName.endsWith('.map'); }, tick: (localPath, remotePath, error) => { - console.log(`"${localPath}" ===> "${remotePath}" ... ${error || 'succeeded!'}`) + console.log(`Uploading "${localPath}" ===> "${remotePath}" ${error || 'succeeded!'}`) err = error }, }) ssh.dispose() if (err) { - console.log('[ Upload failed! ]') + console.log('[ Uploaded with error! ]') process.exit(1) } else { console.log('[ Uploaded successfully! ]') diff --git a/package.json b/package.json index 2c93cb7..390bb5e 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "dev": "vue-cli-service serve", "dist": "vue-cli-service build", - "deploy": "node ./deploy.js -r '/home/tic/node.console.web' -u tic", + "deploy": "node ./deploy.js", + "daemon": "cross-env NODE_ENV=production supervisor -i data.log,node_modules,dist server.js", "lint": "vue-cli-service lint", "test:unit": "vue-cli-service test:unit" }, @@ -42,6 +43,7 @@ "babel-core": "7.0.0-bridge.0", "babel-jest": "^23.0.1", "babel-plugin-transform-imports": "^1.5.1", + "cross-env": "^5.1.3", "node-sass": "^4.9.0", "node-ssh": "^5.1.2", "sass-loader": "^7.0.1",