@@ -352,8 +352,8 @@ function handleMergeSharedStepsAnnotation({ sharedConfig, jobConfig, template })
352352 * Retrieve template and merge into job config
353353 *
354354 * @method mergeTemplateIntoJob
355- * @param {String } jobName Job name
356- * @param {Object } jobConfig Job config
355+ * @param {String[] } jobNames Job names
356+ * @param {Object[] } jobConfigs Job configs
357357 * @param {Object } newJobs Object with all the jobs
358358 * @param {TemplateFactory } templateFactory Template Factory to get templates
359359 * @param {Object } sharedConfig Shared configuration
@@ -362,23 +362,26 @@ function handleMergeSharedStepsAnnotation({ sharedConfig, jobConfig, template })
362362 * @return {Promise }
363363 */
364364async function mergeTemplateIntoJob ( {
365- jobName ,
366- jobConfig ,
365+ jobNames ,
366+ jobConfigs ,
367367 newJobs,
368368 templateFactory,
369369 sharedConfig,
370370 pipelineParameters,
371371 isPipelineTemplate
372372} ) {
373- let oldJob = jobConfig ;
373+ const template = await templateFactory . getTemplate ( jobConfigs [ 0 ] . template ) ;
374374
375375 // Try to get the template
376- return templateFactory . getTemplate ( jobConfig . template ) . then ( template => {
376+ return jobNames . map ( ( jobName , i ) => {
377+ const jobConfig = jobConfigs [ i ] ;
378+ let oldJob = jobConfig ;
379+
377380 if ( ! template ) {
378381 throw new Error ( `Template ${ jobConfig . template } does not exist` ) ;
379382 }
380383
381- const newJob = template . config ;
384+ const newJob = clone ( template . config ) ;
382385 const environment = newJob . environment || { } ;
383386
384387 // Construct full template name
@@ -453,52 +456,60 @@ async function mergeTemplateIntoJob({
453456 */
454457async function flattenTemplates ( doc , templateFactory , isPipelineTemplate ) {
455458 const newJobs = { } ;
456- const templates = [ ] ;
459+ const orderWarnings = [ ] ;
457460 const { jobs, shared, parameters } = doc ;
458- const jobNames = Object . keys ( jobs ) ;
461+ const allJobNames = Object . keys ( jobs ) ;
459462
460- jobNames . forEach ( jobName => {
461- const jobConfig = clone ( jobs [ jobName ] ) ;
462- const templateConfig = jobConfig . template ;
463- const order = jobConfig . order || [ ] ;
464- let warnMessages = [ ] ;
463+ const jobGroupByTemplate = { } ;
465464
466- // Validate order is used with template
467- if ( order . length > 0 && templateConfig === undefined ) {
468- warnMessages = warnMessages . concat ( `"order" in ${ jobName } job cannot be used without "template"` ) ;
465+ allJobNames . forEach ( jobName => {
466+ const templateName = jobs [ jobName ] . template ;
469467
470- templates . push ( warnMessages ) ;
471- }
468+ if ( ! templateName ) {
469+ const jobConfig = clone ( jobs [ jobName ] ) ;
470+ const order = jobConfig . order || [ ] ;
472471
473- // If template is specified, then merge
474- if ( templateConfig ) {
475- templates . push (
476- mergeTemplateIntoJob ( {
477- jobName,
478- jobConfig,
479- newJobs,
480- templateFactory,
481- sharedConfig : shared ,
482- pipelineParameters : parameters ,
483- isPipelineTemplate
484- } )
485- ) ;
472+ // Validate order is used with template
473+ if ( order . length > 0 && templateName === undefined ) {
474+ orderWarnings . push ( `"order" in ${ jobName } job cannot be used without "template"` ) ;
475+ }
476+ newJobs [ jobName ] = jobConfig ;
477+
478+ return ;
479+ }
480+ if ( jobGroupByTemplate [ templateName ] === undefined ) {
481+ jobGroupByTemplate [ templateName ] = [ jobName ] ;
486482 } else {
487- newJobs [ jobName ] = jobConfig ; // Otherwise just use jobConfig
483+ jobGroupByTemplate [ templateName ] . push ( jobName ) ;
488484 }
489485 } ) ;
490486
487+ const promises = Object . values ( jobGroupByTemplate ) . map ( jobNames => {
488+ const jobConfigs = jobNames . map ( jobName => clone ( jobs [ jobName ] ) ) ;
489+
490+ // If template is specified, then merge
491+ return mergeTemplateIntoJob ( {
492+ jobNames,
493+ jobConfigs,
494+ newJobs,
495+ templateFactory,
496+ sharedConfig : shared ,
497+ pipelineParameters : parameters ,
498+ isPipelineTemplate
499+ } ) ;
500+ } ) ;
501+
491502 // Wait until all promises are resolved
492503 // Inserting newJobs with template is delayed, hence the order of newJobs.keys is incompatible to doc.jobs.keys
493- return Promise . all ( templates ) . then ( warnings => {
504+ return Promise . all ( promises ) . then ( warnings => {
494505 const sortedNewJobs = { } ;
495506
496- jobNames . forEach ( jobName => {
507+ allJobNames . forEach ( jobName => {
497508 sortedNewJobs [ jobName ] = newJobs [ jobName ] ;
498509 } ) ;
499510
500511 return {
501- warnings : [ ] . concat ( ...warnings ) ,
512+ warnings : [ ] . concat ( ...orderWarnings , ... warnings . flat ( ) ) ,
502513 newJobs : sortedNewJobs
503514 } ;
504515 } ) ;
0 commit comments