From 53db17ebd6b4ee4b68c3b3b728660dce7d7b1f7e Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Sun, 11 Feb 2018 10:56:04 +0200 Subject: [PATCH 01/15] update --- docs/content/pipelines v2/_index.md | 7 - .../{pipelines v2 => pipelines}/spec.md | 0 .../cli/commands/pipeline/apply.cmd.js | 80 -------- .../{pipeline2 => pipeline}/create.cmd.js | 7 +- .../{pipeline2 => pipeline}/delete.cmd.js | 7 +- .../cli/commands/pipeline/get.cmd.js | 64 +------ .../{pipeline2 => pipeline}/replace.cmd.js | 7 +- .../cli/commands/pipeline/run.cmd.js | 51 ++--- .../cli/commands/pipeline2/get.cmd.js | 38 ---- lib/logic/api/MultipleRunner.js | 2 +- lib/logic/api/pipeline.js | 174 ++++++------------ lib/logic/api/pipeline2.js | 85 --------- lib/logic/entities/Pipeline.js | 8 +- lib/logic/entities/Pipeline2.js | 13 -- test/pipeline.spec.js | 2 +- 15 files changed, 94 insertions(+), 451 deletions(-) delete mode 100644 docs/content/pipelines v2/_index.md rename docs/content/{pipelines v2 => pipelines}/spec.md (100%) delete mode 100644 lib/interface/cli/commands/pipeline/apply.cmd.js rename lib/interface/cli/commands/{pipeline2 => pipeline}/create.cmd.js (87%) rename lib/interface/cli/commands/{pipeline2 => pipeline}/delete.cmd.js (88%) rename lib/interface/cli/commands/{pipeline2 => pipeline}/replace.cmd.js (91%) delete mode 100644 lib/interface/cli/commands/pipeline2/get.cmd.js delete mode 100644 lib/logic/api/pipeline2.js delete mode 100644 lib/logic/entities/Pipeline2.js diff --git a/docs/content/pipelines v2/_index.md b/docs/content/pipelines v2/_index.md deleted file mode 100644 index f8665a7c4..000000000 --- a/docs/content/pipelines v2/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Pipelines V2 (beta)" -weight = 0 -+++ - - -{{COMMANDS}} diff --git a/docs/content/pipelines v2/spec.md b/docs/content/pipelines/spec.md similarity index 100% rename from docs/content/pipelines v2/spec.md rename to docs/content/pipelines/spec.md diff --git a/lib/interface/cli/commands/pipeline/apply.cmd.js b/lib/interface/cli/commands/pipeline/apply.cmd.js deleted file mode 100644 index 710175ea6..000000000 --- a/lib/interface/cli/commands/pipeline/apply.cmd.js +++ /dev/null @@ -1,80 +0,0 @@ -const debug = require('debug')('codefresh:cli:create:context'); -const Command = require('../../Command'); -const CFError = require('cf-errors'); -const _ = require('lodash'); -const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); -const { pipeline } = require('../../../../logic').api; -const applyRoot = require('../root/apply.cmd'); - -const command = new Command({ - command: 'pipeline ', - aliases: ['pip', 'pipelines'], - parent: applyRoot, - description: 'Apply changes to a pipeline', - webDocs: { - category: 'Pipelines', - title: 'Update Pipeline', - }, - builder: (yargs) => { - return yargs - .positional('id', { - describe: 'pipeline id', - }) - .option('context', { - describe: 'context in form of: type=name', - type: 'array', - default: [], - alias: 'c', - }) - .option('engine-cluster', { - describe: 'K8 cluster name to use for execution', - }) - .option('engine-namespace', { - describe: 'K8 namespace in the chosen cluster to use for execution', - }) - .option('default-engine', { - describe: 'Use the default engine configured by the system', - type: 'boolean', - }) - .example('codefresh apply pipeline ID --context secret=my-list', "Add the 'my-list' secret context to pipeline ID") - .example('codefresh apply pipeline ID --engine-cluster=my-cluster --engine-namespace=my-namespace', "Define pipeline ID executions to run on k8 cluster 'my-cluster' on namespace 'my-namespace'") - .example('codefresh apply pipeline ID --default-engine', 'Define pipeline ID executions to run on the default engine of Codefresh'); - }, - handler: async (argv) => { - let pipelineToUpdate = {}; - - const pipelineId = argv.id; - - const contexts = prepareKeyValueFromCLIEnvOption(argv.context); - pipelineToUpdate.contexts = _.map(contexts, (name, type) => { - return { - type, - name, - }; - }); - - const cluster = argv['engine-cluster']; - const namespace = argv['engine-namespace']; - if (cluster && namespace) { - pipelineToUpdate.clusterProvider = { - active: true, - selector: cluster, - namespace: namespace, - }; - } - - if (argv['default-engine']) { - _.merge(pipelineToUpdate, { - clusterProvider: { - active: false, - }, - }); - } - - await pipeline.patchPipelineById(pipelineId, pipelineToUpdate); - console.log(`Pipeline: ${pipelineId} patched`); - }, -}); - -module.exports = command; - diff --git a/lib/interface/cli/commands/pipeline2/create.cmd.js b/lib/interface/cli/commands/pipeline/create.cmd.js similarity index 87% rename from lib/interface/cli/commands/pipeline2/create.cmd.js rename to lib/interface/cli/commands/pipeline/create.cmd.js index 959106c13..738e4e46f 100644 --- a/lib/interface/cli/commands/pipeline2/create.cmd.js +++ b/lib/interface/cli/commands/pipeline/create.cmd.js @@ -7,13 +7,12 @@ const { pipeline2 } = require('../../../../logic').api; const createRoot = require('../root/create.cmd'); const command = new Command({ - betaCommand: true, - command: 'pipeline2 [name]', - aliases: ['pip2'], + command: 'pipeline [name]', + aliases: ['pip'], parent: createRoot, description: 'Create a pipeline', webDocs: { - category: 'Pipelines V2', + category: 'Pipelines', title: 'Create Pipeline', }, builder: (yargs) => { diff --git a/lib/interface/cli/commands/pipeline2/delete.cmd.js b/lib/interface/cli/commands/pipeline/delete.cmd.js similarity index 88% rename from lib/interface/cli/commands/pipeline2/delete.cmd.js rename to lib/interface/cli/commands/pipeline/delete.cmd.js index e8ff45186..54501f2d8 100644 --- a/lib/interface/cli/commands/pipeline2/delete.cmd.js +++ b/lib/interface/cli/commands/pipeline/delete.cmd.js @@ -8,13 +8,12 @@ const deleteRoot = require('../root/delete.cmd'); const command = new Command({ - betaCommand: true, - command: 'pipeline2 [name]', - aliases: ['pip2'], + command: 'pipeline [name]', + aliases: ['pip'], parent: deleteRoot, description: 'Delete a pipeline', webDocs: { - category: 'Pipelines V2', + category: 'Pipelines', title: 'Delete Pipeline', }, builder: (yargs) => { diff --git a/lib/interface/cli/commands/pipeline/get.cmd.js b/lib/interface/cli/commands/pipeline/get.cmd.js index cb959fab0..313c10dbd 100644 --- a/lib/interface/cli/commands/pipeline/get.cmd.js +++ b/lib/interface/cli/commands/pipeline/get.cmd.js @@ -1,78 +1,34 @@ -const debug = require('debug')('codefresh:cli:create:context'); +const debug = require('debug')('codefresh:cli:create:pipelines2'); const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); -const { pipeline } = require('../../../../logic').api; +const { pipeline2 } = require('../../../../logic').api; const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); const getRoot = require('../root/get.cmd'); -const DEFAULTS = require('../../defaults'); - const command = new Command({ - command: 'pipelines [id]', + command: 'pipelines [name]', aliases: ['pip', 'pipeline'], parent: getRoot, description: 'Get a specific pipeline or an array of pipelines', - usage: 'Passing [id] argument will cause a retrieval of a specific pipeline.\n In case of not passing [id] argument, a list will be returned', webDocs: { category: 'Pipelines', title: 'Get Pipeline', }, builder: (yargs) => { return yargs - .positional('id', { - describe: 'Pipeline id', - }) - .option('repo-owner', { - describe: 'Repository owner', - }) - .option('repo-name', { - describe: 'Repository name', - }) - .option('limit', { - describe: 'Limit amount of returned results', - default: DEFAULTS.GET_LIMIT_RESULTS, - }) - .option('page', { - describe: 'Paginated page', - default: DEFAULTS.GET_PAGINATED_PAGE, - }) - .option('name', { - describe: 'Filter results by pipeline name', - type: Array, - }) - .example('codefresh get pipeline ID', 'Get pipeline ID') - .example('codefresh get pipelines', 'Get all pipelines') - .example('codefresh get pipelines --name release', 'Get all pipelines that their name is release') - .example('codefresh get pipelines --repo-name node', "Get all pipelines that are associated with the repository name 'node'"); + .positional('name', { + describe: 'Pipeline name', + }); }, handler: async (argv) => { - const id = argv.id; - const repoOwner = argv['repo-owner']; - const repoName = argv['repo-name']; - const name = argv.name; - const limit = argv.limit; - const page = argv.page; - - let pipelines; - // TODO:need to decide for one way for error handeling - if (id) { - pipelines = await pipeline.getPipelineById(id); - } else { - pipelines = await pipeline.getAll({ - repoOwner, - repoName, - name, - limit, - page, - }); - } + const {name, output} = argv; - if (_.isArray(pipelines)) { - specifyOutputForArray(argv.output, pipelines); + if (name) { + specifyOutputForSingle(output, await pipeline2.getPipelineByName(name)); } else { - specifyOutputForSingle(argv.output, pipelines); + specifyOutputForArray(output, await pipeline2.getAll()); } }, }); diff --git a/lib/interface/cli/commands/pipeline2/replace.cmd.js b/lib/interface/cli/commands/pipeline/replace.cmd.js similarity index 91% rename from lib/interface/cli/commands/pipeline2/replace.cmd.js rename to lib/interface/cli/commands/pipeline/replace.cmd.js index da9ced309..32395e4f9 100644 --- a/lib/interface/cli/commands/pipeline2/replace.cmd.js +++ b/lib/interface/cli/commands/pipeline/replace.cmd.js @@ -7,13 +7,12 @@ const { pipeline2 } = require('../../../../logic').api; const replaceRoot = require('../root/replace.cmd'); const command = new Command({ - betaCommand: true, - command: 'pipeline2 [name]', - aliases: ['pip2'], + command: 'pipeline [name]', + aliases: ['pip'], parent: replaceRoot, description: 'Replace a pipeline', webDocs: { - category: 'Pipelines V2', + category: 'Pipelines', title: 'Replace Pipeline', }, builder: (yargs) => { diff --git a/lib/interface/cli/commands/pipeline/run.cmd.js b/lib/interface/cli/commands/pipeline/run.cmd.js index 9bddd59b6..3d25bf287 100644 --- a/lib/interface/cli/commands/pipeline/run.cmd.js +++ b/lib/interface/cli/commands/pipeline/run.cmd.js @@ -10,7 +10,7 @@ const authManager = require('../../../../logic').auth.manager; const run = new Command({ root: true, - command: 'run ', + command: 'run ', description: 'Run a pipeline and attach the created workflow logs.', usage: 'Returns an exit code according to the workflow finish status (Success: 0, Error: 1, Terminated: 2)', webDocs: { @@ -24,8 +24,8 @@ const run = new Command({ alias: 'b', require: true, }) - .positional('id', { - describe: 'Pipeline id', + .positional('name', { + describe: 'Pipeline name', }) .option('sha', { describe: 'Set commit sha', @@ -64,45 +64,24 @@ const run = new Command({ return yargs; }, handler: async (argv) => { - const pipelineId = argv.id; + const pipelineName = argv.name; const branch = argv.branch; const sha = argv.sha; const noCache = argv['no-cache']; const resetVolume = argv['reset-volume']; const variablesFromFile = argv['var-file']; - - if (!authManager.getCurrentContext() - .isBetaFeatEnabled()) { - // validate that passed pipeline id an a mongo object id in case of pipeline V1 - if (!ObjectID.isValid(pipelineId)) { - throw new CFError({ - message: `Passed pipeline id: ${pipelineId} is not valid`, - }); - } - } - - let pipelineVersion = 'v1'; - if (authManager.getCurrentContext() - .isBetaFeatEnabled()) { - try { - await pipeline.getPipelineById(pipelineId); - } catch (err) { - try { - await pipeline2.getPipelineByName(pipelineId); - pipelineVersion = 'v2'; - } catch (err) { - throw new CFError({ - message: `Passed pipeline id: ${pipelineId} does not exist`, - }); - } - } + try { + await pipeline2.getPipelineByName(pipelineName); + } catch (err) { + throw new CFError({ + message: `Passed pipeline id: ${pipelineName} does not exist`, + }); } - const executionRequests = []; const executionRequestTemplate = { - pipelineId, + pipelineName, options: { noCache, resetVolume, @@ -124,13 +103,9 @@ const run = new Command({ executionRequests.push(request); } - _.forEach(executionRequests, async ({ pipelineId, options }) => { + _.forEach(executionRequests, async ({ pipelineName, options }) => { let workflowId; - if (pipelineVersion === 'v1') { - workflowId = await pipeline.runPipelineById(pipelineId, options); - } else { - workflowId = await pipeline2.runPipelineByName(pipelineId, options); - } + workflowId = await pipeline2.runPipelineByName(pipelineName, options); if (executionRequests.length === 1) { if (argv.detach) { diff --git a/lib/interface/cli/commands/pipeline2/get.cmd.js b/lib/interface/cli/commands/pipeline2/get.cmd.js deleted file mode 100644 index 42eae59d9..000000000 --- a/lib/interface/cli/commands/pipeline2/get.cmd.js +++ /dev/null @@ -1,38 +0,0 @@ -const debug = require('debug')('codefresh:cli:create:pipelines2'); -const Command = require('../../Command'); -const CFError = require('cf-errors'); -const _ = require('lodash'); -const { pipeline2 } = require('../../../../logic').api; -const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); -const getRoot = require('../root/get.cmd'); - - -const command = new Command({ - betaCommand: true, - command: 'pipelines2 [name]', - aliases: ['pip2', 'pipeline2'], - parent: getRoot, - description: 'Get a specific pipeline or an array of pipelines', - webDocs: { - category: 'Pipelines V2', - title: 'Get Pipeline V2', - }, - builder: (yargs) => { - return yargs - .positional('name', { - describe: 'Pipeline name', - }); - }, - handler: async (argv) => { - const {name, output} = argv; - - if (name) { - specifyOutputForSingle(output, await pipeline2.getPipelineByName(name)); - } else { - specifyOutputForArray(output, await pipeline2.getAll()); - } - }, -}); - -module.exports = command; - diff --git a/lib/logic/api/MultipleRunner.js b/lib/logic/api/MultipleRunner.js index 137df73c9..5b91fab1e 100644 --- a/lib/logic/api/MultipleRunner.js +++ b/lib/logic/api/MultipleRunner.js @@ -24,7 +24,7 @@ class MultipleJobRunner extends EventEmitter{ let self = this; let progressList = []; let stream = kefir.sequentially(100, this.jobs).flatMap((job)=>{ - return kefir.fromPromise(pipelines.runPipelineById(job.id, {envVars:job.envs})); + return kefir.fromPromise(pipelines.runPipelineByName(job.id, {envVars:job.envs})); }).log().flatMap((workflow)=>{ let options = { url: `/api/builds/${workflow}`, diff --git a/lib/logic/api/pipeline.js b/lib/logic/api/pipeline.js index ced9aa48a..2954e52c7 100644 --- a/lib/logic/api/pipeline.js +++ b/lib/logic/api/pipeline.js @@ -1,38 +1,18 @@ -const _ = require('lodash'); +const _ = require('lodash'); // eslint-disable-line +const CFError = require('cf-errors'); // eslint-disable-line const { sendHttpRequest } = require('./helper'); -const Pipeline = require('../entities/Pipeline'); -const CFError = require('cf-errors'); - - -const _extractFieldsForPipelineEntity = pipeline => ({ - id: pipeline._id, - name: pipeline.name, - imageName: pipeline.imageName, - repoOwner: pipeline.repoOwner, - repoName: pipeline.repoName, -}); - - -const getAll = async (options) => { - let qs = {}; - if (options) { - qs = { - name: options.name, - limit: options.limit, - page: options.page - 1, - repoOwner: options.repoOwner, - repoName: options.repoName, - }; - } - const RequestOptions = { - url: '/api/pipelines', - qs, +const Pipeline = require('../entities/Pipeline2'); + +const _extractFieldsForPipelineEntity = pipeline => _.pick(pipeline, 'id', 'kind', 'metadata', 'spec'); + +const getAll = async () => { + const options = { + url: '/api/pipelines/new', method: 'GET', }; - const result = await sendHttpRequest(RequestOptions); + const result = await sendHttpRequest(options); const pipelines = []; - _.forEach(result, (pipeline) => { const data = _extractFieldsForPipelineEntity(pipeline); pipelines.push(new Pipeline(data)); @@ -41,72 +21,58 @@ const getAll = async (options) => { return pipelines; }; -/** - * will return all pipelines by repository owner/name - * @param repoOwner - * @param repoName - * @returns {Promise<*>} - */ -const getAllByRepo = async (options) => { - const qs = { - name: options.name, - limit: options.limit, - page: options.page - 1, - }; - const RequestOptions = { - url: `/api/services/${encodeURIComponent(options.repoOwner)}/${encodeURIComponent(options.repoName)}`, - qs, +const getPipelineByName = async (name) => { + const options = { + url: `/api/pipelines/new/${name}`, method: 'GET', }; - const result = await sendHttpRequest(RequestOptions); - const pipelines = []; + const result = await sendHttpRequest(options); + const data = _extractFieldsForPipelineEntity(result); + return new Pipeline(data); +}; - _.forEach(result, (pipeline) => { - const data = _extractFieldsForPipelineEntity(pipeline); - pipelines.push(new Pipeline(data)); - }); +const createPipeline = async (data) => { + const options = { + url: '/api/pipelines/new', + method: 'POST', + body: data, + }; - return pipelines; + return sendHttpRequest(options); +}; - /* TODO:ask itai about this issue - _.forEach(pipelines, (pipeline) => { - delete pipeline.account; - }); - return pipelines; - */ +const replaceByName = async (name, data) => { + const body = data; + + const options = { + url: `/api/pipelines/new/${name}`, + method: 'PUT', + body, + }; + + return sendHttpRequest(options); +}; + +const deletePipelineByName = async (name) => { + const options = { + url: `/api/pipelines/new/${name}`, + method: 'DELETE', + }; + + return sendHttpRequest(options); }; /** - * will a pipeline by its name and repository owner/name + * will update a pipeline with only changes that were passed * @param name * @param repoOwner * @param repoName * @returns {Promise<*>} */ -const getPipelineByNameAndRepo = async (name, repoOwner, repoName) => { - const pipelines = await getAllByRepo({ - repoOwner, - repoName, - }); - const currPipeline = _.find(pipelines, pipeline => pipeline.info.name.toString() === name); - - if (!currPipeline) { - throw new CFError(`Pipeline name: ${name} wasn't found under repository: ${repoOwner}/${repoName}`); - } else { - return currPipeline; - } -}; - -const getPipelineById = async (id) => { - const options = { - url: `/api/pipelines/${id}`, - method: 'GET', - }; - - const pipeline = await sendHttpRequest(options); - const data = _extractFieldsForPipelineEntity(pipeline); - return new Pipeline(data); +const patchPipelineByName = async () => { + // TODO + throw new Error('not implemented'); }; /** @@ -114,7 +80,7 @@ const getPipelineById = async (id) => { * @param id * @returns {Promise<*>} */ -const runPipelineById = async (id, data = {}) => { +const runPipelineByName = async (name, data) => { const body = { options: {}, }; @@ -140,7 +106,7 @@ const runPipelineById = async (id, data = {}) => { } const options = { - url: `/api/builds/${id}`, + url: `/api/builds/${name}`, method: 'POST', body, }; @@ -148,40 +114,12 @@ const runPipelineById = async (id, data = {}) => { return sendHttpRequest(options); }; -/** - * will update a pipeline with only changes that were passed - * @param name - * @param repoOwner - * @param repoName - * @returns {Promise<*>} - */ -const patchPipelineById = async (id, pipeline) => { - const options = { - url: `/api/pipelines/${id}`, - method: 'PATCH', - body: pipeline, - }; - - return sendHttpRequest(options); -}; - -const patchPipelineByNameAndRepo = async (name, repoOwner, repoName, pipeline) => { - const options = { - url: `/api/services/${encodeURIComponent(repoOwner)}/${encodeURIComponent(repoName)}/${encodeURIComponent(name)}`, - method: 'PATCH', - body: pipeline, - }; - - return sendHttpRequest(options); -}; - - module.exports = { - runPipelineById, - patchPipelineById, - patchPipelineByNameAndRepo, - getPipelineById, getAll, - getAllByRepo, - getPipelineByNameAndRepo, + getPipelineByName, + createPipeline, + replaceByName, + patchPipelineByName, + deletePipelineByName, + runPipelineByName, }; diff --git a/lib/logic/api/pipeline2.js b/lib/logic/api/pipeline2.js deleted file mode 100644 index ac42c691e..000000000 --- a/lib/logic/api/pipeline2.js +++ /dev/null @@ -1,85 +0,0 @@ -const _ = require('lodash'); // eslint-disable-line -const CFError = require('cf-errors'); // eslint-disable-line -const { sendHttpRequest } = require('./helper'); -const Pipeline = require('../entities/Pipeline2'); - -const _extractFieldsForPipelineEntity = pipeline => _.pick(pipeline, 'id', 'kind', 'metadata', 'spec'); - -const getAll = async () => { - const options = { - url: '/api/pipelines/new', - method: 'GET', - }; - - const result = await sendHttpRequest(options); - const pipelines = []; - _.forEach(result, (pipeline) => { - const data = _extractFieldsForPipelineEntity(pipeline); - pipelines.push(new Pipeline(data)); - }); - - return pipelines; -}; - -const getPipelineByName = async (name) => { - const options = { - url: `/api/pipelines/new/${name}`, - method: 'GET', - }; - - const result = await sendHttpRequest(options); - const data = _extractFieldsForPipelineEntity(result); - return new Pipeline(data); -}; - -const createPipeline = async (data) => { - const options = { - url: '/api/pipelines/new', - method: 'POST', - body: data, - }; - - return sendHttpRequest(options); -}; - -const replaceByName = async (name, data) => { - const body = data; - - const options = { - url: `/api/pipelines/new/${name}`, - method: 'PUT', - body, - }; - - return sendHttpRequest(options); -}; - -const deletePipelineByName = async (name) => { - const options = { - url: `/api/pipelines/new/${name}`, - method: 'DELETE', - }; - - return sendHttpRequest(options); -}; - -const runPipelineByName = async (name, data) => { - const body = _.pick(data, 'variables', 'branch'); - - const options = { - url: `/api/pipelines/new/run/${name}`, - method: 'POST', - body, - }; - - return sendHttpRequest(options); -}; - -module.exports = { - getAll, - getPipelineByName, - createPipeline, - replaceByName, - deletePipelineByName, - runPipelineByName, -}; diff --git a/lib/logic/entities/Pipeline.js b/lib/logic/entities/Pipeline.js index d52547c68..17cba7618 100644 --- a/lib/logic/entities/Pipeline.js +++ b/lib/logic/entities/Pipeline.js @@ -1,13 +1,13 @@ const Entity = require('./Entity'); -class Pipeline extends Entity { +class Pipeline2 extends Entity { constructor(data) { super(); - this.entityType = 'pipeline'; + this.entityType = 'pipeline2'; this.info = data; - this.defaultColumns = ['id', 'name', 'repoOwner', 'repoName']; + this.defaultColumns = ['id', 'metadata.name']; this.wideColumns = this.defaultColumns.concat([]); } } -module.exports = Pipeline; +module.exports = Pipeline2; diff --git a/lib/logic/entities/Pipeline2.js b/lib/logic/entities/Pipeline2.js deleted file mode 100644 index 17cba7618..000000000 --- a/lib/logic/entities/Pipeline2.js +++ /dev/null @@ -1,13 +0,0 @@ -const Entity = require('./Entity'); - -class Pipeline2 extends Entity { - constructor(data) { - super(); - this.entityType = 'pipeline2'; - this.info = data; - this.defaultColumns = ['id', 'metadata.name']; - this.wideColumns = this.defaultColumns.concat([]); - } -} - -module.exports = Pipeline2; diff --git a/test/pipeline.spec.js b/test/pipeline.spec.js index 70b2e5cc5..fe9b83961 100644 --- a/test/pipeline.spec.js +++ b/test/pipeline.spec.js @@ -27,7 +27,7 @@ const authManager = auth.manager; console.log('after handler'); console.log(a); - const workflowId = await pipelines.runPipelineById('599a72291b3376000106331f', {}); + const workflowId = await pipelines.runPipelineByName('599a72291b3376000106331f', {}); const util = require('util'); const http = require('../lib/logic/api/helper'); let options = { From a41f2805cdb753b3a526d8ba6079b3113614c75f Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Sun, 11 Feb 2018 12:43:04 +0200 Subject: [PATCH 02/15] update --- docs/content/pipelines/spec.md | 6 +++--- lib/interface/cli/commands/pipeline/create.cmd.js | 2 +- lib/interface/cli/commands/pipeline/delete.cmd.js | 4 ++-- lib/interface/cli/commands/pipeline/get.cmd.js | 6 +++--- lib/interface/cli/commands/pipeline/replace.cmd.js | 4 ++-- lib/interface/cli/commands/pipeline/run.cmd.js | 6 +++--- lib/interface/cli/commands/root/create.cmd.js | 4 ++-- lib/logic/api/index.js | 2 -- lib/logic/api/pipeline.js | 12 ++++++------ lib/logic/entities/Pipeline.js | 6 +++--- 10 files changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/content/pipelines/spec.md b/docs/content/pipelines/spec.md index b2b2de293..c20fd5934 100644 --- a/docs/content/pipelines/spec.md +++ b/docs/content/pipelines/spec.md @@ -16,7 +16,7 @@ kind: "pipeline" metadata: name: "new-pipeline" labels: - repo: "github:ArikMaor/ping-server" + repo: "ArikMaor/ping-server" spec: triggers: - type: "scm" @@ -48,7 +48,7 @@ kind: "pipeline" metadata: name: "ew-pipeline-git" labels: - repo: "github:ArikMaor/ping-server" + repo: "ArikMaor/ping-server" spec: triggers: - type: "scm" @@ -76,7 +76,7 @@ kind: "pipeline" metadata: name: "new-pipeline-url" labels: - repo: "github:codefresh-io/cli" + repo: "codefresh-io/cli" spec: triggers: - type: "scm" diff --git a/lib/interface/cli/commands/pipeline/create.cmd.js b/lib/interface/cli/commands/pipeline/create.cmd.js index 738e4e46f..626e57b14 100644 --- a/lib/interface/cli/commands/pipeline/create.cmd.js +++ b/lib/interface/cli/commands/pipeline/create.cmd.js @@ -3,7 +3,7 @@ const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); -const { pipeline2 } = require('../../../../logic').api; +const { pipeline } = require('../../../../logic').api; const createRoot = require('../root/create.cmd'); const command = new Command({ diff --git a/lib/interface/cli/commands/pipeline/delete.cmd.js b/lib/interface/cli/commands/pipeline/delete.cmd.js index 54501f2d8..4d1e13f2f 100644 --- a/lib/interface/cli/commands/pipeline/delete.cmd.js +++ b/lib/interface/cli/commands/pipeline/delete.cmd.js @@ -2,7 +2,7 @@ const debug = require('debug')('codefresh:cli:create:pipelines2'); const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); -const { pipeline2 } = require('../../../../logic').api; +const { pipeline } = require('../../../../logic').api; const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); const deleteRoot = require('../root/delete.cmd'); @@ -25,7 +25,7 @@ const command = new Command({ handler: async (argv) => { const {name} = argv; - await pipeline2.deletePipelineByName(name); + await pipeline.deletePipelineByName(name); console.log(`Pipeline '${name}' deleted.`); }, }); diff --git a/lib/interface/cli/commands/pipeline/get.cmd.js b/lib/interface/cli/commands/pipeline/get.cmd.js index 313c10dbd..fd3a52d65 100644 --- a/lib/interface/cli/commands/pipeline/get.cmd.js +++ b/lib/interface/cli/commands/pipeline/get.cmd.js @@ -2,7 +2,7 @@ const debug = require('debug')('codefresh:cli:create:pipelines2'); const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); -const { pipeline2 } = require('../../../../logic').api; +const { pipeline } = require('../../../../logic').api; const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); const getRoot = require('../root/get.cmd'); @@ -26,9 +26,9 @@ const command = new Command({ const {name, output} = argv; if (name) { - specifyOutputForSingle(output, await pipeline2.getPipelineByName(name)); + specifyOutputForSingle(output, await pipeline.getPipelineByName(name)); } else { - specifyOutputForArray(output, await pipeline2.getAll()); + specifyOutputForArray(output, await pipeline.getAll()); } }, }); diff --git a/lib/interface/cli/commands/pipeline/replace.cmd.js b/lib/interface/cli/commands/pipeline/replace.cmd.js index 32395e4f9..2857dce52 100644 --- a/lib/interface/cli/commands/pipeline/replace.cmd.js +++ b/lib/interface/cli/commands/pipeline/replace.cmd.js @@ -3,7 +3,7 @@ const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); -const { pipeline2 } = require('../../../../logic').api; +const { pipeline } = require('../../../../logic').api; const replaceRoot = require('../root/replace.cmd'); const command = new Command({ @@ -37,7 +37,7 @@ const command = new Command({ _.set(data, 'metadata.name', name); }; - await pipeline2.replaceByName(data.metadata.name, data); + await pipeline.replaceByName(data.metadata.name, data); console.log(`Pipeline '${data.metadata.name}' updated`); }, }); diff --git a/lib/interface/cli/commands/pipeline/run.cmd.js b/lib/interface/cli/commands/pipeline/run.cmd.js index 3d25bf287..8cdda628f 100644 --- a/lib/interface/cli/commands/pipeline/run.cmd.js +++ b/lib/interface/cli/commands/pipeline/run.cmd.js @@ -4,7 +4,7 @@ const _ = require('lodash'); const CFError = require('cf-errors'); const { prepareKeyValueFromCLIEnvOption, crudFilenameOption } = require('../../helpers/general'); const ObjectID = require('mongodb').ObjectID; -const { workflow, pipeline, pipeline2, log } = require('../../../../logic').api; +const { workflow, pipeline, pipeline, log } = require('../../../../logic').api; const authManager = require('../../../../logic').auth.manager; @@ -72,7 +72,7 @@ const run = new Command({ const variablesFromFile = argv['var-file']; try { - await pipeline2.getPipelineByName(pipelineName); + await pipeline.getPipelineByName(pipelineName); } catch (err) { throw new CFError({ message: `Passed pipeline id: ${pipelineName} does not exist`, @@ -105,7 +105,7 @@ const run = new Command({ _.forEach(executionRequests, async ({ pipelineName, options }) => { let workflowId; - workflowId = await pipeline2.runPipelineByName(pipelineName, options); + workflowId = await pipeline.runPipelineByName(pipelineName, options); if (executionRequests.length === 1) { if (argv.detach) { diff --git a/lib/interface/cli/commands/root/create.cmd.js b/lib/interface/cli/commands/root/create.cmd.js index ca4ca5bee..87fb0cc2d 100644 --- a/lib/interface/cli/commands/root/create.cmd.js +++ b/lib/interface/cli/commands/root/create.cmd.js @@ -1,7 +1,7 @@ const CFError = require('cf-errors'); const Command = require('../../Command'); const { crudFilenameOption } = require('../../helpers/general'); -const { context, pipeline2 } = require('../../../../logic').api; +const { context, pipeline } = require('../../../../logic').api; const yargs = require('yargs'); const get = new Command({ @@ -32,7 +32,7 @@ const get = new Command({ console.log(`Context: ${data.metadata.name} created`); break; case 'pipeline': - await pipeline2.createPipeline(data); + await pipeline.createPipeline(data); console.log(`Pipeline '${data.metadata.name}' created`); break; default: diff --git a/lib/logic/api/index.js b/lib/logic/api/index.js index b80370045..b8cf63da6 100644 --- a/lib/logic/api/index.js +++ b/lib/logic/api/index.js @@ -1,7 +1,6 @@ const user = require('./user'); const trigger = require('./trigger'); const pipeline = require('./pipeline'); -const pipeline2 = require('./pipeline2'); const context = require('./context'); const image = require('./image'); const composition = require('./composition'); @@ -14,7 +13,6 @@ module.exports = { user, trigger, pipeline, - pipeline2, context, image, composition, diff --git a/lib/logic/api/pipeline.js b/lib/logic/api/pipeline.js index 2954e52c7..d69d95a87 100644 --- a/lib/logic/api/pipeline.js +++ b/lib/logic/api/pipeline.js @@ -1,13 +1,13 @@ const _ = require('lodash'); // eslint-disable-line const CFError = require('cf-errors'); // eslint-disable-line const { sendHttpRequest } = require('./helper'); -const Pipeline = require('../entities/Pipeline2'); +const Pipeline = require('../entities/Pipeline'); const _extractFieldsForPipelineEntity = pipeline => _.pick(pipeline, 'id', 'kind', 'metadata', 'spec'); const getAll = async () => { const options = { - url: '/api/pipelines/new', + url: '/api/pipelines', method: 'GET', }; @@ -23,7 +23,7 @@ const getAll = async () => { const getPipelineByName = async (name) => { const options = { - url: `/api/pipelines/new/${name}`, + url: `/api/pipelines/${name}`, method: 'GET', }; @@ -34,7 +34,7 @@ const getPipelineByName = async (name) => { const createPipeline = async (data) => { const options = { - url: '/api/pipelines/new', + url: '/api/pipelines', method: 'POST', body: data, }; @@ -46,7 +46,7 @@ const replaceByName = async (name, data) => { const body = data; const options = { - url: `/api/pipelines/new/${name}`, + url: `/api/pipelines/${name}`, method: 'PUT', body, }; @@ -56,7 +56,7 @@ const replaceByName = async (name, data) => { const deletePipelineByName = async (name) => { const options = { - url: `/api/pipelines/new/${name}`, + url: `/api/pipelines/${name}`, method: 'DELETE', }; diff --git a/lib/logic/entities/Pipeline.js b/lib/logic/entities/Pipeline.js index 17cba7618..e472c533e 100644 --- a/lib/logic/entities/Pipeline.js +++ b/lib/logic/entities/Pipeline.js @@ -1,13 +1,13 @@ const Entity = require('./Entity'); -class Pipeline2 extends Entity { +class Pipeline extends Entity { constructor(data) { super(); - this.entityType = 'pipeline2'; + this.entityType = 'pipeline'; this.info = data; this.defaultColumns = ['id', 'metadata.name']; this.wideColumns = this.defaultColumns.concat([]); } } -module.exports = Pipeline2; +module.exports = Pipeline; From d315596c05e957d731b4b2f015a92ce926989dd6 Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Mon, 12 Feb 2018 12:01:43 +0200 Subject: [PATCH 03/15] update --- .../cli/commands/context/replace.cmd.js | 37 --------------- .../cli/commands/pipeline/replace.cmd.js | 46 ------------------- .../cli/commands/pipeline/run.cmd.js | 3 +- lib/interface/cli/commands/root/create.cmd.js | 11 +++-- lib/interface/cli/commands/root/delete.cmd.js | 17 ++++++- .../cli/commands/root/replace.cmd.js | 18 +++++++- lib/logic/entities/Pipeline.js | 5 +- 7 files changed, 45 insertions(+), 92 deletions(-) delete mode 100644 lib/interface/cli/commands/context/replace.cmd.js delete mode 100644 lib/interface/cli/commands/pipeline/replace.cmd.js diff --git a/lib/interface/cli/commands/context/replace.cmd.js b/lib/interface/cli/commands/context/replace.cmd.js deleted file mode 100644 index bf120789e..000000000 --- a/lib/interface/cli/commands/context/replace.cmd.js +++ /dev/null @@ -1,37 +0,0 @@ -const debug = require('debug')('codefresh:cli:replace:context'); -const Command = require('../../Command'); -const CFError = require('cf-errors'); -const _ = require('lodash'); -const { context } = require('../../../../logic').api; -const replaceRoot = require('../root/replace.cmd'); - -const command = new Command({ - command: 'context', - aliases: ['ctx'], - parent: replaceRoot, - description: 'Replace a context', - webDocs: { - category: 'Contexts', - title: 'Replace Context', - }, - builder: (yargs) => { - return yargs - .example('codefresh replace context -f ./context.yml', 'Replace a context that matches name field of context.yml content'); - }, - handler: async (argv) => { - const data = argv.filename; - const name = _.get(data, 'metadata.name'); - - if (!name) { - throw new CFError('Missing name in metadata'); - } - - await context.replaceByName(name, data); - - console.log(`Context: ${name} replaced`); - }, -}); - - -module.exports = command; - diff --git a/lib/interface/cli/commands/pipeline/replace.cmd.js b/lib/interface/cli/commands/pipeline/replace.cmd.js deleted file mode 100644 index 2857dce52..000000000 --- a/lib/interface/cli/commands/pipeline/replace.cmd.js +++ /dev/null @@ -1,46 +0,0 @@ -const debug = require('debug')('codefresh:cli:create:pipelines2'); -const Command = require('../../Command'); -const CFError = require('cf-errors'); -const _ = require('lodash'); -const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); -const { pipeline } = require('../../../../logic').api; -const replaceRoot = require('../root/replace.cmd'); - -const command = new Command({ - command: 'pipeline [name]', - aliases: ['pip'], - parent: replaceRoot, - description: 'Replace a pipeline', - webDocs: { - category: 'Pipelines', - title: 'Replace Pipeline', - }, - builder: (yargs) => { - return yargs - .positional('name', { - describe: 'Name of context', - }); - }, - handler: async (argv) => { - const {filename, name} = argv; - - if (!filename) { - throw new CFError('Pipeline definitions file must be provided'); - } - - if (!_.get(filename, 'metadata.name') && !name) { - throw new CFError('Name must be provided'); - } - - const data = argv.filename; - if (name) { - _.set(data, 'metadata.name', name); - }; - - await pipeline.replaceByName(data.metadata.name, data); - console.log(`Pipeline '${data.metadata.name}' updated`); - }, -}); - -module.exports = command; - diff --git a/lib/interface/cli/commands/pipeline/run.cmd.js b/lib/interface/cli/commands/pipeline/run.cmd.js index 8cdda628f..82b0b9bf1 100644 --- a/lib/interface/cli/commands/pipeline/run.cmd.js +++ b/lib/interface/cli/commands/pipeline/run.cmd.js @@ -4,7 +4,7 @@ const _ = require('lodash'); const CFError = require('cf-errors'); const { prepareKeyValueFromCLIEnvOption, crudFilenameOption } = require('../../helpers/general'); const ObjectID = require('mongodb').ObjectID; -const { workflow, pipeline, pipeline, log } = require('../../../../logic').api; +const { workflow, pipeline, log } = require('../../../../logic').api; const authManager = require('../../../../logic').auth.manager; @@ -22,7 +22,6 @@ const run = new Command({ .option('branch', { describe: 'Branch', alias: 'b', - require: true, }) .positional('name', { describe: 'Pipeline name', diff --git a/lib/interface/cli/commands/root/create.cmd.js b/lib/interface/cli/commands/root/create.cmd.js index 87fb0cc2d..dd77ff74e 100644 --- a/lib/interface/cli/commands/root/create.cmd.js +++ b/lib/interface/cli/commands/root/create.cmd.js @@ -8,7 +8,7 @@ const get = new Command({ root: true, command: 'create', description: 'Create a resource from a file or stdin', - usage: 'Supported resources: \n\t\'Context\'', + usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline\'', webDocs: { description: 'Create a resource from a file, directory or url', category: 'Operate On Resources', @@ -26,14 +26,19 @@ const get = new Command({ const data = argv.filename; const entity = data.kind; + const name = data.metadata.name; + if (!name) { + throw new CFError("Name is missing"); + } + switch (entity) { case 'context': await context.createContext(data); - console.log(`Context: ${data.metadata.name} created`); + console.log(`Context: ${name} created`); break; case 'pipeline': await pipeline.createPipeline(data); - console.log(`Pipeline '${data.metadata.name}' created`); + console.log(`Pipeline '${name}' created`); break; default: throw new CFError(`Entity: ${entity} not supported`); diff --git a/lib/interface/cli/commands/root/delete.cmd.js b/lib/interface/cli/commands/root/delete.cmd.js index f16e180d9..a5c3272c8 100644 --- a/lib/interface/cli/commands/root/delete.cmd.js +++ b/lib/interface/cli/commands/root/delete.cmd.js @@ -1,6 +1,7 @@ const CFError = require('cf-errors'); const Command = require('../../Command'); const { crudFilenameOption } = require('../../helpers/general'); +const { context, pipeline } = require('../../../../logic').api; const yargs = require('yargs'); @@ -8,7 +9,7 @@ const get = new Command({ root: true, command: 'delete', description: 'Delete a resource by file or resource name', - usage: 'Supported resources:', + usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline\'', webDocs: { description: 'Delete a resource from a file, directory or url', category: 'Operate On Resources', @@ -26,7 +27,21 @@ const get = new Command({ const data = argv.filename; const entity = data.kind; + const name = data.metadata.name; + if (!name) { + throw new CFError('Name is missing'); + } + switch (entity) { + case 'context': + const owner = data.owner; + await context.deleteContextByName(name, owner); + console.log(`Context: ${name} deleted`); + break; + case 'pipeline': + await pipeline.deletePipelineByName(name); + console.log(`Pipeline '${name}' deleted`); + break; default: throw new CFError(`Entity: ${entity} not supported`); } diff --git a/lib/interface/cli/commands/root/replace.cmd.js b/lib/interface/cli/commands/root/replace.cmd.js index 8d5d97e9f..02140859c 100644 --- a/lib/interface/cli/commands/root/replace.cmd.js +++ b/lib/interface/cli/commands/root/replace.cmd.js @@ -1,13 +1,14 @@ const CFError = require('cf-errors'); const Command = require('../../Command'); const { crudFilenameOption } = require('../../helpers/general'); +const { context, pipeline } = require('../../../../logic').api; const yargs = require('yargs'); const annotate = new Command({ root: true, command: 'replace', - description: 'Replace a resource by filename or stdin', - usage: 'Replace operation will completely overwrite the existing resource and will throw an error if the resource does not exist.\n\n Supported resources: \n\t\'Context\'', + description: 'Replace a resource by filename', + usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline\'', webDocs: { description: 'Replace a resource from a file, directory or url', category: 'Operate On Resources', @@ -25,7 +26,20 @@ const annotate = new Command({ const data = argv.filename; const entity = data.kind; + const name = data.metadata.name; + if (!name) { + throw new CFError("Name is missing"); + } + switch (entity) { + case 'context': + await context.replaceByName(name, data); + console.log(`Context: ${name} created`); + break; + case 'pipeline': + await pipeline.replaceByName(name, data); + console.log(`Pipeline '${name}' updated`); + break; default: throw new CFError(`Entity: ${entity} not supported`); } diff --git a/lib/logic/entities/Pipeline.js b/lib/logic/entities/Pipeline.js index e472c533e..2544586ec 100644 --- a/lib/logic/entities/Pipeline.js +++ b/lib/logic/entities/Pipeline.js @@ -1,3 +1,4 @@ +const moment = require('moment'); const Entity = require('./Entity'); class Pipeline extends Entity { @@ -5,7 +6,9 @@ class Pipeline extends Entity { super(); this.entityType = 'pipeline'; this.info = data; - this.defaultColumns = ['id', 'metadata.name']; + this.name = this.info.metadata.name; + this.created = moment(this.info.metadata.created).fromNow(); + this.defaultColumns = ['name', 'created']; this.wideColumns = this.defaultColumns.concat([]); } } From c6f7a143a6bde8cfc3a4e328df9af1cbfe3f2bb9 Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Wed, 21 Feb 2018 15:16:50 +0200 Subject: [PATCH 04/15] update --- lib/logic/api/pipeline.js | 3 +-- lib/logic/entities/Pipeline.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/logic/api/pipeline.js b/lib/logic/api/pipeline.js index 3d02dffdc..77ed45306 100644 --- a/lib/logic/api/pipeline.js +++ b/lib/logic/api/pipeline.js @@ -1,8 +1,7 @@ const _ = require('lodash'); // eslint-disable-line -const CFError = require('cf-errors'); // eslint-disable-line +const CFError = require('cf-errors'); const { sendHttpRequest } = require('./helper'); const Pipeline = require('../entities/Pipeline'); -const CFError = require('cf-errors'); const { getContextByName } = require('./context'); const Promise = require('bluebird'); diff --git a/lib/logic/entities/Pipeline.js b/lib/logic/entities/Pipeline.js index 2544586ec..f26ff001b 100644 --- a/lib/logic/entities/Pipeline.js +++ b/lib/logic/entities/Pipeline.js @@ -7,7 +7,7 @@ class Pipeline extends Entity { this.entityType = 'pipeline'; this.info = data; this.name = this.info.metadata.name; - this.created = moment(this.info.metadata.created).fromNow(); + this.created = moment(this.info.metadata.created_at).fromNow(); this.defaultColumns = ['name', 'created']; this.wideColumns = this.defaultColumns.concat([]); } From 4d953812b2d9078fe8bd68d59feafe9985c266ae Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Thu, 22 Feb 2018 08:13:11 +0200 Subject: [PATCH 05/15] remove user-agent --- docs/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/index.js b/docs/index.js index 256ff19e8..9b673c7e3 100644 --- a/docs/index.js +++ b/docs/index.js @@ -273,9 +273,6 @@ const createDownloadPage = async () => { let links = []; const RequestOptions = { url: 'https://api.github.com/repos/codefresh-io/cli/releases/latest', - headers: { - 'User-Agent': 'codefresh-cli}', - }, json: true, }; try { From 5ac1da8a11bf15bfd88b9b04de6bd2806d0863c9 Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Wed, 28 Feb 2018 16:55:49 +0200 Subject: [PATCH 06/15] update --- docs/content/pipelines/spec.md | 19 ++++++++++++++++- .../cli/commands/pipeline/get.cmd.js | 21 ++++++++++++++++++- lib/logic/api/helper.js | 11 +++++++--- lib/logic/api/pipeline.js | 18 ++++++++++++---- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/docs/content/pipelines/spec.md b/docs/content/pipelines/spec.md index c20fd5934..b8fa0468a 100644 --- a/docs/content/pipelines/spec.md +++ b/docs/content/pipelines/spec.md @@ -15,8 +15,13 @@ apiVersion: "v1" kind: "pipeline" metadata: name: "new-pipeline" + description: "my description" labels: repo: "ArikMaor/ping-server" + key1: "Asd" + key2: "asd" + project: "asd" + spec: triggers: - type: "scm" @@ -32,13 +37,25 @@ spec: value: "BLA BLA" encrypted: true steps: - test_step: + clone_step: + repo: github.com/itai-codefresh/test-env-file + revision: master + test_step_1: image: "alpine" + working_directory: ${{clone_step}} commands: + - echo ls - echo "hello world" - echo "plain value $PORT" - echo "encrypted value $PAPA" - echo "value from context $COOKIE" + build: + type: build + working_directory: ${{clone_step}} + dockerfile: ./Dockerfile + image_name: itai/test + tag: bla + ``` #### Pipeline which is stored on a remote git diff --git a/lib/interface/cli/commands/pipeline/get.cmd.js b/lib/interface/cli/commands/pipeline/get.cmd.js index fd3a52d65..2704f5ffe 100644 --- a/lib/interface/cli/commands/pipeline/get.cmd.js +++ b/lib/interface/cli/commands/pipeline/get.cmd.js @@ -2,6 +2,7 @@ const debug = require('debug')('codefresh:cli:create:pipelines2'); const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); +const DEFAULTS = require('../../defaults'); const { pipeline } = require('../../../../logic').api; const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); const getRoot = require('../root/get.cmd'); @@ -20,15 +21,33 @@ const command = new Command({ return yargs .positional('name', { describe: 'Pipeline name', + }) + .option('name-regex', { + describe: 'Filter pipelines by name', + }) + .option('limit', { + describe: 'Limit amount of returned results', + default: DEFAULTS.GET_LIMIT_RESULTS, + }) + .option('page', { + describe: 'Paginated page', + default: DEFAULTS.GET_PAGINATED_PAGE, }); }, handler: async (argv) => { const {name, output} = argv; + const limit = argv.limit; + const offset = (argv.page - 1) * limit; + const nameRegex = argv['name-regex']; if (name) { specifyOutputForSingle(output, await pipeline.getPipelineByName(name)); } else { - specifyOutputForArray(output, await pipeline.getAll()); + specifyOutputForArray(output, await pipeline.getAll({ + limit, + offset, + nameRegex, + })); } }, }); diff --git a/lib/logic/api/helper.js b/lib/logic/api/helper.js index 3b328e830..379e45e1c 100644 --- a/lib/logic/api/helper.js +++ b/lib/logic/api/helper.js @@ -33,15 +33,20 @@ const sendHttpRequest = async (httpOptions, authContext) => { response = await rp(finalOptions); } catch (err) { if (_.isEqual(err.statusCode, 401)) { - printError('Unauthorized error: Please create or update your authentication context'); + printError('Error: Please create or update your authentication context'); process.exit(1); } if (_.isEqual(err.statusCode, 403)) { - printError('Forbidden error: You do not have permissions to perform this action'); + printError('Error: You do not have permissions to perform this action'); + process.exit(1); + } + if (_.get(err, 'error.message')) { + printError(`Error: ${err.error.message}`); process.exit(1); } - throw err; + printError('An error occurred'); + process.exit(1); } debug('Response:\n%O', response); return response; diff --git a/lib/logic/api/pipeline.js b/lib/logic/api/pipeline.js index 77ed45306..6fc7168e3 100644 --- a/lib/logic/api/pipeline.js +++ b/lib/logic/api/pipeline.js @@ -7,15 +7,25 @@ const Promise = require('bluebird'); const _extractFieldsForPipelineEntity = pipeline => _.pick(pipeline, 'id', 'kind', 'metadata', 'spec'); -const getAll = async () => { - const options = { +const getAll = async (options) => { + const qs = { + limit: options.limit, + offset: options.offset, + }; + + if (options.nameRegex) { + qs.name = options.nameRegex; + } + + const RequestOptions = { url: '/api/pipelines', method: 'GET', + qs, }; - const result = await sendHttpRequest(options); + const result = await sendHttpRequest(RequestOptions); const pipelines = []; - _.forEach(result, (pipeline) => { + _.forEach(result.docs, (pipeline) => { const data = _extractFieldsForPipelineEntity(pipeline); pipelines.push(new Pipeline(data)); }); From 4465e90522a70bd7180a94a65f7a464b7698133f Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Thu, 1 Mar 2018 13:18:59 +0200 Subject: [PATCH 07/15] update --- lib/interface/cli/commands/pipeline/get.cmd.js | 9 +++++++++ lib/logic/api/pipeline.js | 1 + 2 files changed, 10 insertions(+) diff --git a/lib/interface/cli/commands/pipeline/get.cmd.js b/lib/interface/cli/commands/pipeline/get.cmd.js index e3242656b..5c65cb73d 100644 --- a/lib/interface/cli/commands/pipeline/get.cmd.js +++ b/lib/interface/cli/commands/pipeline/get.cmd.js @@ -4,6 +4,7 @@ const CFError = require('cf-errors'); const _ = require('lodash'); const DEFAULTS = require('../../defaults'); const { pipeline } = require('../../../../logic').api; +const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); const getRoot = require('../root/get.cmd'); @@ -25,6 +26,11 @@ const command = new Command({ .option('name-regex', { describe: 'Filter pipelines by name', }) + .option('label', { + describe: 'Filter by a label', + alias: 'l', + default: [], + }) .option('limit', { describe: 'Limit amount of returned results', default: DEFAULTS.GET_LIMIT_RESULTS, @@ -39,6 +45,8 @@ const command = new Command({ const limit = argv.limit; const offset = (argv.page - 1) * limit; const nameRegex = argv['name-regex']; + const labels = prepareKeyValueFromCLIEnvOption(argv.label); + const pipelines = []; if (!_.isEmpty(names)) { @@ -51,6 +59,7 @@ const command = new Command({ limit, offset, nameRegex, + labels, })); } }, diff --git a/lib/logic/api/pipeline.js b/lib/logic/api/pipeline.js index 6fc7168e3..b7f77e5b4 100644 --- a/lib/logic/api/pipeline.js +++ b/lib/logic/api/pipeline.js @@ -11,6 +11,7 @@ const getAll = async (options) => { const qs = { limit: options.limit, offset: options.offset, + labels: options.labels, }; if (options.nameRegex) { From 9356449d0ceef90abc806f5788d0c30ac8292c27 Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Thu, 1 Mar 2018 13:28:59 +0200 Subject: [PATCH 08/15] update --- lib/interface/cli/helpers/get.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/interface/cli/helpers/get.js b/lib/interface/cli/helpers/get.js index 87a72189f..b08ae13d3 100644 --- a/lib/interface/cli/helpers/get.js +++ b/lib/interface/cli/helpers/get.js @@ -18,20 +18,21 @@ const print = (output) => { //i tried that this function will be dynamic (with the keys). it is also possible to add an array with all the fields if you think it better const _printArrayTable = (data) => { if (data.length === 0) { - throw ('no available resources'); - } - const keys = Object.keys(data[0]); - const res = []; - let obj = []; - _.forEach(data, (row) => { - obj = []; - _.forEach(keys, (key) => { - obj[key.toUpperCase()] = row[key]; + console.log('no available resources'); + } else { + const keys = Object.keys(data[0]); + const res = []; + let obj = []; + _.forEach(data, (row) => { + obj = []; + _.forEach(keys, (key) => { + obj[key.toUpperCase()] = row[key]; + }); + res.push(obj); }); - res.push(obj); - }); - const columns = columnify(res); - print(columns); + const columns = columnify(res); + print(columns); + } }; const _printSingleTable = (info) => { From ed708dc58fded3bc580a595e9bd9e9965a53d38a Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Thu, 1 Mar 2018 13:42:10 +0200 Subject: [PATCH 09/15] update --- lib/logic/entities/Pipeline.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/logic/entities/Pipeline.js b/lib/logic/entities/Pipeline.js index f26ff001b..8e3e259b1 100644 --- a/lib/logic/entities/Pipeline.js +++ b/lib/logic/entities/Pipeline.js @@ -8,7 +8,8 @@ class Pipeline extends Entity { this.info = data; this.name = this.info.metadata.name; this.created = moment(this.info.metadata.created_at).fromNow(); - this.defaultColumns = ['name', 'created']; + this.updated = moment(this.info.metadata.updated_at).fromNow(); + this.defaultColumns = ['name', 'updated', 'created']; this.wideColumns = this.defaultColumns.concat([]); } } From 0b4d13369c07de2dd5213042037cc244c7e094cf Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Fri, 2 Mar 2018 10:20:19 +0200 Subject: [PATCH 10/15] update --- docs/content/pipelines/spec.md | 3 +- .../cli/commands/pipeline/apply.cmd.js | 80 ++++++++ .../cli/commands/pipeline/create.cmd.js | 31 ---- .../cli/commands/pipeline/get.cmd.js | 63 ++++--- .../cli/commands/pipeline/run.cmd.js | 53 ++++-- .../{pipeline => pipeline2}/delete.cmd.js | 0 .../cli/commands/pipeline2/get.cmd.js | 69 +++++++ .../cli/commands/pipeline2/run.cmd.js | 148 +++++++++++++++ lib/logic/api/MultipleRunner.js | 91 --------- lib/logic/api/index.js | 2 + lib/logic/api/pipeline.js | 175 ++++++++++++------ lib/logic/api/pipeline2.js | 156 ++++++++++++++++ lib/logic/entities/Pipeline.js | 6 +- lib/logic/entities/Pipeline2.js | 17 ++ test/pipeline.spec.js | 2 +- 15 files changed, 664 insertions(+), 232 deletions(-) create mode 100644 lib/interface/cli/commands/pipeline/apply.cmd.js delete mode 100644 lib/interface/cli/commands/pipeline/create.cmd.js rename lib/interface/cli/commands/{pipeline => pipeline2}/delete.cmd.js (100%) create mode 100644 lib/interface/cli/commands/pipeline2/get.cmd.js create mode 100644 lib/interface/cli/commands/pipeline2/run.cmd.js delete mode 100644 lib/logic/api/MultipleRunner.js create mode 100644 lib/logic/api/pipeline2.js create mode 100644 lib/logic/entities/Pipeline2.js diff --git a/docs/content/pipelines/spec.md b/docs/content/pipelines/spec.md index b8fa0468a..1ac8f2ee3 100644 --- a/docs/content/pipelines/spec.md +++ b/docs/content/pipelines/spec.md @@ -18,8 +18,7 @@ metadata: description: "my description" labels: repo: "ArikMaor/ping-server" - key1: "Asd" - key2: "asd" + key1: "value1" project: "asd" spec: diff --git a/lib/interface/cli/commands/pipeline/apply.cmd.js b/lib/interface/cli/commands/pipeline/apply.cmd.js new file mode 100644 index 000000000..710175ea6 --- /dev/null +++ b/lib/interface/cli/commands/pipeline/apply.cmd.js @@ -0,0 +1,80 @@ +const debug = require('debug')('codefresh:cli:create:context'); +const Command = require('../../Command'); +const CFError = require('cf-errors'); +const _ = require('lodash'); +const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); +const { pipeline } = require('../../../../logic').api; +const applyRoot = require('../root/apply.cmd'); + +const command = new Command({ + command: 'pipeline ', + aliases: ['pip', 'pipelines'], + parent: applyRoot, + description: 'Apply changes to a pipeline', + webDocs: { + category: 'Pipelines', + title: 'Update Pipeline', + }, + builder: (yargs) => { + return yargs + .positional('id', { + describe: 'pipeline id', + }) + .option('context', { + describe: 'context in form of: type=name', + type: 'array', + default: [], + alias: 'c', + }) + .option('engine-cluster', { + describe: 'K8 cluster name to use for execution', + }) + .option('engine-namespace', { + describe: 'K8 namespace in the chosen cluster to use for execution', + }) + .option('default-engine', { + describe: 'Use the default engine configured by the system', + type: 'boolean', + }) + .example('codefresh apply pipeline ID --context secret=my-list', "Add the 'my-list' secret context to pipeline ID") + .example('codefresh apply pipeline ID --engine-cluster=my-cluster --engine-namespace=my-namespace', "Define pipeline ID executions to run on k8 cluster 'my-cluster' on namespace 'my-namespace'") + .example('codefresh apply pipeline ID --default-engine', 'Define pipeline ID executions to run on the default engine of Codefresh'); + }, + handler: async (argv) => { + let pipelineToUpdate = {}; + + const pipelineId = argv.id; + + const contexts = prepareKeyValueFromCLIEnvOption(argv.context); + pipelineToUpdate.contexts = _.map(contexts, (name, type) => { + return { + type, + name, + }; + }); + + const cluster = argv['engine-cluster']; + const namespace = argv['engine-namespace']; + if (cluster && namespace) { + pipelineToUpdate.clusterProvider = { + active: true, + selector: cluster, + namespace: namespace, + }; + } + + if (argv['default-engine']) { + _.merge(pipelineToUpdate, { + clusterProvider: { + active: false, + }, + }); + } + + await pipeline.patchPipelineById(pipelineId, pipelineToUpdate); + console.log(`Pipeline: ${pipelineId} patched`); + }, +}); + +module.exports = command; + diff --git a/lib/interface/cli/commands/pipeline/create.cmd.js b/lib/interface/cli/commands/pipeline/create.cmd.js deleted file mode 100644 index 626e57b14..000000000 --- a/lib/interface/cli/commands/pipeline/create.cmd.js +++ /dev/null @@ -1,31 +0,0 @@ -const debug = require('debug')('codefresh:cli:create:pipelines2'); -const Command = require('../../Command'); -const CFError = require('cf-errors'); -const _ = require('lodash'); -const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); -const { pipeline } = require('../../../../logic').api; -const createRoot = require('../root/create.cmd'); - -const command = new Command({ - command: 'pipeline [name]', - aliases: ['pip'], - parent: createRoot, - description: 'Create a pipeline', - webDocs: { - category: 'Pipelines', - title: 'Create Pipeline', - }, - builder: (yargs) => { - return yargs - .positional('name', { - describe: 'Name of context', - }); - }, - handler: async (argv) => { - throw new CFError('Not implemented'); - }, -}); - - -module.exports = command; - diff --git a/lib/interface/cli/commands/pipeline/get.cmd.js b/lib/interface/cli/commands/pipeline/get.cmd.js index 5c65cb73d..fb4763890 100644 --- a/lib/interface/cli/commands/pipeline/get.cmd.js +++ b/lib/interface/cli/commands/pipeline/get.cmd.js @@ -1,35 +1,34 @@ -const debug = require('debug')('codefresh:cli:create:pipelines2'); +const debug = require('debug')('codefresh:cli:create:context'); const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); -const DEFAULTS = require('../../defaults'); const { pipeline } = require('../../../../logic').api; -const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); const getRoot = require('../root/get.cmd'); +const DEFAULTS = require('../../defaults'); + const command = new Command({ - command: 'pipelines [name..]', + command: 'pipelines [id..]', aliases: ['pip', 'pipeline'], parent: getRoot, description: 'Get a specific pipeline or an array of pipelines', + usage: 'Passing [id] argument will cause a retrieval of a specific pipeline.\n In case of not passing [id] argument, a list will be returned', webDocs: { category: 'Pipelines', title: 'Get Pipeline', }, builder: (yargs) => { return yargs - .positional('name', { - describe: 'Pipeline name', + .positional('id', { + describe: 'Pipeline id', }) - .option('name-regex', { - describe: 'Filter pipelines by name', + .option('repo-owner', { + describe: 'Repository owner', }) - .option('label', { - describe: 'Filter by a label', - alias: 'l', - default: [], + .option('repo-name', { + describe: 'Repository name', }) .option('limit', { describe: 'Limit amount of returned results', @@ -38,30 +37,40 @@ const command = new Command({ .option('page', { describe: 'Paginated page', default: DEFAULTS.GET_PAGINATED_PAGE, - }); + }) + .option('name', { + describe: 'Filter results by pipeline name', + type: Array, + }) + .example('codefresh get pipeline ID', 'Get pipeline ID') + .example('codefresh get pipelines', 'Get all pipelines') + .example('codefresh get pipelines --name release', 'Get all pipelines that their name is release') + .example('codefresh get pipelines --repo-name node', "Get all pipelines that are associated with the repository name 'node'"); }, handler: async (argv) => { - const {names, output} = argv; + const pipelineIds = argv.id; + const repoOwner = argv['repo-owner']; + const repoName = argv['repo-name']; + const name = argv.name; const limit = argv.limit; - const offset = (argv.page - 1) * limit; - const nameRegex = argv['name-regex']; - const labels = prepareKeyValueFromCLIEnvOption(argv.label); + const page = argv.page; - - const pipelines = []; - if (!_.isEmpty(names)) { - for (const name of names) { - const currPipeline = await pipeline.getPipelineByName(name); + let pipelines = []; + if (!_.isEmpty(pipelineIds)) { + for (const id of pipelineIds) { + const currPipeline = await pipeline.getPipelineById(id); pipelines.push(currPipeline); } } else { - specifyOutputForArray(output, await pipeline.getAll({ + pipelines = await pipeline.getAll({ + repoOwner, + repoName, + name, limit, - offset, - nameRegex, - labels, - })); + page, + }); } + specifyOutputForArray(argv.output, pipelines); }, }); diff --git a/lib/interface/cli/commands/pipeline/run.cmd.js b/lib/interface/cli/commands/pipeline/run.cmd.js index 7ab20023f..9a2b8bb7f 100644 --- a/lib/interface/cli/commands/pipeline/run.cmd.js +++ b/lib/interface/cli/commands/pipeline/run.cmd.js @@ -4,13 +4,13 @@ const _ = require('lodash'); const CFError = require('cf-errors'); const { prepareKeyValueFromCLIEnvOption, crudFilenameOption } = require('../../helpers/general'); const ObjectID = require('mongodb').ObjectID; -const { workflow, pipeline, log } = require('../../../../logic').api; +const { workflow, pipeline, pipeline2, log } = require('../../../../logic').api; const authManager = require('../../../../logic').auth.manager; const run = new Command({ root: true, - command: 'run ', + command: 'run ', description: 'Run a pipeline and attach the created workflow logs.', usage: 'Returns an exit code according to the workflow finish status (Success: 0, Error: 1, Terminated: 2)', webDocs: { @@ -23,9 +23,10 @@ const run = new Command({ .option('branch', { describe: 'Branch', alias: 'b', + require: true, }) - .positional('name', { - describe: 'Pipeline name', + .positional('id', { + describe: 'Pipeline id', }) .option('sha', { describe: 'Set commit sha', @@ -70,7 +71,7 @@ const run = new Command({ return yargs; }, handler: async (argv) => { - const pipelineName = argv.name; + const pipelineId = argv.id; const branch = argv.branch; const sha = argv.sha; const noCache = argv['no-cache']; @@ -78,17 +79,37 @@ const run = new Command({ const variablesFromFile = argv['var-file']; const contexts = argv['context']; - try { - await pipeline.getPipelineByName(pipelineName); - } catch (err) { - throw new CFError({ - message: `Passed pipeline id: ${pipelineName} does not exist`, - }); + if (!authManager.getCurrentContext() + .isBetaFeatEnabled()) { + // validate that passed pipeline id an a mongo object id in case of pipeline V1 + if (!ObjectID.isValid(pipelineId)) { + throw new CFError({ + message: `Passed pipeline id: ${pipelineId} is not valid`, + }); + } } + let pipelineVersion = 'v1'; + if (authManager.getCurrentContext() + .isBetaFeatEnabled()) { + try { + await pipeline.getPipelineById(pipelineId); + } catch (err) { + try { + await pipeline2.getPipelineByName(pipelineId); + pipelineVersion = 'v2'; + } catch (err) { + throw new CFError({ + message: `Passed pipeline id: ${pipelineId} does not exist`, + }); + } + } + } + + const executionRequests = []; const executionRequestTemplate = { - pipelineName, + pipelineId, options: { noCache, resetVolume, @@ -111,9 +132,13 @@ const run = new Command({ executionRequests.push(request); } - _.forEach(executionRequests, async ({ pipelineName, options }) => { + _.forEach(executionRequests, async ({ pipelineId, options }) => { let workflowId; - workflowId = await pipeline.runPipelineByName(pipelineName, options); + if (pipelineVersion === 'v1') { + workflowId = await pipeline.runPipelineById(pipelineId, options); + } else { + workflowId = await pipeline2.runPipelineByName(pipelineId, options); + } if (executionRequests.length === 1) { if (argv.detach) { diff --git a/lib/interface/cli/commands/pipeline/delete.cmd.js b/lib/interface/cli/commands/pipeline2/delete.cmd.js similarity index 100% rename from lib/interface/cli/commands/pipeline/delete.cmd.js rename to lib/interface/cli/commands/pipeline2/delete.cmd.js diff --git a/lib/interface/cli/commands/pipeline2/get.cmd.js b/lib/interface/cli/commands/pipeline2/get.cmd.js new file mode 100644 index 000000000..5c65cb73d --- /dev/null +++ b/lib/interface/cli/commands/pipeline2/get.cmd.js @@ -0,0 +1,69 @@ +const debug = require('debug')('codefresh:cli:create:pipelines2'); +const Command = require('../../Command'); +const CFError = require('cf-errors'); +const _ = require('lodash'); +const DEFAULTS = require('../../defaults'); +const { pipeline } = require('../../../../logic').api; +const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); +const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); +const getRoot = require('../root/get.cmd'); + + +const command = new Command({ + command: 'pipelines [name..]', + aliases: ['pip', 'pipeline'], + parent: getRoot, + description: 'Get a specific pipeline or an array of pipelines', + webDocs: { + category: 'Pipelines', + title: 'Get Pipeline', + }, + builder: (yargs) => { + return yargs + .positional('name', { + describe: 'Pipeline name', + }) + .option('name-regex', { + describe: 'Filter pipelines by name', + }) + .option('label', { + describe: 'Filter by a label', + alias: 'l', + default: [], + }) + .option('limit', { + describe: 'Limit amount of returned results', + default: DEFAULTS.GET_LIMIT_RESULTS, + }) + .option('page', { + describe: 'Paginated page', + default: DEFAULTS.GET_PAGINATED_PAGE, + }); + }, + handler: async (argv) => { + const {names, output} = argv; + const limit = argv.limit; + const offset = (argv.page - 1) * limit; + const nameRegex = argv['name-regex']; + const labels = prepareKeyValueFromCLIEnvOption(argv.label); + + + const pipelines = []; + if (!_.isEmpty(names)) { + for (const name of names) { + const currPipeline = await pipeline.getPipelineByName(name); + pipelines.push(currPipeline); + } + } else { + specifyOutputForArray(output, await pipeline.getAll({ + limit, + offset, + nameRegex, + labels, + })); + } + }, +}); + +module.exports = command; + diff --git a/lib/interface/cli/commands/pipeline2/run.cmd.js b/lib/interface/cli/commands/pipeline2/run.cmd.js new file mode 100644 index 000000000..7ab20023f --- /dev/null +++ b/lib/interface/cli/commands/pipeline2/run.cmd.js @@ -0,0 +1,148 @@ +const debug = require('debug')('codefresh:cli:run:pipeline'); +const Command = require('../../Command'); +const _ = require('lodash'); +const CFError = require('cf-errors'); +const { prepareKeyValueFromCLIEnvOption, crudFilenameOption } = require('../../helpers/general'); +const ObjectID = require('mongodb').ObjectID; +const { workflow, pipeline, log } = require('../../../../logic').api; +const authManager = require('../../../../logic').auth.manager; + + +const run = new Command({ + root: true, + command: 'run ', + description: 'Run a pipeline and attach the created workflow logs.', + usage: 'Returns an exit code according to the workflow finish status (Success: 0, Error: 1, Terminated: 2)', + webDocs: { + category: 'Pipelines', + title: 'Run Pipeline', + weight: 50, + }, + builder: (yargs) => { + yargs + .option('branch', { + describe: 'Branch', + alias: 'b', + }) + .positional('name', { + describe: 'Pipeline name', + }) + .option('sha', { + describe: 'Set commit sha', + alias: 's', + }) + .option('no-cache', { + describe: 'Ignore cached images', + alias: 'nc', + default: false, + }) + .option('reset-volume', { + describe: 'Reset pipeline cached volume', + alias: 'rv', + default: false, + }) + .option('variable', { + describe: 'Set build variables', + default: [], + alias: 'v', + }) + .option('detach', { + alias: 'd', + describe: 'Run pipeline and print build ID', + }) + .option('context', { + alias: 'c', + describe: 'Run pipeline with contexts', + default: [], + }) + .example('codefresh run PIPELINE_ID -b=master', 'Defining the source control context using a branch') + .example('codefresh run PIPELINE_ID -s=52b992e783d2f84dd0123c70ac8623b4f0f938d1', 'Defining the source control context using a commit') + .example('codefresh run PIPELINE_ID -b=master -v key1=value1 -v key2=value2', 'Setting variables through the command') + .example('codefresh run PIPELINE_ID -b=master --var-file ./var_file.yml', 'Settings variables through a yml file') + .example('codefresh run PIPELINE_ID -b=master --context context', 'Inject contexts to the pipeline execution'); + + crudFilenameOption(yargs, { + name: 'variable-file', + alias: 'var-file', + describe: 'Set build variables from a file', + }); + + return yargs; + }, + handler: async (argv) => { + const pipelineName = argv.name; + const branch = argv.branch; + const sha = argv.sha; + const noCache = argv['no-cache']; + const resetVolume = argv['reset-volume']; + const variablesFromFile = argv['var-file']; + const contexts = argv['context']; + + try { + await pipeline.getPipelineByName(pipelineName); + } catch (err) { + throw new CFError({ + message: `Passed pipeline id: ${pipelineName} does not exist`, + }); + } + + const executionRequests = []; + const executionRequestTemplate = { + pipelineName, + options: { + noCache, + resetVolume, + branch, + sha, + }, + }; + + if (variablesFromFile) { + _.forEach(variablesFromFile, (variables) => { + const request = _.cloneDeep(executionRequestTemplate); + request.options.variables = variables; + executionRequests.push(request); + }); + } else { + const variables = prepareKeyValueFromCLIEnvOption(argv.variable); + const request = _.cloneDeep(executionRequestTemplate); + request.options.variables = variables; + request.options.contexts = contexts; + executionRequests.push(request); + } + + _.forEach(executionRequests, async ({ pipelineName, options }) => { + let workflowId; + workflowId = await pipeline.runPipelineByName(pipelineName, options); + + if (executionRequests.length === 1) { + if (argv.detach) { + console.log(workflowId); + } else { + await log.showWorkflowLogs(workflowId, true); + const workflowInstance = await workflow.getWorkflowById(workflowId); + switch (workflowInstance.getStatus()) { + case 'success': + process.exit(0); + break; + case 'error': + process.exit(1); + break; + case 'terminated': + process.exit(2); + break; + default: + process.exit(100); + break; + } + } + } else { + console.log(workflowId); + } + }); + + + }, +}); + +module.exports = run; diff --git a/lib/logic/api/MultipleRunner.js b/lib/logic/api/MultipleRunner.js deleted file mode 100644 index 5b91fab1e..000000000 --- a/lib/logic/api/MultipleRunner.js +++ /dev/null @@ -1,91 +0,0 @@ -/* eslint-disable */ - -const kefir = require('kefir'); -const EventEmitter = require('events'); -const debug = require('debug')('workflow.js') -const util = require('util'); -const http = require('./helper'); - - -const _ = require('lodash'); -const pipelines = require('./pipeline'); - -class MultipleJobRunner extends EventEmitter{ - - constructor(jobs, options){ - super(); - _.set(this, "jobs" , jobs); - let self = this; - - } - - - run (){ - let self = this; - let progressList = []; - let stream = kefir.sequentially(100, this.jobs).flatMap((job)=>{ - return kefir.fromPromise(pipelines.runPipelineByName(job.id, {envVars:job.envs})); - }).log().flatMap((workflow)=>{ - let options = { - url: `/api/builds/${workflow}`, - method: 'GET' - }; - return kefir.fromPromise(http.sendHttpRequest(options)) - }).log('workflow->').map((b)=>{ - return _.get(b, "id") - }).scan((prev, current)=>{ - prev.push(current); - return prev - }, progressList) - - class Emitter extends EventEmitter{ - start(period, buildId){ - this.buildId = buildId; - let intervalId = setInterval(()=>{ - let options = { - url: `/api/builds/${buildId}`, - method: 'GET' - }; - const statuses = ["success", "terminated", "failed"] - http.sendHttpRequest(options).then((v)=>{ - this.emit('value', v); - (_.get(v, "finished")) ? this.stop() : _.noop() - }); - }, period); - this.intervalId = intervalId; - } - - stop(){ - debug(`end of http request for buildId ${this.buildId}`); - clearInterval(this.intervalId); - this.emit('end'); - } - } - - let resultStream = stream.last().flatten().flatMap((progressId)=>{ - let emitter = new Emitter(); - emitter.start(1000, progressId); - return kefir.fromEvents(emitter, "value") - }) - - //.map(_.partial(_.pick,_ ,["steps","branchName", "revision", "status"] )).log(); - let onlyFinalResults = resultStream.filter(_.partial(_.get,_, "finished")).take(_.size(this.jobs)).log('finished->'); - let results = []; - onlyFinalResults.scan((prev , current)=>{ - prev.push(current); - return prev; - }, results).onEnd(()=>{ - self.emit('end' ,results); - }) - resultStream.onValue((v)=>{ - self.emit('progress', v); - }) - resultStream.filter((v)=>v.status !== "success") - resultStream.filter((v)=>v.status === "success") - onlyFinalResults.onEnd(()=>{ - console.log('running env finsihed'); - // self.emit('end'); - }) - } -} -module.exports = MultipleJobRunner; diff --git a/lib/logic/api/index.js b/lib/logic/api/index.js index b8cf63da6..b80370045 100644 --- a/lib/logic/api/index.js +++ b/lib/logic/api/index.js @@ -1,6 +1,7 @@ const user = require('./user'); const trigger = require('./trigger'); const pipeline = require('./pipeline'); +const pipeline2 = require('./pipeline2'); const context = require('./context'); const image = require('./image'); const composition = require('./composition'); @@ -13,6 +14,7 @@ module.exports = { user, trigger, pipeline, + pipeline2, context, image, composition, diff --git a/lib/logic/api/pipeline.js b/lib/logic/api/pipeline.js index b7f77e5b4..0232a71b9 100644 --- a/lib/logic/api/pipeline.js +++ b/lib/logic/api/pipeline.js @@ -1,32 +1,43 @@ -const _ = require('lodash'); // eslint-disable-line -const CFError = require('cf-errors'); +const _ = require('lodash'); const { sendHttpRequest } = require('./helper'); const Pipeline = require('../entities/Pipeline'); -const { getContextByName } = require('./context'); +const CFError = require('cf-errors'); +const { + getContextByName, +} = require('./context'); const Promise = require('bluebird'); -const _extractFieldsForPipelineEntity = pipeline => _.pick(pipeline, 'id', 'kind', 'metadata', 'spec'); -const getAll = async (options) => { - const qs = { - limit: options.limit, - offset: options.offset, - labels: options.labels, - }; +const _extractFieldsForPipelineEntity = pipeline => ({ + id: pipeline._id, + name: pipeline.name, + imageName: pipeline.imageName, + repoOwner: pipeline.repoOwner, + repoName: pipeline.repoName, +}); - if (options.nameRegex) { - qs.name = options.nameRegex; - } +const getAll = async (options) => { + let qs = {}; + if (options) { + qs = { + name: options.name, + limit: options.limit, + page: options.page - 1, + repoOwner: options.repoOwner, + repoName: options.repoName, + }; + } const RequestOptions = { url: '/api/pipelines', - method: 'GET', qs, + method: 'GET', }; const result = await sendHttpRequest(RequestOptions); const pipelines = []; - _.forEach(result.docs, (pipeline) => { + + _.forEach(result, (pipeline) => { const data = _extractFieldsForPipelineEntity(pipeline); pipelines.push(new Pipeline(data)); }); @@ -34,58 +45,72 @@ const getAll = async (options) => { return pipelines; }; -const getPipelineByName = async (name) => { - const options = { - url: `/api/pipelines/${name}`, - method: 'GET', +/** + * will return all pipelines by repository owner/name + * @param repoOwner + * @param repoName + * @returns {Promise<*>} + */ +const getAllByRepo = async (options) => { + const qs = { + name: options.name, + limit: options.limit, + page: options.page - 1, }; - - const result = await sendHttpRequest(options); - const data = _extractFieldsForPipelineEntity(result); - return new Pipeline(data); -}; - -const createPipeline = async (data) => { - const options = { - url: '/api/pipelines', - method: 'POST', - body: data, + const RequestOptions = { + url: `/api/services/${encodeURIComponent(options.repoOwner)}/${encodeURIComponent(options.repoName)}`, + qs, + method: 'GET', }; - return sendHttpRequest(options); -}; - -const replaceByName = async (name, data) => { - const body = data; - - const options = { - url: `/api/pipelines/${name}`, - method: 'PUT', - body, - }; + const result = await sendHttpRequest(RequestOptions); + const pipelines = []; - return sendHttpRequest(options); -}; + _.forEach(result, (pipeline) => { + const data = _extractFieldsForPipelineEntity(pipeline); + pipelines.push(new Pipeline(data)); + }); -const deletePipelineByName = async (name) => { - const options = { - url: `/api/pipelines/${name}`, - method: 'DELETE', - }; + return pipelines; - return sendHttpRequest(options); + /* TODO:ask itai about this issue + _.forEach(pipelines, (pipeline) => { + delete pipeline.account; + }); + return pipelines; + */ }; /** - * will update a pipeline with only changes that were passed + * will a pipeline by its name and repository owner/name * @param name * @param repoOwner * @param repoName * @returns {Promise<*>} */ -const patchPipelineByName = async () => { - // TODO - throw new Error('not implemented'); +const getPipelineByNameAndRepo = async (name, repoOwner, repoName) => { + const pipelines = await getAllByRepo({ + repoOwner, + repoName, + }); + const currPipeline = _.find(pipelines, pipeline => pipeline.info.name.toString() === name); + + if (!currPipeline) { + throw new CFError(`Pipeline name: ${name} wasn't found under repository: ${repoOwner}/${repoName}`); + } else { + return currPipeline; + } +}; + +const getPipelineById = async (id) => { + const options = { + url: `/api/pipelines/${id}`, + method: 'GET', + }; + + const pipeline = await sendHttpRequest(options); + const data = _extractFieldsForPipelineEntity(pipeline); + return new Pipeline(data); }; /** @@ -93,7 +118,7 @@ const patchPipelineByName = async () => { * @param id * @returns {Promise<*>} */ -const runPipelineByName = async (name, data) => { +const runPipelineById = async (id, data = {}) => { const body = { options: {}, }; @@ -137,7 +162,7 @@ const runPipelineByName = async (name, data) => { } const options = { - url: `/api/builds/${name}`, + url: `/api/builds/${id}`, method: 'POST', body, }; @@ -145,12 +170,40 @@ const runPipelineByName = async (name, data) => { return sendHttpRequest(options); }; +/** + * will update a pipeline with only changes that were passed + * @param name + * @param repoOwner + * @param repoName + * @returns {Promise<*>} + */ +const patchPipelineById = async (id, pipeline) => { + const options = { + url: `/api/pipelines/${id}`, + method: 'PATCH', + body: pipeline, + }; + + return sendHttpRequest(options); +}; + +const patchPipelineByNameAndRepo = async (name, repoOwner, repoName, pipeline) => { + const options = { + url: `/api/services/${encodeURIComponent(repoOwner)}/${encodeURIComponent(repoName)}/${encodeURIComponent(name)}`, + method: 'PATCH', + body: pipeline, + }; + + return sendHttpRequest(options); +}; + + module.exports = { + runPipelineById, + patchPipelineById, + patchPipelineByNameAndRepo, + getPipelineById, getAll, - getPipelineByName, - createPipeline, - replaceByName, - patchPipelineByName, - deletePipelineByName, - runPipelineByName, + getAllByRepo, + getPipelineByNameAndRepo, }; diff --git a/lib/logic/api/pipeline2.js b/lib/logic/api/pipeline2.js new file mode 100644 index 000000000..b7f77e5b4 --- /dev/null +++ b/lib/logic/api/pipeline2.js @@ -0,0 +1,156 @@ +const _ = require('lodash'); // eslint-disable-line +const CFError = require('cf-errors'); +const { sendHttpRequest } = require('./helper'); +const Pipeline = require('../entities/Pipeline'); +const { getContextByName } = require('./context'); +const Promise = require('bluebird'); + +const _extractFieldsForPipelineEntity = pipeline => _.pick(pipeline, 'id', 'kind', 'metadata', 'spec'); + +const getAll = async (options) => { + const qs = { + limit: options.limit, + offset: options.offset, + labels: options.labels, + }; + + if (options.nameRegex) { + qs.name = options.nameRegex; + } + + const RequestOptions = { + url: '/api/pipelines', + method: 'GET', + qs, + }; + + const result = await sendHttpRequest(RequestOptions); + const pipelines = []; + _.forEach(result.docs, (pipeline) => { + const data = _extractFieldsForPipelineEntity(pipeline); + pipelines.push(new Pipeline(data)); + }); + + return pipelines; +}; + +const getPipelineByName = async (name) => { + const options = { + url: `/api/pipelines/${name}`, + method: 'GET', + }; + + const result = await sendHttpRequest(options); + const data = _extractFieldsForPipelineEntity(result); + return new Pipeline(data); +}; + +const createPipeline = async (data) => { + const options = { + url: '/api/pipelines', + method: 'POST', + body: data, + }; + + return sendHttpRequest(options); +}; + +const replaceByName = async (name, data) => { + const body = data; + + const options = { + url: `/api/pipelines/${name}`, + method: 'PUT', + body, + }; + + return sendHttpRequest(options); +}; + +const deletePipelineByName = async (name) => { + const options = { + url: `/api/pipelines/${name}`, + method: 'DELETE', + }; + + return sendHttpRequest(options); +}; + +/** + * will update a pipeline with only changes that were passed + * @param name + * @param repoOwner + * @param repoName + * @returns {Promise<*>} + */ +const patchPipelineByName = async () => { + // TODO + throw new Error('not implemented'); +}; + +/** + * will run a pipeline by its id + * @param id + * @returns {Promise<*>} + */ +const runPipelineByName = async (name, data) => { + const body = { + options: {}, + }; + + if (data.branch) { + body.branch = data.branch; + } + + if (data.variables) { + body.variables = data.variables; + } + + if (data.noCache) { + body.options.noCache = data.noCache; + } + + if (data.resetVolume) { + body.options.resetVolume = data.resetVolume; + } + + if (data.sha) { + body.sha = data.sha; + } + + if (data.contexts) { + let contexts = []; + if (_.isString(data.contexts)) { + contexts = [data.contexts]; + } + await Promise.map(data.contexts, async (name) => { + try { + await getContextByName(name); + contexts.push({ + name, + }); + } catch (err) { + throw new CFError(err, `Failed to verify context ${name} with error ${err.message}`); + } + }); + body.contexts = contexts; + } + + const options = { + url: `/api/builds/${name}`, + method: 'POST', + body, + }; + + return sendHttpRequest(options); +}; + +module.exports = { + getAll, + getPipelineByName, + createPipeline, + replaceByName, + patchPipelineByName, + deletePipelineByName, + runPipelineByName, +}; diff --git a/lib/logic/entities/Pipeline.js b/lib/logic/entities/Pipeline.js index 8e3e259b1..d52547c68 100644 --- a/lib/logic/entities/Pipeline.js +++ b/lib/logic/entities/Pipeline.js @@ -1,4 +1,3 @@ -const moment = require('moment'); const Entity = require('./Entity'); class Pipeline extends Entity { @@ -6,10 +5,7 @@ class Pipeline extends Entity { super(); this.entityType = 'pipeline'; this.info = data; - this.name = this.info.metadata.name; - this.created = moment(this.info.metadata.created_at).fromNow(); - this.updated = moment(this.info.metadata.updated_at).fromNow(); - this.defaultColumns = ['name', 'updated', 'created']; + this.defaultColumns = ['id', 'name', 'repoOwner', 'repoName']; this.wideColumns = this.defaultColumns.concat([]); } } diff --git a/lib/logic/entities/Pipeline2.js b/lib/logic/entities/Pipeline2.js new file mode 100644 index 000000000..b9c72d0ab --- /dev/null +++ b/lib/logic/entities/Pipeline2.js @@ -0,0 +1,17 @@ +const moment = require('moment'); +const Entity = require('./Entity'); + +class Pipeline extends Entity { + constructor(data) { + super(); + this.entityType = 'pipeline V2'; + this.info = data; + this.name = this.info.metadata.name; + this.created = moment(this.info.metadata.created_at).fromNow(); + this.updated = moment(this.info.metadata.updated_at).fromNow(); + this.defaultColumns = ['name', 'updated', 'created']; + this.wideColumns = this.defaultColumns.concat([]); + } +} + +module.exports = Pipeline; diff --git a/test/pipeline.spec.js b/test/pipeline.spec.js index fe9b83961..70b2e5cc5 100644 --- a/test/pipeline.spec.js +++ b/test/pipeline.spec.js @@ -27,7 +27,7 @@ const authManager = auth.manager; console.log('after handler'); console.log(a); - const workflowId = await pipelines.runPipelineByName('599a72291b3376000106331f', {}); + const workflowId = await pipelines.runPipelineById('599a72291b3376000106331f', {}); const util = require('util'); const http = require('../lib/logic/api/helper'); let options = { From 3fb03c0ad04058e145043d255d4221e6030d344e Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Fri, 2 Mar 2018 10:22:46 +0200 Subject: [PATCH 11/15] update --- docs/content/pipelines v2/_index.md | 7 +++++++ docs/content/{pipelines => pipelines v2}/spec.md | 0 2 files changed, 7 insertions(+) create mode 100644 docs/content/pipelines v2/_index.md rename docs/content/{pipelines => pipelines v2}/spec.md (100%) diff --git a/docs/content/pipelines v2/_index.md b/docs/content/pipelines v2/_index.md new file mode 100644 index 000000000..f8665a7c4 --- /dev/null +++ b/docs/content/pipelines v2/_index.md @@ -0,0 +1,7 @@ ++++ +title = "Pipelines V2 (beta)" +weight = 0 ++++ + + +{{COMMANDS}} diff --git a/docs/content/pipelines/spec.md b/docs/content/pipelines v2/spec.md similarity index 100% rename from docs/content/pipelines/spec.md rename to docs/content/pipelines v2/spec.md From 536244d2d90d3357992fa815e4aa84ad51def02e Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Fri, 2 Mar 2018 10:28:47 +0200 Subject: [PATCH 12/15] update --- lib/interface/cli/commands/pipeline2/delete.cmd.js | 9 ++++----- lib/interface/cli/commands/pipeline2/get.cmd.js | 10 +++++----- lib/interface/cli/commands/pipeline2/run.cmd.js | 2 ++ lib/interface/cli/commands/root/create.cmd.js | 8 ++++---- lib/interface/cli/commands/root/delete.cmd.js | 6 +++--- lib/interface/cli/commands/root/replace.cmd.js | 6 +++--- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/interface/cli/commands/pipeline2/delete.cmd.js b/lib/interface/cli/commands/pipeline2/delete.cmd.js index 4d1e13f2f..c6f4e2568 100644 --- a/lib/interface/cli/commands/pipeline2/delete.cmd.js +++ b/lib/interface/cli/commands/pipeline2/delete.cmd.js @@ -2,18 +2,17 @@ const debug = require('debug')('codefresh:cli:create:pipelines2'); const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); -const { pipeline } = require('../../../../logic').api; -const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); +const { pipeline2: pipeline } = require('../../../../logic').api; const deleteRoot = require('../root/delete.cmd'); const command = new Command({ - command: 'pipeline [name]', - aliases: ['pip'], + command: 'pipeline-v2 [name]', + aliases: ['pip-v2'], parent: deleteRoot, description: 'Delete a pipeline', webDocs: { - category: 'Pipelines', + category: 'Pipelines V2', title: 'Delete Pipeline', }, builder: (yargs) => { diff --git a/lib/interface/cli/commands/pipeline2/get.cmd.js b/lib/interface/cli/commands/pipeline2/get.cmd.js index 5c65cb73d..7c4a99845 100644 --- a/lib/interface/cli/commands/pipeline2/get.cmd.js +++ b/lib/interface/cli/commands/pipeline2/get.cmd.js @@ -3,19 +3,19 @@ const Command = require('../../Command'); const CFError = require('cf-errors'); const _ = require('lodash'); const DEFAULTS = require('../../defaults'); -const { pipeline } = require('../../../../logic').api; +const { pipeline2: pipeline } = require('../../../../logic').api; const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); -const { specifyOutputForSingle, specifyOutputForArray } = require('../../helpers/get'); +const { specifyOutputForArray } = require('../../helpers/get'); const getRoot = require('../root/get.cmd'); const command = new Command({ - command: 'pipelines [name..]', - aliases: ['pip', 'pipeline'], + command: 'pipelines-v2 [name..]', + aliases: ['pip-v2', 'pipeline-v2'], parent: getRoot, description: 'Get a specific pipeline or an array of pipelines', webDocs: { - category: 'Pipelines', + category: 'Pipelines V2', title: 'Get Pipeline', }, builder: (yargs) => { diff --git a/lib/interface/cli/commands/pipeline2/run.cmd.js b/lib/interface/cli/commands/pipeline2/run.cmd.js index 7ab20023f..4df16b927 100644 --- a/lib/interface/cli/commands/pipeline2/run.cmd.js +++ b/lib/interface/cli/commands/pipeline2/run.cmd.js @@ -1,3 +1,4 @@ +/* const debug = require('debug')('codefresh:cli:run:pipeline'); const Command = require('../../Command'); const _ = require('lodash'); @@ -146,3 +147,4 @@ const run = new Command({ }); module.exports = run; +*/ diff --git a/lib/interface/cli/commands/root/create.cmd.js b/lib/interface/cli/commands/root/create.cmd.js index 7634f3736..b13f7380e 100644 --- a/lib/interface/cli/commands/root/create.cmd.js +++ b/lib/interface/cli/commands/root/create.cmd.js @@ -1,14 +1,14 @@ const CFError = require('cf-errors'); const Command = require('../../Command'); const { crudFilenameOption } = require('../../helpers/general'); -const { context, pipeline } = require('../../../../logic').api; +const { context, pipeline2: pipeline } = require('../../../../logic').api; const yargs = require('yargs'); const get = new Command({ root: true, command: 'create', description: 'Create a resource from a file or stdin', - usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline\'', + usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline-v2\'', webDocs: { description: 'Create a resource from a file, directory or url', category: 'Operate On Resources', @@ -37,9 +37,9 @@ const get = new Command({ await context.createContext(data); console.log(`Context: ${name} created`); break; - case 'pipeline': + case 'pipeline-v2': await pipeline.createPipeline(data); - console.log(`Pipeline '${name}' created`); + console.log(`Pipeline-v2 '${name}' created`); break; default: throw new CFError(`Entity: ${entity} not supported`); diff --git a/lib/interface/cli/commands/root/delete.cmd.js b/lib/interface/cli/commands/root/delete.cmd.js index 4c4347c59..ca9748736 100644 --- a/lib/interface/cli/commands/root/delete.cmd.js +++ b/lib/interface/cli/commands/root/delete.cmd.js @@ -1,7 +1,7 @@ const CFError = require('cf-errors'); const Command = require('../../Command'); const { crudFilenameOption } = require('../../helpers/general'); -const { context, pipeline } = require('../../../../logic').api; +const { context, pipeline2: pipeline } = require('../../../../logic').api; const yargs = require('yargs'); @@ -9,7 +9,7 @@ const get = new Command({ root: true, command: 'delete', description: 'Delete a resource by file or resource name', - usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline\'', + usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline-v2\'', webDocs: { description: 'Delete a resource from a file, directory or url', category: 'Operate On Resources', @@ -39,7 +39,7 @@ const get = new Command({ await context.deleteContextByName(name, owner); console.log(`Context: ${name} deleted`); break; - case 'pipeline': + case 'pipeline-v2': await pipeline.deletePipelineByName(name); console.log(`Pipeline '${name}' deleted`); break; diff --git a/lib/interface/cli/commands/root/replace.cmd.js b/lib/interface/cli/commands/root/replace.cmd.js index c13d868e0..d95ec6607 100644 --- a/lib/interface/cli/commands/root/replace.cmd.js +++ b/lib/interface/cli/commands/root/replace.cmd.js @@ -1,14 +1,14 @@ const CFError = require('cf-errors'); const Command = require('../../Command'); const { crudFilenameOption } = require('../../helpers/general'); -const { context, pipeline } = require('../../../../logic').api; +const { context, pipeline2: pipeline } = require('../../../../logic').api; const yargs = require('yargs'); const annotate = new Command({ root: true, command: 'replace', description: 'Replace a resource by filename', - usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline\'', + usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline-v2\'', webDocs: { description: 'Replace a resource from a file, directory or url', category: 'Operate On Resources', @@ -37,7 +37,7 @@ const annotate = new Command({ await context.replaceByName(name, data); console.log(`Context: ${name} created`); break; - case 'pipeline': + case 'pipeline-v2': await pipeline.replaceByName(name, data); console.log(`Pipeline '${name}' updated`); break; From 7db91a4a1e6e9a500e9a96c53151a2c3b2ac221e Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Fri, 2 Mar 2018 10:36:46 +0200 Subject: [PATCH 13/15] update --- .../cli/commands/pipeline/run.cmd.js | 45 +++++-------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/lib/interface/cli/commands/pipeline/run.cmd.js b/lib/interface/cli/commands/pipeline/run.cmd.js index 9a2b8bb7f..90112c494 100644 --- a/lib/interface/cli/commands/pipeline/run.cmd.js +++ b/lib/interface/cli/commands/pipeline/run.cmd.js @@ -4,9 +4,7 @@ const _ = require('lodash'); const CFError = require('cf-errors'); const { prepareKeyValueFromCLIEnvOption, crudFilenameOption } = require('../../helpers/general'); const ObjectID = require('mongodb').ObjectID; -const { workflow, pipeline, pipeline2, log } = require('../../../../logic').api; -const authManager = require('../../../../logic').auth.manager; - +const { workflow, pipeline, log } = require('../../../../logic').api; const run = new Command({ root: true, @@ -79,34 +77,20 @@ const run = new Command({ const variablesFromFile = argv['var-file']; const contexts = argv['context']; - if (!authManager.getCurrentContext() - .isBetaFeatEnabled()) { - // validate that passed pipeline id an a mongo object id in case of pipeline V1 - if (!ObjectID.isValid(pipelineId)) { - throw new CFError({ - message: `Passed pipeline id: ${pipelineId} is not valid`, - }); - } + if (!ObjectID.isValid(pipelineId)) { + throw new CFError({ + message: `Passed pipeline id: ${pipelineId} is not valid`, + }); } - let pipelineVersion = 'v1'; - if (authManager.getCurrentContext() - .isBetaFeatEnabled()) { - try { - await pipeline.getPipelineById(pipelineId); - } catch (err) { - try { - await pipeline2.getPipelineByName(pipelineId); - pipelineVersion = 'v2'; - } catch (err) { - throw new CFError({ - message: `Passed pipeline id: ${pipelineId} does not exist`, - }); - } - } + try { + await pipeline.getPipelineById(pipelineId); + } catch (err) { + throw new CFError({ + message: `Passed pipeline id: ${pipelineId} does not exist`, + }); } - const executionRequests = []; const executionRequestTemplate = { pipelineId, @@ -133,12 +117,7 @@ const run = new Command({ } _.forEach(executionRequests, async ({ pipelineId, options }) => { - let workflowId; - if (pipelineVersion === 'v1') { - workflowId = await pipeline.runPipelineById(pipelineId, options); - } else { - workflowId = await pipeline2.runPipelineByName(pipelineId, options); - } + const workflowId = await pipeline.runPipelineById(pipelineId, options); if (executionRequests.length === 1) { if (argv.detach) { From 2b06fdedb3d1bb7d88a652fe8f3971c8ba998496 Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Fri, 2 Mar 2018 10:38:26 +0200 Subject: [PATCH 14/15] update --- .../cli/commands/pipeline2/{run.cmd.js => run.cmd-beta.js} | 2 -- 1 file changed, 2 deletions(-) rename lib/interface/cli/commands/pipeline2/{run.cmd.js => run.cmd-beta.js} (99%) diff --git a/lib/interface/cli/commands/pipeline2/run.cmd.js b/lib/interface/cli/commands/pipeline2/run.cmd-beta.js similarity index 99% rename from lib/interface/cli/commands/pipeline2/run.cmd.js rename to lib/interface/cli/commands/pipeline2/run.cmd-beta.js index 4df16b927..7ab20023f 100644 --- a/lib/interface/cli/commands/pipeline2/run.cmd.js +++ b/lib/interface/cli/commands/pipeline2/run.cmd-beta.js @@ -1,4 +1,3 @@ -/* const debug = require('debug')('codefresh:cli:run:pipeline'); const Command = require('../../Command'); const _ = require('lodash'); @@ -147,4 +146,3 @@ const run = new Command({ }); module.exports = run; -*/ From d832519e24c6a552a03e9201fa50f3b0ddb8821f Mon Sep 17 00:00:00 2001 From: Itai Gendler Date: Fri, 2 Mar 2018 12:58:21 +0200 Subject: [PATCH 15/15] update --- .../spec.md | 1 - docs/content/pipelines v2/_index.md | 7 ------- docs/index.js | 6 +++++- .../cli/commands/pipeline2/delete.cmd.js | 2 +- .../cli/commands/pipeline2/get.cmd.js | 20 ++++++++++++++----- lib/interface/cli/commands/root/create.cmd.js | 4 ++-- lib/interface/cli/helpers/general.js | 2 +- lib/logic/api/helper.js | 9 ++++----- lib/logic/api/pipeline2.js | 12 +++++------ package.json | 2 +- 10 files changed, 35 insertions(+), 30 deletions(-) rename docs/content/{pipelines v2 => pipelines v2 (beta)}/spec.md (99%) delete mode 100644 docs/content/pipelines v2/_index.md diff --git a/docs/content/pipelines v2/spec.md b/docs/content/pipelines v2 (beta)/spec.md similarity index 99% rename from docs/content/pipelines v2/spec.md rename to docs/content/pipelines v2 (beta)/spec.md index 1ac8f2ee3..b90f45f2d 100644 --- a/docs/content/pipelines v2/spec.md +++ b/docs/content/pipelines v2 (beta)/spec.md @@ -1,6 +1,5 @@ +++ title = "Spec" -weight = 10 +++ A Pipeline needs `.apiVersion`, `.kind`, and `.metadata` fields. diff --git a/docs/content/pipelines v2/_index.md b/docs/content/pipelines v2/_index.md deleted file mode 100644 index f8665a7c4..000000000 --- a/docs/content/pipelines v2/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Pipelines V2 (beta)" -weight = 0 -+++ - - -{{COMMANDS}} diff --git a/docs/index.js b/docs/index.js index 368998b24..9e9ffa50f 100644 --- a/docs/index.js +++ b/docs/index.js @@ -10,12 +10,13 @@ const CFError = require('cf-errors'); const TEMP_DIR = path.resolve(__dirname, '../temp'); const TEMPLATE_DIR = path.resolve(__dirname); -const FILES_TO_IGNORE = ['index.js', 'content/pipelines v2/_index.md', 'content/pipelines v2/spec.md']; +const FILES_TO_IGNORE = ['index.js']; const baseDir = path.resolve(TEMP_DIR, './content'); const ALLOW_BETA_COMMANDS = process.env.ALLOW_BETA_COMMANDS; const categoriesOrder = { authentication: 30, pipelines : 40, + 'pipelines v2 (beta)' : 42, builds: 50, 'operate on resources' : 60, contexts : 70 , @@ -339,6 +340,9 @@ const createDownloadPage = async () => { let links = []; const RequestOptions = { url: 'https://api.github.com/repos/codefresh-io/cli/releases/latest', + headers: { + 'User-Agent': 'codefresh-cli-build', + }, json: true, }; try { diff --git a/lib/interface/cli/commands/pipeline2/delete.cmd.js b/lib/interface/cli/commands/pipeline2/delete.cmd.js index c6f4e2568..ca528b0c4 100644 --- a/lib/interface/cli/commands/pipeline2/delete.cmd.js +++ b/lib/interface/cli/commands/pipeline2/delete.cmd.js @@ -12,7 +12,7 @@ const command = new Command({ parent: deleteRoot, description: 'Delete a pipeline', webDocs: { - category: 'Pipelines V2', + category: 'Pipelines V2 (beta)', title: 'Delete Pipeline', }, builder: (yargs) => { diff --git a/lib/interface/cli/commands/pipeline2/get.cmd.js b/lib/interface/cli/commands/pipeline2/get.cmd.js index 7c4a99845..e2b41564d 100644 --- a/lib/interface/cli/commands/pipeline2/get.cmd.js +++ b/lib/interface/cli/commands/pipeline2/get.cmd.js @@ -4,8 +4,9 @@ const CFError = require('cf-errors'); const _ = require('lodash'); const DEFAULTS = require('../../defaults'); const { pipeline2: pipeline } = require('../../../../logic').api; -const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general'); +const { prepareKeyValueFromCLIEnvOption, printError } = require('../../helpers/general'); const { specifyOutputForArray } = require('../../helpers/get'); + const getRoot = require('../root/get.cmd'); @@ -15,7 +16,7 @@ const command = new Command({ parent: getRoot, description: 'Get a specific pipeline or an array of pipelines', webDocs: { - category: 'Pipelines V2', + category: 'Pipelines V2 (beta)', title: 'Get Pipeline', }, builder: (yargs) => { @@ -41,7 +42,7 @@ const command = new Command({ }); }, handler: async (argv) => { - const {names, output} = argv; + const {name: names, output} = argv; const limit = argv.limit; const offset = (argv.page - 1) * limit; const nameRegex = argv['name-regex']; @@ -51,8 +52,17 @@ const command = new Command({ const pipelines = []; if (!_.isEmpty(names)) { for (const name of names) { - const currPipeline = await pipeline.getPipelineByName(name); - pipelines.push(currPipeline); + try { + const currPipeline = await pipeline.getPipelineByName(name); + pipelines.push(currPipeline); + } catch (err) { + const message = err.toString() + .includes('404') ? `Pipeline '${name}' was not found.` : 'Error occurred'; + throw new CFError({ + cause: err, + message, + }); + } } } else { specifyOutputForArray(output, await pipeline.getAll({ diff --git a/lib/interface/cli/commands/root/create.cmd.js b/lib/interface/cli/commands/root/create.cmd.js index b13f7380e..0f351c1a7 100644 --- a/lib/interface/cli/commands/root/create.cmd.js +++ b/lib/interface/cli/commands/root/create.cmd.js @@ -8,7 +8,7 @@ const get = new Command({ root: true, command: 'create', description: 'Create a resource from a file or stdin', - usage: 'Supported resources: \n\t\'Context\'\n\t\'Pipeline-v2\'', + usage: 'Supported resources: \n\t\'context\'\n\t\'pipeline-v2\'', webDocs: { description: 'Create a resource from a file, directory or url', category: 'Operate On Resources', @@ -37,7 +37,7 @@ const get = new Command({ await context.createContext(data); console.log(`Context: ${name} created`); break; - case 'pipeline-v2': + case 'pipeline': await pipeline.createPipeline(data); console.log(`Pipeline-v2 '${name}' created`); break; diff --git a/lib/interface/cli/helpers/general.js b/lib/interface/cli/helpers/general.js index 46d96d8ad..9a2ef6da6 100644 --- a/lib/interface/cli/helpers/general.js +++ b/lib/interface/cli/helpers/general.js @@ -11,7 +11,7 @@ const printError = (error) => { if ((process.env.DEBUG || '').includes(defaults.DEBUG_PATTERN)) { console.error(error.stack); } else { - console.error(error.toString()); + console.error(`${error.message}`); } }; diff --git a/lib/logic/api/helper.js b/lib/logic/api/helper.js index 379e45e1c..0b2640066 100644 --- a/lib/logic/api/helper.js +++ b/lib/logic/api/helper.js @@ -40,13 +40,12 @@ const sendHttpRequest = async (httpOptions, authContext) => { printError('Error: You do not have permissions to perform this action'); process.exit(1); } + if (_.get(err, 'error.message')) { - printError(`Error: ${err.error.message}`); - process.exit(1); + throw new Error(err.error.message); + } else { + throw err; } - - printError('An error occurred'); - process.exit(1); } debug('Response:\n%O', response); return response; diff --git a/lib/logic/api/pipeline2.js b/lib/logic/api/pipeline2.js index b7f77e5b4..374381803 100644 --- a/lib/logic/api/pipeline2.js +++ b/lib/logic/api/pipeline2.js @@ -1,7 +1,7 @@ const _ = require('lodash'); // eslint-disable-line const CFError = require('cf-errors'); const { sendHttpRequest } = require('./helper'); -const Pipeline = require('../entities/Pipeline'); +const Pipeline = require('../entities/Pipeline2'); const { getContextByName } = require('./context'); const Promise = require('bluebird'); @@ -19,7 +19,7 @@ const getAll = async (options) => { } const RequestOptions = { - url: '/api/pipelines', + url: '/api/pipelines/new', method: 'GET', qs, }; @@ -36,7 +36,7 @@ const getAll = async (options) => { const getPipelineByName = async (name) => { const options = { - url: `/api/pipelines/${name}`, + url: `/api/pipelines/new/${name}`, method: 'GET', }; @@ -47,7 +47,7 @@ const getPipelineByName = async (name) => { const createPipeline = async (data) => { const options = { - url: '/api/pipelines', + url: '/api/pipelines/new', method: 'POST', body: data, }; @@ -59,7 +59,7 @@ const replaceByName = async (name, data) => { const body = data; const options = { - url: `/api/pipelines/${name}`, + url: `/api/pipelines/new/${name}`, method: 'PUT', body, }; @@ -69,7 +69,7 @@ const replaceByName = async (name, data) => { const deletePipelineByName = async (name) => { const options = { - url: `/api/pipelines/${name}`, + url: `/api/pipelines/new/${name}`, method: 'DELETE', }; diff --git a/package.json b/package.json index bdc86cb66..6f3bc1495 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codefresh", - "version": "0.8.28", + "version": "0.8.29", "description": "Codefresh command line utility", "main": "index.js", "preferGlobal": true,