123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- 'use strict';
- // eslint-disable-next-line camelcase
- var child_process = require('child_process');
- var format = require('util').format;
- var path = require('path');
- var series = require('run-series');
- var tv4 = require('tv4');
- var schema = {
- type: 'object',
- properties: {
- user: { type: 'string', minLength: 1 },
- host: { type: ['string', 'array'] },
- repo: { type: 'string' },
- path: { type: 'string' },
- ref: { type: 'string' },
- fetch: { type: 'string' },
- },
- required: ['host', 'repo', 'path', 'ref'],
- };
- /**
- * Spawn a modified version of visionmedia/deploy
- * @private
- * @param {object} config config to be piped to deploy
- * @param {array} args custom deploy command-line arguments
- * @param {DeployCallback} cb done callback
- */
- function spawn(config, args, cb) {
- var cmd = format('echo \'%j\' | "%s"', config, require.resolve('./deploy'));
- args = args || [];
- if (args.length > 0) {
- var cmdArgs = args.map(function (arg) {
- return format('"%s"', arg);
- }).join(' ');
- cmd = [cmd, cmdArgs].join(' ');
- }
- var proc = child_process.spawn('sh', ['-c', cmd], { stdio: 'inherit' });
- var error;
- proc.on('error', function (err) {
- error = err;
- });
- proc.on('close', function (code) {
- if (code === 0) return cb(null, args);
- error = error || new Error(format('Deploy failed with exit code: %s', code));
- error.code = code;
- return cb(error);
- });
- }
- function clone(obj) {
- return JSON.parse(JSON.stringify(obj));
- }
- function castArray(arg) {
- return Array.isArray(arg) ? arg : [arg];
- }
- /**
- * Deploy to a single environment
- * @param {object} deployConfig object containing deploy configs for all environments
- * @param {string} env the name of the environment to deploy to
- * @param {array} args custom deploy command-line arguments
- * @param {DeployCallback} cb done callback
- * @returns {boolean} return value is always `false`
- */
- function deployForEnv(deployConfig, env, args, cb) {
- if (!deployConfig[env]) {
- return cb(new Error(format('%s not defined in deploy section', env)));
- }
- var envConfig = clone(deployConfig[env]);
- if (envConfig.ssh_options) {
- envConfig.ssh_options = castArray(envConfig.ssh_options).map(function (option) {
- return format('-o %s', option);
- }).join(' ');
- }
- var result = tv4.validateResult(envConfig, schema);
- if (!result.valid) {
- return cb(result.error);
- }
- if (process.env.NODE_ENV !== 'test') {
- console.log('--> Deploying to %s environment', env);
- }
- if (process.platform !== 'win32') {
- envConfig.path = path.resolve(envConfig.path);
- }
- var hosts = castArray(envConfig.host);
- var jobs = hosts.map(function (host) {
- return function job(done) {
- if (process.env.NODE_ENV !== 'test') {
- console.log('--> on host %s', host.host ? host.host : host);
- }
- var config = clone(envConfig);
- config.host = host;
- config['post-deploy'] = prependEnv(config['post-deploy'], config.env);
- spawn(config, args, done);
- };
- });
- series(jobs, function (err, result) {
- result = Array.isArray(envConfig.host) ? result : result[0];
- cb(err, result);
- });
- return false;
- }
- function envToString(env) {
- env = env || {};
- return Object.keys(env).map(function (name) {
- return format('%s=%s', name.toUpperCase(), env[name]);
- }).join(' ');
- }
- /**
- * Prepend command with environment variables
- * @private
- * @param {string} cmd command
- * @param {object} env object containing environment variables
- * @returns {string} concatenated shell command
- */
- function prependEnv(cmd, env) {
- const envVars = envToString(env);
- if (!envVars) return cmd;
- if (!cmd) return format('export %s', envVars);
- return format('export %s && %s', envVars, cmd);
- }
- module.exports = {
- deployForEnv: deployForEnv,
- };
- /**
- * @callback DeployCallback
- * @param {Error} error deployment error
- * @param {array} args custom command-line arguments provided to deploy
- */
|