From 7be01fba7c3c9ba32768610a3d6b52020f537477 Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Wed, 18 Nov 2020 18:25:07 -0500 Subject: [PATCH 01/10] implementing reserving library loading order --- .../boozallen/plugins/jte/init/PipelineDecorator.groovy | 4 +++- .../config/dsl/PipelineConfigurationObject.groovy | 5 +++++ .../init/primitives/injectors/LibraryStepInjector.groovy | 9 +++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy index 0daa238f9..67da976ba 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy @@ -172,6 +172,7 @@ class PipelineDecorator extends InvisibleAction { String pipeline_template = null Boolean allow_scm_jenkinsfile = true Boolean permissive_initialization = false + Boolean prevent_library_override = false static LinkedHashMap getSchema(){ return [ @@ -179,7 +180,8 @@ class PipelineDecorator extends InvisibleAction { optional: [ allow_scm_jenkinsfile: Boolean, pipeline_template: String, - permissive_initialization: Boolean + permissive_initialization: Boolean, + prevent_library_override: Boolean ] ] ] diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/governance/config/dsl/PipelineConfigurationObject.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/governance/config/dsl/PipelineConfigurationObject.groovy index 7930a1cb3..d78585c78 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/governance/config/dsl/PipelineConfigurationObject.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/governance/config/dsl/PipelineConfigurationObject.groovy @@ -15,6 +15,7 @@ */ package org.boozallen.plugins.jte.init.governance.config.dsl +import org.boozallen.plugins.jte.init.PipelineDecorator import org.boozallen.plugins.jte.util.TemplateLogger import org.codehaus.groovy.runtime.InvokerHelper import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner @@ -38,6 +39,10 @@ class PipelineConfigurationObject implements Serializable{ this.flowOwner = flowOwner } + PipelineDecorator.JteBlockWrapper getJteBlockWrapper(){ + return (config.jte ?: [:]) as PipelineDecorator.JteBlockWrapper + } + PipelineConfigurationObject plus(PipelineConfigurationObject child){ /* If this is the first call to join, then there is no pre-existing diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy index 0de03cfe9..f626feecf 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy @@ -54,6 +54,10 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob LinkedHashMap aggregatedConfig = config.getConfig() AggregateException errors = new AggregateException() List providers = getLibraryProviders(flowOwner) + boolean reverseProviders = config.jteBlockWrapper.prevent_library_override + if(reverseProviders) { + providers = providers.reverse() + } ConfigValidator validator = new ConfigValidator(flowOwner) aggregatedConfig[KEY].each { libName, libConfig -> LibraryProvider provider = providers.find{ provider -> @@ -86,7 +90,12 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob @Override void injectPrimitives(FlowExecutionOwner flowOwner, PipelineConfigurationObject config, TemplateBinding binding){ LinkedHashMap aggregatedConfig = config.getConfig() + List providers = getLibraryProviders(flowOwner) + boolean reverseProviders = config.jteBlockWrapper.prevent_library_override + if(reverseProviders) { + providers = providers.reverse() + } aggregatedConfig[KEY].each{ libName, libConfig -> LibraryProvider provider = providers.find{ provider -> provider.hasLibrary(flowOwner, libName) From 55c739844fd461d6f4d71a59d08723784f883c5c Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Thu, 19 Nov 2020 10:17:12 -0500 Subject: [PATCH 02/10] unit test for LibraryStepInjector --- .../injectors/LibraryStepInjectorSpec.groovy | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy diff --git a/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy b/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy new file mode 100644 index 000000000..16bcf2187 --- /dev/null +++ b/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy @@ -0,0 +1,332 @@ +/* + Copyright 2018 Booz Allen Hamilton + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +package org.boozallen.plugins.jte.init.primitives.injectors + +import org.boozallen.plugins.jte.init.PipelineDecorator +import org.boozallen.plugins.jte.init.governance.GovernanceTier +import org.boozallen.plugins.jte.init.governance.config.dsl.PipelineConfigurationObject +import org.boozallen.plugins.jte.init.governance.libs.LibraryProvider +import org.boozallen.plugins.jte.init.governance.libs.LibrarySource +import org.boozallen.plugins.jte.init.primitives.TemplateBinding +import org.boozallen.plugins.jte.util.AggregateException +import org.jenkinsci.plugins.workflow.cps.CpsScript +import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner +import org.jenkinsci.plugins.workflow.job.WorkflowJob +import org.junit.ClassRule +import org.jvnet.hudson.test.JenkinsRule +import org.jvnet.hudson.test.WithoutJenkins +import spock.lang.Shared +import spock.lang.Specification + +class LibraryStepInjectorSpec extends Specification{ + + class JobChild { + WorkflowJob getParent(){ return null } + } + + @Shared @ClassRule JenkinsRule jenkins = new JenkinsRule() + CpsScript script = Mock() + PrintStream logger = Mock() + + WorkflowJob job = GroovyMock() + LibraryStepInjector injector = new LibraryStepInjector() + FlowExecutionOwner flowExecutionOwner = GroovyMock{ + run() >> GroovyMock(JobChild){ + getParent() >> job + } + } + + TemplateBinding templateBinding = Mock() + LinkedHashMap config = [ + jte: [:], + libraries: [:] + ] + + PipelineConfigurationObject pipelineConfigurationObject = pipelineConfigurationObject = Mock{ + getConfig() >> config + + getJteBlockWrapper() >> { return config.jte as PipelineDecorator.JteBlockWrapper } + } + + class MockLibraryProvider extends LibraryProvider{ + + @Override + Boolean hasLibrary(FlowExecutionOwner flowOwner, String libraryName) { + return false + } + + @Override + String getLibrarySchema(FlowExecutionOwner flowOwner, String libraryName) { + return null + } + + @Override + void loadLibrary(FlowExecutionOwner flowOwner, Binding binding, String libName, Map libConfig) { + } + + } + + @WithoutJenkins + def "when library source has library, loadLibrary is called"(){ + setup: + String libraryName = "libA" + config.libraries["libA"] = [:] + + MockLibraryProvider p1 = Mock{ + hasLibrary(flowExecutionOwner, libraryName) >> true + } + + LibrarySource s1 = Mock{ + getLibraryProvider() >> p1 + } + + GovernanceTier t1 = GroovyMock(global:true){ + getLibrarySources() >> [ s1 ] + } + + GovernanceTier.getHierarchy(_) >> [ t1 ] + + when: + injector.injectPrimitives(flowExecutionOwner, pipelineConfigurationObject, templateBinding) + + then: + 1 * p1.loadLibrary(flowExecutionOwner, templateBinding, libraryName, _) + } + + @WithoutJenkins + def "Libraries can be loaded across library sources in a governance tier"(){ + setup: + config.libraries["libA"] = [:] + config.libraries["libB"] = [:] + + MockLibraryProvider p1 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + } + MockLibraryProvider p2 = Mock{ + hasLibrary(flowExecutionOwner, "libB") >> true + } + + LibrarySource s1 = Mock{ + getLibraryProvider() >> p1 + } + LibrarySource s2 = Mock{ + getLibraryProvider() >> p2 + } + + GovernanceTier t1 = GroovyMock(global:true){ + getLibrarySources() >> [ s1, s2 ] + } + + GovernanceTier.getHierarchy(_) >> [ t1 ] + + when: + injector.injectPrimitives(flowExecutionOwner, pipelineConfigurationObject, templateBinding) + + then: + 1 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + 0 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libB", _) + 1 * p2.loadLibrary(flowExecutionOwner, templateBinding, "libB", _) + 0 * p2.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + } + + @WithoutJenkins + def "Libraries can be loaded across library sources in different governance tiers"(){ + setup: + config.libraries["libA"] = [:] + config.libraries["libB"] = [:] + + MockLibraryProvider p1 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + } + MockLibraryProvider p2 = Mock{ + hasLibrary(flowExecutionOwner, "libB") >> true + } + + LibrarySource s1 = Mock{ + getLibraryProvider() >> p1 + } + LibrarySource s2 = Mock{ + getLibraryProvider() >> p2 + } + + GovernanceTier tier1 = Mock{ + getLibrarySources() >> [ s1, s2 ] + } + + GovernanceTier tier2 = GroovyMock(global:true){ + getLibrarySources() >> [ s1, s2 ] + } + + GovernanceTier.getHierarchy(_) >> [ tier1, tier2 ] + + when: + injector.injectPrimitives(flowExecutionOwner, pipelineConfigurationObject, templateBinding) + + then: + 1 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + 0 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libB", _) + 0 * p2.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + 1 * p2.loadLibrary(flowExecutionOwner, templateBinding, "libB", _) + } + + @WithoutJenkins + def "library on more granular governance tier gets loaded"(){ + setup: + config.libraries["libA"] = [:] + + MockLibraryProvider p1 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + } + MockLibraryProvider p2 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + } + + LibrarySource s1 = Mock{ + getLibraryProvider() >> p1 + } + LibrarySource s2 = Mock{ + getLibraryProvider() >> p2 + } + + GovernanceTier tier1 = Mock{ + getLibrarySources() >> [ s1 ] + } + + GovernanceTier tier2 = GroovyMock(global:true){ + getLibrarySources() >> [ s2 ] + } + + GovernanceTier.getHierarchy(_) >> [ tier1, tier2 ] + + when: + injector.injectPrimitives(flowExecutionOwner, pipelineConfigurationObject, templateBinding) + + then: + 1 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + 0 * p2.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + } + + @WithoutJenkins + def "library on higher governance tier (last in hierarchy array) gets loaded if library override set to false"(){ + setup: + config.jte['prevent_library_override'] = true + config.libraries["libA"] = [:] + + MockLibraryProvider p1 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + } + MockLibraryProvider p2 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + } + + LibrarySource s1 = Mock{ + getLibraryProvider() >> p1 + } + LibrarySource s2 = Mock{ + getLibraryProvider() >> p2 + } + + GovernanceTier t1 = Mock{ + getLibrarySources() >> [ s1 ] + } + + GovernanceTier t2 = GroovyMock(global:true){ + getLibrarySources() >> [ s2 ] + } + + GovernanceTier.getHierarchy(_) >> [ t1, t2 ] + + when: + injector.injectPrimitives(flowExecutionOwner, pipelineConfigurationObject, templateBinding) + + then: + 0 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + 1 * p2.loadLibrary(flowExecutionOwner, templateBinding, "libA", _) + } + + @WithoutJenkins + def "library loader correctly passes step config"(){ + setup: + config.libraries = [ + libA: [ + fieldA: "A" + ], + libB: [ + fieldB: "B" + ] + ] + + MockLibraryProvider p1 = Mock{ + hasLibrary(flowExecutionOwner, "libA") >> true + hasLibrary(flowExecutionOwner, "libB") >> true + } + + LibrarySource s1 = Mock{ + getLibraryProvider() >> p1 + } + + GovernanceTier t1 = GroovyMock(global:true){ + getLibrarySources() >> [ s1 ] + } + + GovernanceTier.getHierarchy(_) >> [ t1 ] + + when: + injector.injectPrimitives(flowExecutionOwner, pipelineConfigurationObject, templateBinding) + + then: + 1 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libA", [fieldA: "A"]) + 1 * p1.loadLibrary(flowExecutionOwner, templateBinding, "libB", [fieldB: "B"]) + } + + @WithoutJenkins + def "Missing library throws exception"(){ + // now, when a library isn't found, we push a message onto the `libConfigErrors` array + // and throw the exception later after validating all the libraries. + // so this test represents making sure that an exception is thrown if a library does not exist. + setup: + config.libraries = [ + libA: [ + fieldA: "A" + ], + libB: [ + fieldB: "B" + ] + ] + + MockLibraryProvider p = Mock{ + 1 * hasLibrary(flowExecutionOwner, "libA") >> true + 1 * hasLibrary(flowExecutionOwner, "libB") >> false + } + + LibrarySource s = Mock{ + getLibraryProvider() >> p + } + + GovernanceTier tier = GroovyMock(global:true){ + getLibrarySources() >> [ s ] + } + + GovernanceTier.getHierarchy(_) >> [ tier ] + + when: + injector.validateConfiguration(flowExecutionOwner, pipelineConfigurationObject) + + then: + thrown(AggregateException) + } + +} From e90f3d5042d05ec3738cdad21c0a8cfb0bc81646 Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Thu, 19 Nov 2020 11:08:27 -0500 Subject: [PATCH 03/10] renamed 'prevent_library_override' to reverse_library_resolution --- .../org/boozallen/plugins/jte/init/PipelineDecorator.groovy | 4 ++-- .../jte/init/primitives/injectors/LibraryStepInjector.groovy | 4 ++-- .../init/primitives/injectors/LibraryStepInjectorSpec.groovy | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy index 67da976ba..0e1165882 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy @@ -172,7 +172,7 @@ class PipelineDecorator extends InvisibleAction { String pipeline_template = null Boolean allow_scm_jenkinsfile = true Boolean permissive_initialization = false - Boolean prevent_library_override = false + Boolean reverse_library_resolution = false static LinkedHashMap getSchema(){ return [ @@ -181,7 +181,7 @@ class PipelineDecorator extends InvisibleAction { allow_scm_jenkinsfile: Boolean, pipeline_template: String, permissive_initialization: Boolean, - prevent_library_override: Boolean + reverse_library_resolution: Boolean ] ] ] diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy index f626feecf..f232d2d69 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy @@ -54,7 +54,7 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob LinkedHashMap aggregatedConfig = config.getConfig() AggregateException errors = new AggregateException() List providers = getLibraryProviders(flowOwner) - boolean reverseProviders = config.jteBlockWrapper.prevent_library_override + boolean reverseProviders = config.jteBlockWrapper.reverse_library_resolution if(reverseProviders) { providers = providers.reverse() } @@ -92,7 +92,7 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob LinkedHashMap aggregatedConfig = config.getConfig() List providers = getLibraryProviders(flowOwner) - boolean reverseProviders = config.jteBlockWrapper.prevent_library_override + boolean reverseProviders = config.jteBlockWrapper.reverse_library_resolution if(reverseProviders) { providers = providers.reverse() } diff --git a/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy b/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy index 16bcf2187..3d3593cec 100644 --- a/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy +++ b/src/test/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjectorSpec.groovy @@ -222,7 +222,7 @@ class LibraryStepInjectorSpec extends Specification{ @WithoutJenkins def "library on higher governance tier (last in hierarchy array) gets loaded if library override set to false"(){ setup: - config.jte['prevent_library_override'] = true + config.jte['reverse_library_resolution'] = true config.libraries["libA"] = [:] MockLibraryProvider p1 = Mock{ From 4a01e2111024cf396d5c848c9a01d93f20c5f255 Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Thu, 19 Nov 2020 11:23:56 -0500 Subject: [PATCH 04/10] added reverse_library_resolution to the docs --- .../pipeline-templating/pages/configuration_files.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/modules/pipeline-templating/pages/configuration_files.adoc b/docs/modules/pipeline-templating/pages/configuration_files.adoc index dd7e6db91..4b4c279f9 100644 --- a/docs/modules/pipeline-templating/pages/configuration_files.adoc +++ b/docs/modules/pipeline-templating/pages/configuration_files.adoc @@ -22,6 +22,7 @@ jte{ <1> allow_scm_jenkinsfile = true pipeline_template = "some_template" permissive_initialization = false + reverse_library_resolution = false } template_methods{} <2> @@ -59,6 +60,10 @@ keywords{} <7> | Whether or not JTE will allow a naming collision within the binding. For example, two library's that both contribute a step by the same name or a keyword and application environment by the same name. | `false` +| reverse_library_resolution +| Normally, JTE resolves libraries based on the pipeline configurations from the highest governance tier down towards the job. This flag, if enabled, reverses the library search order +| `false` + |=== [WARNING] From 5385abd7107d60c9ef09883f3863dfd0eb028a6b Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Thu, 19 Nov 2020 11:44:18 -0500 Subject: [PATCH 05/10] fixed reverse_library_resolution heading in the docs --- docs/modules/pipeline-templating/pages/configuration_files.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/pipeline-templating/pages/configuration_files.adoc b/docs/modules/pipeline-templating/pages/configuration_files.adoc index 4b4c279f9..891b3bdee 100644 --- a/docs/modules/pipeline-templating/pages/configuration_files.adoc +++ b/docs/modules/pipeline-templating/pages/configuration_files.adoc @@ -60,7 +60,7 @@ keywords{} <7> | Whether or not JTE will allow a naming collision within the binding. For example, two library's that both contribute a step by the same name or a keyword and application environment by the same name. | `false` -| reverse_library_resolution +| `reverse_library_resolution` | Normally, JTE resolves libraries based on the pipeline configurations from the highest governance tier down towards the job. This flag, if enabled, reverses the library search order | `false` From 92ed1914b59843c0ec962e22a5f336295d1a370c Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Thu, 19 Nov 2020 11:47:58 -0500 Subject: [PATCH 06/10] fixed reverse_library_resolution explanation --- docs/modules/pipeline-templating/pages/configuration_files.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/pipeline-templating/pages/configuration_files.adoc b/docs/modules/pipeline-templating/pages/configuration_files.adoc index 891b3bdee..ffd34b3a9 100644 --- a/docs/modules/pipeline-templating/pages/configuration_files.adoc +++ b/docs/modules/pipeline-templating/pages/configuration_files.adoc @@ -61,7 +61,7 @@ keywords{} <7> | `false` | `reverse_library_resolution` -| Normally, JTE resolves libraries based on the pipeline configurations from the highest governance tier down towards the job. This flag, if enabled, reverses the library search order +| Normally, JTE resolves libraries based on the library sources from the highest governance tier down towards the job. This flag, if enabled, reverses the library search order | `false` |=== From 31f9e7290060abcdb645b38b3f8281abeee888c2 Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Fri, 20 Nov 2020 16:11:25 -0500 Subject: [PATCH 07/10] updated unit tests for additional jte block options --- .../plugins/jte/init/PipelineDecoratorSpec.groovy | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/groovy/org/boozallen/plugins/jte/init/PipelineDecoratorSpec.groovy b/src/test/groovy/org/boozallen/plugins/jte/init/PipelineDecoratorSpec.groovy index 935765b42..1b64e2c76 100644 --- a/src/test/groovy/org/boozallen/plugins/jte/init/PipelineDecoratorSpec.groovy +++ b/src/test/groovy/org/boozallen/plugins/jte/init/PipelineDecoratorSpec.groovy @@ -63,12 +63,14 @@ class PipelineDecoratorSpec extends Specification{ then: jte.allow_scm_jenkinsfile == expected_allow jte.pipeline_template == expected_template + jte.permissive_initialization == permissive + jte.reverse_library_resolution == reverse_libs where: - config | expected_allow | expected_template - [:] | true | null - [allow_scm_jenkinsfile:false] | false | null - [allow_scm_jenkinsfile:false, pipeline_template:'dev_template'] | false | 'dev_template' + config | expected_allow | expected_template | permissive | reverse_libs + [:] | true | null | false | false + [allow_scm_jenkinsfile:false, reverse_library_resolution:true] | false | null | false | true + [allow_scm_jenkinsfile:false, pipeline_template:'dev_template', permissive_initialization:true] | false | 'dev_template' | true | false } } From 2ca39e209c5012ebf6252b6b8715289514f26dfc Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Fri, 20 Nov 2020 16:11:45 -0500 Subject: [PATCH 08/10] update version doc with various features --- Version_2.adoc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Version_2.adoc b/Version_2.adoc index 932ff7da2..57d69b5fb 100644 --- a/Version_2.adoc +++ b/Version_2.adoc @@ -50,12 +50,17 @@ As JTE grows in adoption, there is plenty that can be done to improve our abilit == Feature Development +* [] https://github.com/jenkinsci/templating-engine-plugin/pull/132[Allow for reversal of library sources traversal] +* [x] https://github.com/jenkinsci/templating-engine-plugin/issues/111[move JTE behavior feature flags into a root level `jte` block in the pipeline configuration] +* [x] https://github.com/jenkinsci/templating-engine-plugin/issues/100[Pipeline Job: added SCM pipeline configuration and template] +* [x] https://github.com/jenkinsci/templating-engine-plugin/pull/101[JTE pipelines can survive an ungraceful restart now] +* [x] https://github.com/jenkinsci/templating-engine-plugin/pull/98[Added pipelineConfig reserved variable] * [x] https://github.com/jenkinsci/templating-engine-plugin/issues/46[Add support for Library Resources] * [x] https://github.com/jenkinsci/templating-engine-plugin/issues/97[Field-level pipeline configuration governance] * [x] https://github.com/jenkinsci/templating-engine-plugin/issues/79[Standardize on autowired variables - remove the Lifecycle Hook context parameter in favor of an autowired variable] * [x] https://github.com/jenkinsci/templating-engine-plugin/issues/72[Document the StageContext functionality to pass arguments to steps run as part of a Stage] -* [ ] https://github.com/jenkinsci/templating-engine-plugin/issues/62[Introduce step namespacing so that multiple steps with the same name can be loaded via a less-strict initialization process configurable by the user] -* [ ] https://github.com/jenkinsci/templating-engine-plugin/issues/84[Improve overall initialization logging for JTE to help users debug issues] +* [x] https://github.com/jenkinsci/templating-engine-plugin/issues/62[Introduce step namespacing so that multiple steps with the same name can be loaded via a less-strict initialization process configurable by the user] +* [x] https://github.com/jenkinsci/templating-engine-plugin/issues/84[Improve overall initialization logging for JTE to help users debug issues] * [ ] https://github.com/jenkinsci/templating-engine-plugin/issues/23[Investigate whether or not JTE can integrate with Jenkins Pipeline's Declarative Syntax] From fbca295127a67b93ffd6b73afe6459ff5eba6b96 Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Mon, 23 Nov 2020 10:02:03 -0500 Subject: [PATCH 09/10] using jteBlockWrapper getter --- .../org/boozallen/plugins/jte/init/PipelineDecorator.groovy | 3 +-- .../plugins/jte/init/primitives/TemplateBindingFactory.groovy | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy index 0e1165882..dc2621d41 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/PipelineDecorator.groovy @@ -106,10 +106,9 @@ class PipelineDecorator extends InvisibleAction { } String determinePipelineTemplate(){ - LinkedHashMap pipelineConfig = config.getConfig() WorkflowJob job = getJob() FlowDefinition flowDefinition = job.getDefinition() - JteBlockWrapper jteBlockWrapper = (pipelineConfig.jte ?: [:]) as JteBlockWrapper + JteBlockWrapper jteBlockWrapper = config.jteBlockWrapper if (flowDefinition instanceof AdHocTemplateFlowDefinition){ String template = flowDefinition.getTemplate(flowOwner) if(template){ diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplateBindingFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplateBindingFactory.groovy index 3975c8445..dd6ab8387 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplateBindingFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplateBindingFactory.groovy @@ -39,7 +39,7 @@ class TemplateBindingFactory { static TemplateBinding create(FlowExecutionOwner flowOwner, PipelineConfigurationObject config){ invoke("validateConfiguration", flowOwner, config) - JteBlockWrapper jte = (config.getConfig().jte ?: [:]) as JteBlockWrapper + JteBlockWrapper jte = config.jteBlockWrapper TemplateBinding templateBinding = new TemplateBinding(flowOwner, jte.permissive_initialization) invoke("injectPrimitives", flowOwner, config, templateBinding) invoke("validateBinding", flowOwner, config, templateBinding) From 6a69ebdff9b6e94cb16f09e2ba7f4052bc482c2a Mon Sep 17 00:00:00 2001 From: Carlos OKieffe Date: Mon, 23 Nov 2020 14:09:26 -0500 Subject: [PATCH 10/10] adding reference to default library selection on reverse library sources flag --- docs/modules/pipeline-templating/pages/configuration_files.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/pipeline-templating/pages/configuration_files.adoc b/docs/modules/pipeline-templating/pages/configuration_files.adoc index ffd34b3a9..06f708fd1 100644 --- a/docs/modules/pipeline-templating/pages/configuration_files.adoc +++ b/docs/modules/pipeline-templating/pages/configuration_files.adoc @@ -61,7 +61,7 @@ keywords{} <7> | `false` | `reverse_library_resolution` -| Normally, JTE resolves libraries based on the library sources from the highest governance tier down towards the job. This flag, if enabled, reverses the library search order +| Normally, JTE resolves libraries based on the library sources from the highest governance tier down towards the job, xref:governance:library_selection.adoc[default library selection]. This flag, if enabled, reverses the library search order | `false` |===