diff --git a/docs/cheatsheet/web/index.html b/docs/cheatsheet/web/index.html index 086c6c2c..d2634912 100644 --- a/docs/cheatsheet/web/index.html +++ b/docs/cheatsheet/web/index.html @@ -485,6 +485,9 @@

Deploy

Deploy whole project

s deploy
+

Deploy whole project (with instance creation)

+
s deploy --create-instance <new instance name>
+

Deploy whole project

s deploy <socket name>
diff --git a/docs/docs/cli-reference/commands.md b/docs/docs/cli-reference/commands.md index 494b1bfb..754f9d61 100644 --- a/docs/docs/cli-reference/commands.md +++ b/docs/docs/cli-reference/commands.md @@ -63,6 +63,11 @@ syncano-cli deploy ``` It compiles and deploys all global configuration and Syncano Sockets in your project. From now on, you can call every endpoint from every Socket in your project. Dependencies will be also deployed in that process. +I you don't have instance for that project yet, you can create it during `deploy` process: +```sh +syncano-cli deploy --create-instance +``` + #### Deploy single Socket To deploy single Socket provide socket name as an additional argument: diff --git a/packages/cli/src/cli.js b/packages/cli/src/cli.js index 8a60029a..ef6c8103 100755 --- a/packages/cli/src/cli.js +++ b/packages/cli/src/cli.js @@ -98,11 +98,12 @@ const setup = async () => { .description('Synchronize your project to Syncano') .option('--hot', 'Enable Hot deploy') .option('-b, --bail', 'Bail after first deploy failure') + .option('-i, --create-instance ', 'Create instance if it doesn\'t exist') .option('-t, --trace', 'Turn on showing traces') .action(async (...options) => { trackAndDebug(options) session.isAuthenticated() - session.hasProject() + session.hasProjectPath() await session.checkConnection() echo() new commands.SocketDeploy(context).run(options) diff --git a/packages/cli/src/commands/helpers/create-instance.js b/packages/cli/src/commands/helpers/create-instance.js new file mode 100644 index 00000000..c1509056 --- /dev/null +++ b/packages/cli/src/commands/helpers/create-instance.js @@ -0,0 +1,35 @@ +import format from 'chalk' + +import logger from '../../utils/debug' +import { echo, echon, error } from '../../utils/print-tools' + +const { debug } = logger('cmd-helpers-socket') + +export const createInstance = async (instanceName, session) => { + let newInstance = null + try { + debug('Creating Instance') + echo() + echon(4)('Creating Syncano Instance... ') + newInstance = await session.createInstance(instanceName) + } catch (err) { + echo() + echo() + if (err.message === 'No such API Key.') { + error(4)('It looks like your account key is invalid.') + echo(4)(`Try ${format.cyan('syncano-cli logout')} and ${format.cyan('syncano-cli login')} again.`) + } else if (err.message === 'name: This field must be unique.') { + error(4)('Instance already exist!') + echo(4)('Try another instace name.') + } else { + error(4)(err.message || 'Error while creating instance. Try again!') + } + echo() + process.exit(1) + } finally { + echo(`${format.green('Done')}`) + echo(4)(`Syncano Instance ${format.cyan(newInstance.name)} has been created!`) + echo() + } + return newInstance +} diff --git a/packages/cli/src/commands/init.js b/packages/cli/src/commands/init.js index aec9fb13..dd184e98 100644 --- a/packages/cli/src/commands/init.js +++ b/packages/cli/src/commands/init.js @@ -2,7 +2,8 @@ import format from 'chalk' import inquirer from 'inquirer' import logger from '../utils/debug' -import { p, echo, echon, error } from '../utils/print-tools' +import { createInstance } from './helpers/create-instance' +import { p, echo } from '../utils/print-tools' import Login from './login' const { debug } = logger('cmd-init') @@ -58,28 +59,7 @@ class InitCmd { } if (!project && !instance) { - let newInstance = null - try { - debug('Creating Instance') - echo() - echon(4)('Creating Syncano Instance... ') - newInstance = await this.session.createInstance() - } catch (err) { - echo() - echo() - if (err.message === 'No such API Key.') { - error(4)('It looks like your account key is invalid.') - echo(4)(`Try ${format.cyan('syncano-cli logout')} and ${format.cyan('syncano-cli login')} again.`) - } else { - error(4)(err.message || 'Error while creating instance. Try again!') - } - echo() - process.exit() - } finally { - echo(`${format.green('Done')}`) - echo(4)(`Syncano Instance ${format.cyan(newInstance.name)} has been created!`) - echo() - } + const newInstance = createInstance() this.init.addConfigFiles({ instance: newInstance.name }) this.init.createFilesAndFolders() diff --git a/packages/cli/src/commands/socket-deploy.js b/packages/cli/src/commands/socket-deploy.js index b516f3ca..4bd799e9 100644 --- a/packages/cli/src/commands/socket-deploy.js +++ b/packages/cli/src/commands/socket-deploy.js @@ -4,6 +4,7 @@ import Promise from 'bluebird' import logger from '../utils/debug' import { SimpleSpinner } from './helpers/spinner' +import { createInstance } from './helpers/create-instance' import { askQuestions } from './helpers/socket' import { p, error, echo } from '../utils/print-tools' import { currentTime, Timer } from '../utils/date-utils' @@ -28,6 +29,14 @@ export default class SocketDeployCmd { // echo(2)(`♻️ ${format.grey(' Deploying...')}`); + // Create Instance if --create-instance provided + if (cmd.createInstance) { + await createInstance(cmd.createInstance, this.session) + } else { + // If not, we have to check if we have a project attached to any instance + this.session.hasProject() + } + if (socketName) { debug(`Deploying Socket: ${socketName}`) const msg = p(2)(`${format.magenta('getting sockets:')} ${currentTime()}`) diff --git a/packages/cli/tests/e2e/deploy.test-e2e.js b/packages/cli/tests/e2e/deploy.test-e2e.js index 7ecacde5..832c25db 100644 --- a/packages/cli/tests/e2e/deploy.test-e2e.js +++ b/packages/cli/tests/e2e/deploy.test-e2e.js @@ -1,10 +1,12 @@ /* global describe it before after */ +import fs from 'fs-extra' import path from 'path' import { nixt, testsLocation, deleteInstance, createProject, + createInstance, uniqueInstance, getRandomString } from '@syncano/test-tools' @@ -64,4 +66,47 @@ describe('[E2E] CLI Deploy', function () { .stdout(/Hello TEST CLI/) .end(done) }) + + it('can deploy with instance creation', function (done) { + let testInstance = uniqueInstance() + + const projectTestTemplate = path.join(__dirname, './assets/project/empty/') + const moveTestProject = (template) => { + fs.copySync(template, path.join(testsLocation, testInstance)) + } + + const testNixt = () => nixt() + .env('SYNCANO_AUTH_KEY', process.env.E2E_CLI_ACCOUNT_KEY) + .cwd(path.join(testsLocation, testInstance)) + + testNixt() + .before(() => moveTestProject(projectTestTemplate)) + .after(() => deleteInstance(testInstance)) + .run(`${cliLocation} deploy --create-instance ${testInstance}`) + .stdout(/project synced:/) + .end(done) + }) + + it('can\'t deploy with instance creation if instance already exist', function (done) { + let testInstance = uniqueInstance() + + const projectTestTemplate = path.join(__dirname, './assets/project/empty/') + const moveTestProject = (template) => { + fs.copySync(template, path.join(testsLocation, testInstance)) + } + + const testNixt = () => nixt() + .env('SYNCANO_AUTH_KEY', process.env.E2E_CLI_ACCOUNT_KEY) + .cwd(path.join(testsLocation, testInstance)) + + testNixt() + .before(async () => { + await moveTestProject(projectTestTemplate) + await createInstance(testInstance) + }) + .after(() => deleteInstance(testInstance)) + .run(`${cliLocation} deploy --create-instance ${testInstance}`) + .stdout(/Instance already exist!/) + .end(done) + }) }) diff --git a/packages/test-tools/src/index.js b/packages/test-tools/src/index.js index 43c85ee1..f7d7907f 100644 --- a/packages/test-tools/src/index.js +++ b/packages/test-tools/src/index.js @@ -96,7 +96,9 @@ const createInstance = (instanceName) => connection.instance const deleteInstance = (instanceName) => connection.instance .delete(instanceName) - .catch((error) => process.stderr.write(JSON.stringify(error.message, null, ''))) + .catch((error) => process.stderr.write( + JSON.stringify(`deleteInstance: ${error.message}`, null, '') + )) const deleteEachInstance = (instances) => { const list = []