This commit is contained in:
陆柯 2022-07-21 09:08:14 +08:00
parent 816f2e3e82
commit 4abcbf62a2
3 changed files with 130 additions and 149 deletions

View File

@ -1,17 +1,17 @@
## 参数
* -t, --type: web(默认) 或 git
* 如果是 git
* -r, --repo: 远程仓库,例如 'https://github.com/ORG/ORG.github.io'
* -b, --branch: 分支,默认为 main
* -n, --gitname
* -e, --gitemail
* 如果是 web
* -H, --host: 远程主机
* -P, --port: 远程端口,默认为 22
* -D, --dir: 远程路径,例如 /home/USER/FOLDER
* -d, --dist: 远程文件夹,例如 www。默认为 dist。
* -l, --local: 本地路径,例如 ../../project/public。默认为 ./dist
* -u, --user: 用户名
* -p, --password: 密码
* -k, --key: 密钥文件
- -t, --type: web(默认) 或 git
- 如果是 git
- -r, --repo: 远程仓库,例如 'https://github.com/ORG/ORG.github.io'
- -b, --branch: 分支,默认为 main
- -n, --gitname
- -e, --gitemail
- 如果是 web
- -H, --host: 远程主机
- -P, --port: 远程端口,默认为 22
- -D, --dir: 远程路径,例如 /home/USER/FOLDER
- -d, --dist: 远程文件夹,例如 www。默认为 dist。
- -l, --local: 本地路径,例如 ../../project/public。默认为 ./dist
- -u, --user: 用户名
- -p, --password: 密码
- -k, --privateKey: 密钥文件

244
deploy.js
View File

