UNPKG

r8s-cli

Version:

A command line tool for Reaction Commerce to be used with kubernetes

344 lines (261 loc) 11.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.deploy = undefined; var _filter2 = require('lodash/filter'); var _filter3 = _interopRequireDefault(_filter2); var _omit2 = require('lodash/omit'); var _omit3 = _interopRequireDefault(_omit2); var deploy = exports.deploy = function () { var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(yargs) { var args, app, image, apps, appToDeploy, msg, values, conf, options, notInReactionDir, packageFile, configFilePath, _ref2, download, res, json, configFile, branch, _ref3, push; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _utils.Log.args(yargs.argv); args = (0, _omit3.default)(yargs.argv, ['_', '$0']); app = args.app, image = args.image; if (!(!app && !image)) { _context.next = 5; break; } return _context.abrupt('return', _utils.Log.default(helpMessage)); case 5: if (app) { _context.next = 7; break; } return _context.abrupt('return', _utils.Log.error('Error: App name required (--app myapp)')); case 7: apps = _utils.Config.get('global', 'launchdock.apps', []); appToDeploy = (0, _filter3.default)(apps, function (a) { return a.name === app; })[0]; if (!appToDeploy) { msg = 'App not found. Run \'reaction apps list\' to see your active apps'; _utils.Log.error(msg); process.exit(1); } values = {}; // convert any supplied env vars into an object if (Array.isArray(args.e)) { args.e.forEach(function (val) { var conf = val.split('='); values[conf[0]] = conf[1]; }); } else if (typeof args.e === 'string') { conf = args.e.split('='); values[conf[0]] = conf[1]; } // read in a settings file if provided if (args.settings) { values.METEOR_SETTINGS = (0, _utils.getStringFromFile)(args.settings); } // read in a Reaction registry file if provided if (args.registry) { values.REACTION_REGISTRY = (0, _utils.getStringFromFile)(args.registry); } options = { _id: appToDeploy._id }; if (Object.keys(values).length > 0) { options.env = values; } if (!(image || appToDeploy.image)) { _context.next = 22; break; } // docker pull deployment _utils.Log.warn('Prebuilt Docker image deployment is currently unavailable.'); _utils.Log.warn('Contact support for more info.'); process.exit(1); // TODO: allow deployment of prebuilt images // // options.image = image || appToDeploy.image; // // const result = await gql.fetch(` // mutation appPull($_id: ID!, $image: String! $env: JSON) { // appPull(_id: $_id, image: $image, env: $env) { // _id // name // image // defaultUrl // } // } // `, options); // // if (!!result.errors) { // result.errors.forEach((err) => { // Log.error(err.message); // }); // process.exit(1); // } // // const { defaultUrl } = result.data.appPull; // // Log.success('\nDone!\n'); // // Log.info(`Updated ${Log.magenta(app)} with image ${Log.magenta(options.image)}\n`); // Log.info('You will receive a notification email as soon as the deployment finishes.\n'); // Log.info(`App URL: ${Log.magenta(defaultUrl)}\n`); _context.next = 72; break; case 22: // git push deployment notInReactionDir = function notInReactionDir() { _utils.Log.error('\nNot in a Reaction app directory.\n'); _utils.Log.info('To create a new local project, run: ' + _utils.Log.magenta('reaction init') + '\n'); }; packageFile = void 0; try { packageFile = _fsExtra2.default.readJSONSync('./package.json'); } catch (e) { notInReactionDir(); process.exit(1); } if (packageFile.name !== 'reaction') { notInReactionDir(); process.exit(1); } // If we don't have a Reaction CI config file, // prompt the user to download it from Github // and commit it to their repo configFilePath = '.reaction/ci/config.yml'; if (!(0, _utils.isEmptyOrMissing)(configFilePath)) { _context.next = 56; break; } _utils.Log.warn('\nRequired Reaction CI configuration file not found at: ' + configFilePath + '\n'); _context.next = 31; return _inquirer2.default.prompt([{ type: 'confirm', name: 'download', message: '\nWould you like to download the latest from Github and commit it to your repo?', default: true }]); case 31: _ref2 = _context.sent; download = _ref2.download; if (!download) { _context.next = 54; break; } _context.prev = 34; _context.next = 37; return (0, _nodeFetch2.default)('https://api.github.com/repos/reactioncommerce/reaction/contents/' + configFilePath); case 37: res = _context.sent; _context.next = 40; return res.json(); case 40: json = _context.sent; configFile = new Buffer(json.content, 'base64').toString('utf8'); _fsExtra2.default.writeFileSync(_path2.default.resolve(configFilePath), configFile); _context.next = 50; break; case 45: _context.prev = 45; _context.t0 = _context['catch'](34); _utils.Log.debug(_context.t0); _utils.Log.error('Failed to create Reaction CI config file. Please contact support.'); process.exit(1); case 50: try { (0, _child_process.exec)('git add ' + configFilePath + ' && git commit -m "Add Reaction CI config file"', { stdio: 'inherit' }); } catch (err) { _utils.Log.error('\nFailed to commit new config file to your repo\n'); process.exit(1); } _utils.Log.success('\nReaction CI config file created!\n'); _context.next = 56; break; case 54: _utils.Log.error('\nReaction CI configuration is required. Please add one at: ' + configFilePath + '\n'); process.exit(1); case 56: _context.next = 58; return (0, _utils.ensureSSHKeysExist)(); case 58: _utils.Log.info('\nPushing updates to be built...\n'); (0, _utils.setGitSSHKeyEnv)(); branch = void 0; try { branch = (0, _child_process.execSync)('git rev-parse --abbrev-ref HEAD').toString().replace(/\r?\n|\r/g, ''); } catch (err) { _utils.Log.error('\nFailed to get current branch. Exiting.'); process.exit(1); } if (!(branch !== 'master')) { _context.next = 71; break; } _utils.Log.warn('You are not on the master branch. A deployment will NOT happen.'); _context.next = 66; return _inquirer2.default.prompt([{ type: 'confirm', name: 'push', message: '\nWould you like to push the branch up anyway?\n', default: false }]); case 66: _ref3 = _context.sent; push = _ref3.push; if (push) { (0, _child_process.exec)('git push ' + appToDeploy.group.namespace + '-' + app + ' ' + branch, function (err, stdout, stderr) { if (err) { _utils.Log.error('\nDeployment failed'); process.exit(1); } if (stderr.includes('Everything up-to-date')) { _utils.Log.info('\nNo committed changes to deploy.\n'); } else { _utils.Log.info('\nYour branch has been pushed, but this was not the master branch, so nothing will be deployed.\n'); } _utils.Log.success('Done!\n'); process.exit(0); }); } else { _utils.Log.error('Not pushing code. Exiting.'); process.exit(1); } _context.next = 72; break; case 71: (0, _child_process.exec)('git push ' + appToDeploy.group.namespace + '-' + app + ' ' + branch, function (err, stdout, stderr) { if (err) { _utils.Log.default(stderr); _utils.Log.error('\nDeployment failed'); process.exit(1); } if (stderr.includes('Everything up-to-date')) { _utils.Log.info('No committed changes to deploy.\n'); } else { _utils.Log.info('You will be notified as soon as your app finishes building and deploying.\n'); } _utils.Log.success('Done!\n'); process.exit(0); }); case 72: case 'end': return _context.stop(); } } }, _callee, this, [[34, 45]]); })); return function deploy(_x) { return _ref.apply(this, arguments); }; }(); var _fsExtra = require('fs-extra'); var _fsExtra2 = _interopRequireDefault(_fsExtra); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _child_process = require('child_process'); var _nodeFetch = require('node-fetch'); var _nodeFetch2 = _interopRequireDefault(_nodeFetch); var _inquirer = require('inquirer'); var _inquirer2 = _interopRequireDefault(_inquirer); var _utils = require('../utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } var helpMessage = '\nUsage:\n\n reaction deploy [options]\n\n Options:\n --app, -a The name of the app to deploy (required)\n --env, -e Set/update an environment varible before deployment\n --image, -i The Docker image to deploy\n';