From 9ad3e1b1d40b0f7f7f22f563b7ed0717819e416c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 14 Jul 2023 14:59:13 +0200 Subject: [PATCH] #1025: add new command schedule and deploy option --schedule --- docs/dist/documentation.md | 15 ++++++++++++ lib/cli.js | 41 +++++++++++++++++++++++++++++++-- lib/index.js | 12 ++++++++++ lib/metadataTypes/Automation.js | 13 ++++------- test/type.automation.test.js | 30 +++++++++++++++++++++--- 5 files changed, 98 insertions(+), 13 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 99ba66f0f..57e14a1e0 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -519,6 +519,7 @@ main class * [.buildDefinition(businessUnit, selectedType, name, market)](#Mcdev.buildDefinition) ⇒ Promise.<void> * [.buildDefinitionBulk(listName, type, name)](#Mcdev.buildDefinitionBulk) ⇒ Promise.<void> * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> + * [.schedule(businessUnit, [selectedType], [keys])](#Mcdev.schedule) ⇒ Promise.<boolean> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> @@ -773,6 +774,20 @@ Build a specific metadata file based on a template using a list of bu-market com | selectedType | string | supported metadata type | | keyArr | Array.<string> | customerkey of the metadata | + + +### Mcdev.schedule(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> +Schedule an item (shortcut for execute --schedule) + +**Kind**: static method of [Mcdev](#Mcdev) +**Returns**: Promise.<boolean> - true if all started successfully, false if not + +| Param | Type | Description | +| --- | --- | --- | +| businessUnit | string | name of BU | +| [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | +| [keys] | Array.<string> | customerkey of the metadata | + ### Mcdev.execute(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> diff --git a/lib/cli.js b/lib/cli.js index 1c8395c55..99d83894e 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -87,10 +87,16 @@ yargs 'optional for asset-message: runs refresh command for related triggeredSends after deploy', }) .option('execute', { - type: 'string', + type: 'boolean', group: 'Options for deploy:', describe: - 'optional: executes item after deploy; for automations you can set it to --execute=schedule; alternatively it will run the automation once immediately', + 'optional: executes item after deploy; this will run the item once immediately', + }) + .option('schedule', { + type: 'boolean', + group: 'Options for deploy:', + describe: + 'optionally start existing schedule instead of running item once immediately (only works for automations)', }); }, handler: (argv) => { @@ -445,6 +451,37 @@ yargs Mcdev.execute(argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) + .command({ + command: 'schedule [KEY]', + aliases: ['sched'], + desc: 'starts the predefined schedule of the item (shortcut for running execute --schedule)', + builder: (yargs) => { + yargs + .positional('BU', { + type: 'string', + describe: 'the business unit where to start an item', + }) + .positional('TYPE', { + type: 'string', + describe: 'metadata type', + }) + .positional('KEY', { + type: 'string', + describe: 'key(s) of the metadata component(s)', + }) + .option('like', { + type: 'string', + group: 'Options for execute:', + describe: + 'filter metadata components (can include % as wildcard or _ for a single character)', + }); + }, + handler: (argv) => { + Mcdev.setOptions(argv); + // ! do not allow multiple types to be passed in here via csvToArray + Mcdev.schedule(argv.BU, argv.TYPE, csvToArray(argv.KEY)); + }, + }) .command({ command: 'pause [KEY]', aliases: ['p', 'stop'], diff --git a/lib/index.js b/lib/index.js index 13b2325e4..19b625ec7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -729,6 +729,18 @@ class Mcdev { return DevOps.getFilesToCommit(properties, buObject, selectedType, keyArr); } } + /** + * Schedule an item (shortcut for execute --schedule) + * + * @param {string} businessUnit name of BU + * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types + * @param {string[]} [keys] customerkey of the metadata + * @returns {Promise.} true if all started successfully, false if not + */ + static async schedule(businessUnit, selectedType, keys) { + this.setOptions({ schedule: true }); + return this.#runMethod('execute', businessUnit, selectedType, keys); + } /** * Start/execute an item * diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 714ff3f8b..f48554790 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -464,7 +464,7 @@ class Automation extends MetadataType { static async execute(keyArr) { const metadataMap = {}; for (const key of keyArr) { - if (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') { + if (Util.OPTIONS.schedule) { // schedule const results = await this.retrieve(undefined, undefined, undefined, key); if (Object.keys(results.metadata).length) { @@ -492,17 +492,14 @@ class Automation extends MetadataType { } Util.logger.info( `Starting automations ${ - Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule' + Util.OPTIONS.schedule ? 'according to schedule' : 'to run once (use --schedule or --execute=schedule to schedule instead)' }: ${Object.keys(metadataMap).length}` ); const promiseResults = []; for (const key of Object.keys(metadataMap)) { - if ( - (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') && - metadataMap[key].status === 'Scheduled' - ) { + if (Util.OPTIONS.schedule && metadataMap[key].status === 'Scheduled') { // schedule Util.logger.info( ` - skipping ${this.definition.type} ${metadataMap[key].name}: already scheduled.` @@ -527,7 +524,7 @@ class Automation extends MetadataType { * @returns {Promise.} Returns the result of the API call */ static async #executeItem(metadataMap, key) { - if (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') { + if (Util.OPTIONS.schedule) { this.#preDeploySchedule(metadataMap[key]); metadataMap[key].status = 'Scheduled'; return this.#scheduleAutomation(metadataMap, metadataMap, key); @@ -905,7 +902,7 @@ class Automation extends MetadataType { } } } - if (Util.OPTIONS.execute) { + if (Util.OPTIONS.execute || Util.OPTIONS.schedule) { Util.logger.info(`Executing: ${this.definition.type}`); await this.execute(Object.keys(metadataMap)); } diff --git a/test/type.automation.test.js b/test/type.automation.test.js index 581c232d3..de2a5c204 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -118,7 +118,7 @@ describe('type: automation', () => { }); it('Should update & schedule an automation with --execute option', async () => { // WHEN - handler.setOptions({ execute: 'schedule' }); + handler.setOptions({ schedule: true }); const deployed = await handler.deploy( 'testInstance/testBU', ['automation'], @@ -382,6 +382,30 @@ describe('type: automation', () => { }); describe('Execute ================', () => { it('Should schedule an automation by key', async () => { + const execute = await handler.schedule('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; + }); + it('Should schedule an automation selected via --like', async () => { + handler.setOptions({ like: { key: 'testExist%automation' } }); + const execute = await handler.schedule('testInstance/testBU', 'automation'); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; + }); + it('Should not schedule executing an automation because key and --like was specified', async () => { + handler.setOptions({ like: { key: 'testExisting%' } }); + const execute = await handler.schedule('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, true, 'execute should not have thrown an error'); + assert.equal(execute, false, 'automation was not supposed to be executed'); + return; + }); + it('Should execute --schedule an automation by key', async () => { handler.setOptions({ schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation', [ 'testExisting_automation', @@ -390,14 +414,14 @@ describe('type: automation', () => { assert.equal(execute, true, 'automation was supposed to be executed'); return; }); - it('Should schedule an automation selected via --like', async () => { + it('Should execute --schedule an automation selected via --like', async () => { handler.setOptions({ like: { key: 'testExist%automation' }, schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation'); assert.equal(process.exitCode, false, 'execute should not have thrown an error'); assert.equal(execute, true, 'automation was supposed to be executed'); return; }); - it('Should not schedule executing an automation because key and --like was specified', async () => { + it('Should not execute --schedule executing an automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting%' }, schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation', [ 'testExisting_automation',