From bb4e7827f2897ab78e27830f23e499475c02517a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Thu, 19 Sep 2019 15:59:29 +0200 Subject: [PATCH] feat: add cancel command --- src/cancel.js | 40 ++++++++++++++++++++++++++++++++++++++ src/cancel.test.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 42 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 src/cancel.js create mode 100644 src/cancel.test.js diff --git a/src/cancel.js b/src/cancel.js new file mode 100644 index 0000000..40fc92c --- /dev/null +++ b/src/cancel.js @@ -0,0 +1,40 @@ +import fetch from 'node-fetch' +import getEnvironment from './getEnvironment' +import config from './config' +import pkg from '../package.json' + +export class CancelError extends Error {} + +async function cancel(options) { + const { token: tokenOption, externalBuildId: externalBuildIdOption } = options + + const token = tokenOption || config.get('token') + + if (!token) { + throw new CancelError( + 'Token missing: use ARGOS_TOKEN or the --token option.', + ) + } + + let environment = {} + + if (process.env.ARGOS_CLI_TEST !== 'true') { + environment = getEnvironment(process.env) + } + + const externalBuildId = + externalBuildIdOption || + config.get('externalBuildId') || + environment.externalBuildId + + return fetch(`${config.get('endpoint')}/cancel-build`, { + headers: { + 'X-Argos-CLI-Version': pkg.version, + 'Content-Type': 'application/json', + }, + method: 'POST', + body: JSON.stringify({ token, externalBuildId }), + }) +} + +export default cancel diff --git a/src/cancel.test.js b/src/cancel.test.js new file mode 100644 index 0000000..514ace8 --- /dev/null +++ b/src/cancel.test.js @@ -0,0 +1,48 @@ +import path from 'path' +import fetch from 'node-fetch' +import cancel from './cancel' +import config from './config' +import pkg from '../package.json' + +jest.mock('node-fetch') + +describe('cancel', () => { + beforeEach(() => { + config.set('endpoint', 'http://localhost') + }) + + afterEach(() => { + config.reset('endpoint') + }) + + describe('with missing token', () => { + it('should throw', async () => { + expect.assertions(1) + + try { + await cancel({ + directory: path.join(__dirname, '../__fixtures__/screenshots'), + }) + } catch (error) { + expect(error.message).toMatch('Token missing') + } + }) + }) + + describe.only('with all good', () => { + beforeEach(() => { + fetch.mockImplementation(async () => {}) + }) + + it('should ping cancel-build api', async () => { + await cancel({ + token: 'myToken', + }) + expect(fetch.mock.calls[0][0]).toBe('http://localhost/cancel-build') + expect(fetch.mock.calls[0][1].headers).toEqual({ + 'X-Argos-CLI-Version': pkg.version, + 'Content-Type': 'application/json', + }) + }) + }) +}) diff --git a/src/index.js b/src/index.js index 27cf48d..ac4f743 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import updateNotifier from 'update-notifier' import errorReporter, { initializeErrorReporter } from './errorReporter' import pkg from '../package.json' import upload, { UploadError } from './upload' +import cancel, { CancelError } from './cancel' import { displayError, displaySuccess } from './display' updateNotifier({ pkg }).notify() @@ -19,14 +20,15 @@ if (process.env.NODE_ENV !== 'production') { const list = value => value.split(',') +program.version(pkg.version) + program - .version(pkg.version) .command('upload ') .description('Upload screenshots') + .option('-T, --token ', 'Repository token') .option('-C, --commit ', 'Git commit') .option('-B, --branch ', 'Git branch') - .option('-T, --token ', 'Repository token') - .option('--externalBuildId [string]', 'ID of the build (batch mode)') + .option('--externalBuildId [string]', 'ID of the build (batch mode only)') .option( '--batchCount [int]', 'Number of batches expected (batch mode)', @@ -71,6 +73,40 @@ program console.log(chalk.green(`build url: ${json.build.buildUrl}`)) }) +program + .command('cancel') + .description('Cancel the build (batch mode only)') + .option('-T, --token ', 'Repository token') + .option('--externalBuildId [string]', 'ID of the build (batch mode only)') + .action(async command => { + console.log(`=== argos-cli: canceling build`) + + let json + + try { + const res = await cancel({ ...command }) + json = await res.json() + + if (json.error) { + throw new CancelError(json.error.message) + } + } catch (error) { + displayError('Sorry an error happened:') + + if (error instanceof CancelError) { + console.error(chalk.bold.red(error.message)) + } else { + errorReporter.captureException(error) + console.error(chalk.bold.red(error.message)) + console.error(chalk.bold.red(error.stack)) + } + + process.exit(1) + } + + displaySuccess('Build canceled.') + }) + if (!process.argv.slice(2).length) { program.outputHelp() } else {