diff --git a/config/base.js b/config/base.js index 1d7b7087..04fa90bf 100644 --- a/config/base.js +++ b/config/base.js @@ -65,15 +65,24 @@ const SCHEMA_SUBSCRIBE = Joi.object().keys({ const SCHEMA_CONFIG = Joi.object() .keys({ + template: Joi.string().regex(Regex.FULL_TEMPLATE_NAME_WITH_NAMESPACE), version: Joi.number().integer().min(1).max(50), - annotations: Annotations.annotations, - jobs: SCHEMA_JOBS.required(), - shared: SCHEMA_SHARED, - cache: SCHEMA_CACHE, - childPipelines: SCHEMA_CHILD_PIPELINES, - stages: SCHEMA_STAGES, - subscribe: SCHEMA_SUBSCRIBE, - parameters: Parameters.parameters.default({}) + annotations: Annotations.annotations.when('template', { is: Joi.exist(), then: Joi.forbidden() }), + jobs: SCHEMA_JOBS.when('template', { is: Joi.exist(), then: Joi.forbidden(), otherwise: Joi.required() }), + shared: Joi.when('template', { + is: Joi.exist(), + then: Joi.object().keys({ + image: Job.image, + environment: Job.environment, + settings: Job.settings + }), + otherwise: SCHEMA_SHARED + }), + cache: SCHEMA_CACHE.when('template', { is: Joi.exist(), then: Joi.forbidden() }), + childPipelines: SCHEMA_CHILD_PIPELINES.when('template', { is: Joi.exist(), then: Joi.forbidden() }), + stages: SCHEMA_STAGES.when('template', { is: Joi.exist(), then: Joi.forbidden() }), + subscribe: SCHEMA_SUBSCRIBE.when('template', { is: Joi.exist(), then: Joi.forbidden() }), + parameters: Parameters.parameters.default({}).when('template', { is: Joi.exist(), then: Joi.forbidden() }) }) .unknown(false); diff --git a/test/config/base.test.js b/test/config/base.test.js index b0ee35b7..7ed47d6f 100644 --- a/test/config/base.test.js +++ b/test/config/base.test.js @@ -44,4 +44,18 @@ describe('config base', () => { assert.isNull(validate('config.base.stages.yaml', config.base.stages).error); }); }); + + describe('pipeline template', () => { + it('validates the basic pipeline template usage', () => { + assert.isNull(validate('config.base.pipelineTemplate.yaml', config.base.config).error); + }); + + it('if template is provided then unsupported fields are foridden', () => { + assert.isNotNull(validate('config.base.pipelineTemplate-forbidden.yaml', config.base.config).error); + }); + + it('if template is not provided then job is required', () => { + assert.isNotNull(validate('config.base.pipelineTemplate-invalid.yaml', config.base.config).error); + }); + }); }); diff --git a/test/data/config.base.pipelineTemplate-forbidden.yaml b/test/data/config.base.pipelineTemplate-forbidden.yaml new file mode 100644 index 00000000..f596523c --- /dev/null +++ b/test/data/config.base.pipelineTemplate-forbidden.yaml @@ -0,0 +1,13 @@ +template: foo/bar@1.0.0 +shared: + image: node:20 + environment: + FOO: user overwrite + settings: + email: foo@example.com +jobs: + main: + required: [ ~commit ] + steps: + - init: npm install + - test: npm test \ No newline at end of file diff --git a/test/data/config.base.pipelineTemplate-invalid.yaml b/test/data/config.base.pipelineTemplate-invalid.yaml new file mode 100644 index 00000000..8cbe1280 --- /dev/null +++ b/test/data/config.base.pipelineTemplate-invalid.yaml @@ -0,0 +1 @@ +version: 1 \ No newline at end of file diff --git a/test/data/config.base.pipelineTemplate.yaml b/test/data/config.base.pipelineTemplate.yaml new file mode 100644 index 00000000..d51cb84f --- /dev/null +++ b/test/data/config.base.pipelineTemplate.yaml @@ -0,0 +1,7 @@ +template: foo/bar@1.0.0 +shared: + image: node:20 + environment: + FOO: user overwrite + settings: + email: foo@example.com \ No newline at end of file