@ -2,137 +2,119 @@ const fs = require('fs')
const path = require('path')
/** ******************* 读取命令行以及配置文件里的参数 ******************** **/
const commander = require('commander')
const deepmerge = require('deepmerge')
// 默认参数
const wo = (global.wo = {
envar: {
deploy: {
fromPath: './webroot',
gotoTarget: 'github',
envar: require('basend-envar').merge_envar({
rawEnvar: {
Commander_Option_List: [
// 命令行里可以接受的参数。将传给 commander。每个参数的定义格式是 [参数名,参数键,描述],后两者用于传给 commander取值后覆盖掉同名变量。
[
'fromPath',
'-f, --fromPath <fromPath>',
'local distribution path to copy from.'
],
[
'gotoTarget',
'-g, --gotoTarget <gotoTarget>',
'connection section name.'
],
vultr: {
targetType: 'ssh',
host: undefined,
port: 22,
targetPath: undefined,
targetDir: 'webroot',
user: undefined,
password: undefined,
key: `${process.env.HOME}/.ssh/id_rsa`
},
github: {
targetType: 'git',
repo: undefined,
branch: 'main',
gitname: undefined,
gitemail: undefined,
user: undefined,
password: undefined,
key: `${process.env.HOME}/.ssh/id_rsa`
[
'targetType',
'-t, --targetType <targetType>',
'target type, git or ssh.'
],
[
'host',
'-H, --host <host>',
'Host IP or domain name of the target server.'
],
['port', '-P, --port <port>', 'Ssh port number of the target server.'],
[
'targetPath',
'-d, --targetPath <targetPath>',
'Destination path to deploy on the target.'
],
[
'targetDir',
'-D, --targetDir <targetDir>',
'Destination folder to deploy on the target.'
],
['repo', '-r, --repo <repo>', 'git repo address.'],
['branch', '-b, --branch <branch>', 'git repo branch.'],
['gitname', '-n, --gitname <gitname>', 'git user name.'],
['gitemail', '-m, --gitemail <gitemail>', 'git user email.'],
['user', '-u, --user <user>', 'User id to login the target server.'],
[
'privateKey',
'-k, --privateKey <privateKey>',
'User private key file to login the target server.'
],
[
'password',
'-p, --password <password>',
'User password to login the target server. You may have to enclose it in "".'
]
],
// 最基础的必须的默认配置,如果用户什么也没有提供
deploy: {
fromPath: './webroot',
gotoTarget: 'github',
server: {
targetType: 'ssh',
host: undefined,
port: 22,
targetPath: undefined, // 目标服务器上的目录。似乎该目录必须已经存在于服务器上
targetDir: 'webroot', // 新系统将发布在这个文件夹里。建议为dist和npm run build产生的目录一致这样既可以远程自动部署也可以直接登录服务器手动部署。
user: undefined,
password: undefined,
privateKey: `${process.env.HOME}/.ssh/id_rsa`
},
github: {
targetType: 'git',
repo: undefined,
branch: 'main',
gitname: undefined,
gitemail: undefined,
user: undefined,
password: undefined,
privateKey: `${process.env.HOME}/.ssh/id_rsa`
}
}
}
}
},
envarFiles: ['./envar-deploy.js', './envar-deploy-secret.js']
})
})
// 读取配置文件
try {
let configFile
const envarDeploy = wo.envar.deploy
delete wo.envar.deploy
// 用 commander 采集到的配置 替换 文件中采集到的配置
envarDeploy.fromPath = wo.envar.fromPath || envarDeploy.fromPath
envarDeploy.gotoTarget = wo.envar.gotoTarget || envarDeploy.gotoTarget
// 使用用户指定的连接
const connection = envarDeploy[envarDeploy.gotoTarget]
Object.assign(connection, wo.envar) // 用 commander 采集到的配置 替换 文件中采集到的配置
connection.tryKeyboard = true
connection.onKeyboardInteractive = (
name,
instructions,
lang,
prompts,
finish
) => {
// 不起作用
if (
fs.existsSync(
(configFile = path.join(process.cwd(), 'envar-base-deploy.js'))
)
prompts.length > 0 &&
prompts[0].prompt.toLowerCase().includes('password')
) {
wo.envar = deepmerge(wo.envar, require(configFile))
console.info(`- ${configFile} loaded`)
finish([password])
}
if (
fs.existsSync(
(configFile = path.join(process.cwd(), 'envar-base-secret.js'))
)
) {
wo.envar = deepmerge(wo.envar, require(configFile))
console.info(`- ${configFile} loaded`)
}
} catch (err) {
console.error('- Loading config files failed: ' + err.message)
}
// 读取命令行参数
commander
.version('1.0', '-v, --version') // 默认是 -V。如果要 -v就要加 '-v --version'
.option('-f, --fromPath <fromPath>', `local distribution path to copy from.`)
.option('-g, --gotoTarget <gotoTarget>', `connection section in config.`)
.option('-t, --targetType <targetType>', `target type, git or ssh.`)
.option('-H, --host <host>', `Host IP or domain name of the target server.`)
.option('-P, --port <port>', `Ssh port number of the target server.`)
.option(
'-d, --targetPath <targetPath>',
`Destination path to deploy on the target.`
)
.option(
'-D, --targetDir <targetDir>',
`Destination folder to deploy on the target.`
)
.option('-r, --repo <repo>', `git repo address.`)
.option('-b, --branch <branch>', `git repo branch.`)
.option('-n, --gitname <gitname>', `git user name.`)
.option('-m, --gitemail <gitemail>', `git user email.`)
.option('-u, --user <user>', `User id to login the target server.`)
.option(
'-k, --key <key>',
`User private key file to login the target server.`
)
.option(
'-p, --password <password>',
`User password to login the target server. You may have to enclose it in "".`
)
.parse(process.argv)
wo.envar.deploy.fromPath = commander.fromPath || wo.envar.deploy.fromPath
wo.envar.deploy.connection =
wo.envar.deploy[commander.gotoTarget || wo.envar.deploy.gotoTarget] // 使用用户指定的连接
// 可以用命令行参数覆盖掉配置文件
const connection = {
targetType: commander.targetType || wo.envar.deploy.connection.targetType,
// for ssh
host: commander.host || wo.envar.deploy.connection.host,
port: commander.port || wo.envar.deploy.connection.port,
targetPath: commander.targetPath || wo.envar.deploy.connection.targetPath, // 目标服务器上的目录。似乎该目录必须已经存在于服务器上
targetDir: commander.targetDir || wo.envar.deploy.connection.targetDir, // 新系统将发布在这个文件夹里。建议为dist和npm run build产生的目录一致这样既可以远程自动部署也可以直接登录服务器手动部署。
// for git
repo: commander.repo || wo.envar.deploy.connection.repo,
branch: commander.branch || wo.envar.deploy.connection.branch,
gitname: commander.gitname || wo.envar.deploy.connection.gitname,
gitemail: commander.gitemail || wo.envar.deploy.connection.gitemail,
// common
username: commander.user || wo.envar.deploy.connection.user,
privateKey: fs.existsSync(commander.key || wo.envar.deploy.connection.key)
? commander.key || wo.envar.deploy.connection.key
: undefined,
password: commander.password || wo.envar.deploy.connection.password,
tryKeyboard: true,
onKeyboardInteractive: (name, instructions, lang, prompts, finish) => {
// 不起作用
if (
prompts.length > 0 &&
prompts[0].prompt.toLowerCase().includes('password')
) {
finish([password])
}
},
url: wo.envar.deploy.connection.url
}
console.log(
` deploy from ${wo.envar.deploy.fromPath} to ${JSON.stringify(connection)}`
`*** Deploy from ${envarDeploy.fromPath} to ${JSON.stringify(connection)} ***`
)
if (connection.targetType === 'ssh') {
@ -184,7 +166,7 @@ function deployToSsh (connection) {
await ssh.execCommand(`mkdir ${connection.targetDir}`, {
cwd: connection.targetPath
})
const toCreate = necessaryPath(path.join('./', wo.envar.deploy.fromPath))
const toCreate = necessaryPath(path.join('./', envarDeploy.fromPath))
for (const name of toCreate) {
console.log(`[ mkdir ${connection.targetDir}/${name.join('/')} ... ]`)
await ssh.execCommand(
@ -198,7 +180,7 @@ function deployToSsh (connection) {
`[ Upload to ${connection.targetPath}/${connection.targetDir} ... ]`
)
await ssh.putDirectory(
path.join('./', wo.envar.deploy.fromPath),
path.join('./', envarDeploy.fromPath),
`${connection.targetPath}/${connection.targetDir}`,
{
concurrency: 10,
@ -219,12 +201,12 @@ function deployToSsh (connection) {
ssh.dispose()
if (err) {
console.error(
`🤷‍♀️🤷‍♀️🤷‍♀️ Failed deploy ${wo.envar.deploy.fromPath} to ${connection.targetPath}/${connection.targetDir} 🤷‍♀️🤷‍♀️🤷‍♀️`
`🤷‍♀️🤷‍♀️🤷‍♀️ Failed deploy ${envarDeploy.fromPath} to ${connection.targetPath}/${connection.targetDir} 🤷‍♀️🤷‍♀️🤷‍♀️`
)
process.exit(1)
} else {
console.info(
`😊😊😊 Successfully deployed [${wo.envar.deploy.fromPath}] to [${connection.targetPath}/${connection.targetDir}] 😊😊😊`
`😊😊😊 Successfully deployed [${envarDeploy.fromPath}] to [${connection.targetPath}/${connection.targetDir}] 😊😊😊`
)
if (connection.url) {
console.info(`😊😊😊 ${connection.url} 😊😊😊`)
@ -236,7 +218,7 @@ function deployToSsh (connection) {
console.error(err)
ssh.dispose()
console.error(
`🤷‍♀️🤷‍♀️🤷‍♀️ Failed deploy [${wo.envar.deploy.fromPath}] to [${connection.targetPath}/${connection.targetDir}] 🤷‍♀️🤷‍♀️🤷‍♀️`
`🤷‍♀️🤷‍♀️🤷‍♀️ Failed deploy [${envarDeploy.fromPath}] to [${connection.targetPath}/${connection.targetDir}] 🤷‍♀️🤷‍♀️🤷‍♀️`
)
process.exit(1)
})
@ -307,7 +289,7 @@ function deployToGit (connection) {
function exec () {
const targetDir = ''
const deployDir = pathFn.join(targetDir, '.deploy_git')
const fromDir = wo.envar.deploy.fromPath
const fromDir = envarDeploy.fromPath
let extendDirs = connection.extend_dirs
const ignoreHidden = connection.ignore_hidden
const ignorePattern = connection.ignore_pattern
@ -340,8 +322,8 @@ function deployToGit (connection) {
}
function setup () {
const userName = wo.envar.deploy.gitname || ''
const userEmail = wo.envar.deploy.gitemail || ''
const userName = connection.gitname || ''
const userEmail = connection.gitemail || ''
// Create a placeholder for the first commit
return fs
@ -375,7 +357,7 @@ function deployToGit (connection) {
})
.then(() => {
console.info(
`😊😊😊 Successfully deployed [${wo.envar.deploy.fromPath}] to [${connection.repo}#${connection.branch}] 😊😊😊`
`😊😊😊 Successfully deployed [${envarDeploy.fromPath}] to [${connection.repo}#${connection.branch}] 😊😊😊`
)
if (connection.url) {
console.info(`😊😊😊 ${connection.url} 😊😊😊`)
@ -383,7 +365,7 @@ function deployToGit (connection) {
})
.catch(err => {
console.error(
`🤷‍♀️🤷‍♀️🤷‍♀️ Failed deploy [${wo.envar.deploy.fromPath}] to [${connection.repo}#${connection.branch}] 🤷‍♀️🤷‍♀️🤷‍♀️`
`🤷‍♀️🤷‍♀️🤷‍♀️ Failed deploy [${envarDeploy.fromPath}] to [${connection.repo}#${connection.branch}] 🤷‍♀️🤷‍♀️🤷‍♀️`
)
process.exit(1)
})

View File

@ -13,10 +13,9 @@
"author": "",
"license": "ISC",
"dependencies": {
"basend-envar": "git+https://git.faronear.org/npm/basend-envar",
"bluebird": "^3.5.5",
"chalk": "^2.4.2",
"commander": "^3.0.1",
"deepmerge": "^4.0.0",
"hexo-fs": "^3.1.0",
"hexo-util": "^2.5.0",
"moment": "^2.24.0",