From 5e2939f1fd152aba3398caf1925ebab88b44914b Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Tue, 30 Jan 2018 21:36:49 +0100 Subject: [PATCH 01/44] add JaCoCo code coverage --- pom.xml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pom.xml b/pom.xml index b0725ab81..8a64802b1 100644 --- a/pom.xml +++ b/pom.xml @@ -159,6 +159,49 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.0 + + + + + + pre-unit-test + prepare-agent + + + + post-unit-test + report + + + + + + pre-integration-test + prepare-agent-integration + + + + post-integration-test + report-integration + + + From 3821b96b3f3d890011a2a87061a9f3cee62f8c19 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 31 Jan 2018 08:31:01 +0100 Subject: [PATCH 02/44] add coveralls repo token --- .coveralls.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 000000000..451d00976 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +repo_token: $COVERALLS_REPO_TOKEN From 6700e570a5e8c9e100a02208de2919eca6fa14ba Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 31 Jan 2018 09:25:59 +0100 Subject: [PATCH 03/44] add coveralls maven config --- pom.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pom.xml b/pom.xml index 8a64802b1..f9f6758d9 100644 --- a/pom.xml +++ b/pom.xml @@ -202,6 +202,24 @@ + + org.eluder.coveralls + coveralls-maven-plugin + 4.3.0 + + $COVERALLS_REPO_TOKEN + + + + post-unit-test + report + + + post-integration-test + report + + + From 0a42fe8b1d7292ca8fc2a4595b4b9dcbb98fd556 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 31 Jan 2018 10:38:55 +0100 Subject: [PATCH 04/44] add phase for jacoco & coverall report --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index f9f6758d9..424aa110a 100644 --- a/pom.xml +++ b/pom.xml @@ -180,6 +180,7 @@ post-unit-test + package report @@ -212,6 +213,7 @@ post-unit-test + package report From 4f624d5aea766063433c829390d653f34b8b7fcc Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Thu, 1 Feb 2018 09:42:53 +0100 Subject: [PATCH 05/44] add error rule as common rule --- test/groovy/MTABuildTest.groovy | 1 - test/groovy/NeoDeploymentTest.groovy | 1 - test/groovy/util/JenkinsErrorRule.groovy | 35 ++++++++++++++++++++++++ test/groovy/util/Rules.groovy | 7 +++-- 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 test/groovy/util/JenkinsErrorRule.groovy diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 100aa8969..994bec0a9 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -57,7 +57,6 @@ public class MTABuildTest extends BasePipelineTest { mtaBuildShEnv = l c() }) - helper.registerAllowedMethod('error', [String], { s -> throw new hudson.AbortException(s) }) binding.setVariable('PATH', '/usr/bin') binding.setVariable('JAVA_HOME', '/opt/java') diff --git a/test/groovy/NeoDeploymentTest.groovy b/test/groovy/NeoDeploymentTest.groovy index bb9dccd25..a86341031 100644 --- a/test/groovy/NeoDeploymentTest.groovy +++ b/test/groovy/NeoDeploymentTest.groovy @@ -47,7 +47,6 @@ class NeoDeploymentTest extends BasePipelineTest { archiveName = "archive.mtar" helper.registerAllowedMethod('dockerExecute', [Map, Closure], null) - helper.registerAllowedMethod('error', [String], { s -> throw new AbortException(s) }) helper.registerAllowedMethod('fileExists', [String], { s -> return new File(workspacePath, s).exists() }) helper.registerAllowedMethod('usernamePassword', [Map], { m -> return m }) helper.registerAllowedMethod('withCredentials', [List, Closure], { l, c -> diff --git a/test/groovy/util/JenkinsErrorRule.groovy b/test/groovy/util/JenkinsErrorRule.groovy new file mode 100644 index 000000000..52809fc67 --- /dev/null +++ b/test/groovy/util/JenkinsErrorRule.groovy @@ -0,0 +1,35 @@ +package util + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +class JenkinsErrorRule implements TestRule { + + final BasePipelineTest testInstance + + + JenkinsErrorRule(BasePipelineTest testInstance) { + this.testInstance = testInstance + } + + @Override + Statement apply(Statement base, Description description) { + return statement(base) + } + + private Statement statement(final Statement base) { + return new Statement() { + @Override + void evaluate() throws Throwable { + + testInstance.helper.registerAllowedMethod('error', [String], { + s -> throw new hudson.AbortException(s) + }) + + base.evaluate() + } + } + } +} diff --git a/test/groovy/util/Rules.groovy b/test/groovy/util/Rules.groovy index d009d2576..e9c5791de 100644 --- a/test/groovy/util/Rules.groovy +++ b/test/groovy/util/Rules.groovy @@ -1,8 +1,8 @@ -package util; +package util -import org.junit.rules.RuleChain; +import org.junit.rules.RuleChain -import com.lesfurets.jenkins.unit.BasePipelineTest; +import com.lesfurets.jenkins.unit.BasePipelineTest import com.lesfurets.jenkins.unit.global.lib.LibraryConfiguration public class Rules { @@ -15,5 +15,6 @@ public class Rules { return RuleChain.outerRule(new JenkinsSetupRule(testCase, libConfig)) .around(new JenkinsReadYamlRule(testCase)) .around(new JenkinsResetDefaultCacheRule()) + .around(new JenkinsErrorRule(testCase)) } } From d7cd626a08da79c2984e56396174acff39d9b95d Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Thu, 1 Feb 2018 10:54:18 +0100 Subject: [PATCH 06/44] add slack notification --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index bf129433c..7536be168 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,6 @@ cache: directories: - $HOME/.m2 - $HOME/.cache/pip +notifications: + slack: + secure: tVAUbZgVBx/vkGrnISjtsmtbtUnjRcGRidphqSvSMBZYqJvP7xREcKcdG2FoFUuHXgConN6SBlbKk752+xZkrt8t9F5A+kaJJhIqKtq+qGmxZX2UBCJz31jlHrNyprZtUeQnOSOlfJuN8p6VkGCQqefKmE6uLV67sUrkDAms36e+Dx0juxkB0sC34JwWN0YWDwa3cAysorENYsBubcEE+hFd0PHlnP+jap0o1wpOQ1d6XMszm6Ce0ZE+jSBvSvVuHJbxhiPT+Mda+LtxVE2Wjwal18bdcmOR3hZM0MKwxALWWmJ7q3Fs2Zw2fSEYa+rmZDr+gdhsqUjiMRQcjwpGPrD4Rjwm1vR+y7+9Ox3J6sVcZQUj9zqZIUp5lNnvOCQ8vD5IYRFqcrpgGypboMyx+YuE4uODgP+lEzuzNC36nfY4dZNCgEFq4c9QwTRa0mwaeqHRqkQ9wL2to8XBSuWXUwbNyFwQ5Mf7FzmmiuuBWXJVECMUR5J3PMiYdYqi1Sas95a5txHiuySBB4Y2SCwcrCOAANnDNME5TplqDxczzPTFS3WIGCKnG0vh+byiqXS9qNZhht4K7s+0EUScOB1QDbWUMULr+ZXjp0en6sWrh4SkUWdvVygt8zFUf+9B+y+MAZF56AK12HDc2C36g66XJx6c2H1a9U2JgE6rSrOsJ6c= From 2caf0db181f5e9bf8995d642f7f8433dbf56365c Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Thu, 1 Feb 2018 11:05:50 +0100 Subject: [PATCH 07/44] change notification secret --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7536be168..78dcbb7ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ cache: - $HOME/.cache/pip notifications: slack: - secure: tVAUbZgVBx/vkGrnISjtsmtbtUnjRcGRidphqSvSMBZYqJvP7xREcKcdG2FoFUuHXgConN6SBlbKk752+xZkrt8t9F5A+kaJJhIqKtq+qGmxZX2UBCJz31jlHrNyprZtUeQnOSOlfJuN8p6VkGCQqefKmE6uLV67sUrkDAms36e+Dx0juxkB0sC34JwWN0YWDwa3cAysorENYsBubcEE+hFd0PHlnP+jap0o1wpOQ1d6XMszm6Ce0ZE+jSBvSvVuHJbxhiPT+Mda+LtxVE2Wjwal18bdcmOR3hZM0MKwxALWWmJ7q3Fs2Zw2fSEYa+rmZDr+gdhsqUjiMRQcjwpGPrD4Rjwm1vR+y7+9Ox3J6sVcZQUj9zqZIUp5lNnvOCQ8vD5IYRFqcrpgGypboMyx+YuE4uODgP+lEzuzNC36nfY4dZNCgEFq4c9QwTRa0mwaeqHRqkQ9wL2to8XBSuWXUwbNyFwQ5Mf7FzmmiuuBWXJVECMUR5J3PMiYdYqi1Sas95a5txHiuySBB4Y2SCwcrCOAANnDNME5TplqDxczzPTFS3WIGCKnG0vh+byiqXS9qNZhht4K7s+0EUScOB1QDbWUMULr+ZXjp0en6sWrh4SkUWdvVygt8zFUf+9B+y+MAZF56AK12HDc2C36g66XJx6c2H1a9U2JgE6rSrOsJ6c= + secure: Dc+bIVXZALNlye4lp/Ks2kX0Vx0Ocqpa+ho5MTfjk5LVW6Un+8b2dlB9LYAKQB2ohEfl66Cc+7PpuXee1t6UxirSS33EU3CTBBRbPyf9BwOBtV4IfSfZiEmXBFzkNC0JAp+v/viw+2zTieE/qxL2XCwbPBpGMD/siIHjpoXsyJ8oy8FPfdVXEStiek2RU6DbPi2YtNYRDii3opiue8CqVMDTrOezqfdEzJMpUbIJqdWJw+z4dleSsdNpb40u/urrgQkIjmoYCu6LnWnL7xYJmUgDIihgGW3Ozm/W1Hnzsy73aTfSDJrT7deQw/NHO0yL2Pcvyl0V+Vg1IIamBAll8mwLSlxa3QuAiKwZLLgyL3v7Ukr7iZWrf9cWEsLaFMs/kj0swAJcRjh/ZX2S5zPnAFIyI3wyVlfkGlff73NaBujtA5mZMA9Sas2I/AGKSzeWO4dqa2FeMifk0x/QIj7xXwyGOdwQwFBBbdq7QVm+6px1I+wQH0k0j8Q7xF5BT68EYHLcZLv9jUFHz/dM3CdFYPu6fSh6vYjMuSKKsOsa5ABBXx94BUZGI37zqjUbmp1Pu1sYsUQWH+a3zX/3NNsNAO0hWcgvCMkWET/3eog1sQZyxesqFCaoStgg/0rpB2AduJFCItc41+kkoT4EJeVC2ZeEQAE2jRIEoEvg0Im4W1M= From 0dbd79aa9a9f5fb0c9b966d5e0b1023a032f3fbf Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Thu, 1 Feb 2018 11:06:52 +0100 Subject: [PATCH 08/44] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 78dcbb7ac..69a77c501 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ cache: - $HOME/.cache/pip notifications: slack: - secure: Dc+bIVXZALNlye4lp/Ks2kX0Vx0Ocqpa+ho5MTfjk5LVW6Un+8b2dlB9LYAKQB2ohEfl66Cc+7PpuXee1t6UxirSS33EU3CTBBRbPyf9BwOBtV4IfSfZiEmXBFzkNC0JAp+v/viw+2zTieE/qxL2XCwbPBpGMD/siIHjpoXsyJ8oy8FPfdVXEStiek2RU6DbPi2YtNYRDii3opiue8CqVMDTrOezqfdEzJMpUbIJqdWJw+z4dleSsdNpb40u/urrgQkIjmoYCu6LnWnL7xYJmUgDIihgGW3Ozm/W1Hnzsy73aTfSDJrT7deQw/NHO0yL2Pcvyl0V+Vg1IIamBAll8mwLSlxa3QuAiKwZLLgyL3v7Ukr7iZWrf9cWEsLaFMs/kj0swAJcRjh/ZX2S5zPnAFIyI3wyVlfkGlff73NaBujtA5mZMA9Sas2I/AGKSzeWO4dqa2FeMifk0x/QIj7xXwyGOdwQwFBBbdq7QVm+6px1I+wQH0k0j8Q7xF5BT68EYHLcZLv9jUFHz/dM3CdFYPu6fSh6vYjMuSKKsOsa5ABBXx94BUZGI37zqjUbmp1Pu1sYsUQWH+a3zX/3NNsNAO0hWcgvCMkWET/3eog1sQZyxesqFCaoStgg/0rpB2AduJFCItc41+kkoT4EJeVC2ZeEQAE2jRIEoEvg0Im4W1M= + secure: jViT5eaOggeh0//G2kLKLgntSsL4QAc5VeduWtpjO3VyyMx84h5tZMs4mhSkeK6UT8Ps+xDYbArkaipf0wJ/yyqxDfxr2Fal4e0cJJl/LKBnIHBSl5MuIGR9qrlH/tXg5NjTCTtkayDj8GZqaE+YOatK85gT3SAx3IA/kp5l0FabZTrzdvpWs7mJSNSPU9Qm97Vp6/kJxdDDMo1HOUQ15uxNj1CxusCwBvtWbtzA8D0mRzEGAdpLc5BUZGNQQaQW69M4EiWzLIRBxPezxfmvQUjkS/LNZH9HZnr+r6EE6YzE279T7nq1o1wjjRl/m+Jl2uY3/hXclwyLEyJxfPlfzBt7/C0GXEnQ4d0Ci2lAuoMNyr4r7kFvjvmPCbkSOOaGwowRTbgKbIcqlrW3e2B0CxunhFy+/Vvg9ThgeDOQwn+gLQVEdAlJn0bnEZ6KMx+jyFN8AerqxS2YWElV3TAAUWoPfTfAf8gM1xxjOTqYsHWqdljVtD4s7ZjkENc0IBPIhIYaWajtCILoikC5InCtCwx5BQIkKur08M7ntuhJTWv/g0R2/JJsqT1fTLY1+r3j+mkyi786n0zvPYhnEwaxS6fLe+ndpUkSvD1sgdgdrZCSnJ3p44TJJzVbFAYGfoxbBpIGUSTxQzbvs3NrNSXmPpMdpKSJykgCBm/XZZNJ/KU= From 864f27d129a2d0eff8efe61f09b219633d185a22 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Thu, 1 Feb 2018 13:01:00 +0100 Subject: [PATCH 09/44] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 69a77c501..5c4a2cffd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ cache: - $HOME/.cache/pip notifications: slack: - secure: jViT5eaOggeh0//G2kLKLgntSsL4QAc5VeduWtpjO3VyyMx84h5tZMs4mhSkeK6UT8Ps+xDYbArkaipf0wJ/yyqxDfxr2Fal4e0cJJl/LKBnIHBSl5MuIGR9qrlH/tXg5NjTCTtkayDj8GZqaE+YOatK85gT3SAx3IA/kp5l0FabZTrzdvpWs7mJSNSPU9Qm97Vp6/kJxdDDMo1HOUQ15uxNj1CxusCwBvtWbtzA8D0mRzEGAdpLc5BUZGNQQaQW69M4EiWzLIRBxPezxfmvQUjkS/LNZH9HZnr+r6EE6YzE279T7nq1o1wjjRl/m+Jl2uY3/hXclwyLEyJxfPlfzBt7/C0GXEnQ4d0Ci2lAuoMNyr4r7kFvjvmPCbkSOOaGwowRTbgKbIcqlrW3e2B0CxunhFy+/Vvg9ThgeDOQwn+gLQVEdAlJn0bnEZ6KMx+jyFN8AerqxS2YWElV3TAAUWoPfTfAf8gM1xxjOTqYsHWqdljVtD4s7ZjkENc0IBPIhIYaWajtCILoikC5InCtCwx5BQIkKur08M7ntuhJTWv/g0R2/JJsqT1fTLY1+r3j+mkyi786n0zvPYhnEwaxS6fLe+ndpUkSvD1sgdgdrZCSnJ3p44TJJzVbFAYGfoxbBpIGUSTxQzbvs3NrNSXmPpMdpKSJykgCBm/XZZNJ/KU= + secure: UYzfd4QYLtAX39r8LzV1dYp7cKMhYRRjI/xswMEkR+RgdMWxVPPH3kcsNLwkdNGSPn1b8Aidz8YLss9JolrepWjwI283dK8EUthZAOw03+PmL5X/3nOJ7aGv0sxwYqF5ypltBrerTf6jtPUTcQdtao+0O8bgnzShc6nWWE4MLXonjOm1pZLRUo81un+0bzm8C2ABIeHC6xuZCRycXP5u1mW1nDLK3900uY1rxIDTSZKEzA0IzLQhE9uROvI1r48fW8cKJQQjMMO5PPorq+0eDl2YTE8rQr9ldvuRE7A/ubsOQR0N5F8iAv1JTZXuXGt62fw6eKDQ1h94suEk7X+baV0EwlfhsHXcI1MxRFwxNSr9k1WaVFfA4TrM8XYBAcW3JGRA51ZK3q4EcjpuxpupaA7kZDtH53W7ePzH2TIp6yknln1q+yfcsP7cGv38sSKpKwOyMgAPRElkZzcoo31kw/PLzKPXYJEovRqx/0lWzczbFSscsroNaGCavC02++bUnyUXW2W+PG4gDSBFVZjtrvTPKnZ6DpHXV97x6xC/CzyhFj/Nf+ao/J9IIfocnc4vXJojwS550KIvM7xCDJwa/+29dajj2l6dQqrcOe3UT3O5UGU9I0KkGEDMfkLOD71eRy58qiYz3y953e52DvvzWQJbvfuk8ubMO+Fmn4GyRz8= From 41e85c035c55db8be45fe6dc4a325fffd597c9e3 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Thu, 1 Feb 2018 12:16:21 +0100 Subject: [PATCH 10/44] extend config merger to handle deep config structures --- src/com/sap/piper/ConfigurationMerger.groovy | 30 +++++++++++++++++++ .../sap/piper/ConfigurationMergerTest.groovy | 13 ++++++++ 2 files changed, 43 insertions(+) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 17e9321f6..cf1513313 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -12,6 +12,22 @@ class ConfigurationMerger { return merged } + @NonCPS + def static merge(Map configs, Map configKeys, Map defaults = [:]) { + Map merged = [:] + merged.putAll(defaults) + if(configs != null) + for(String key : configKeys.keySet()){ + if(isMap(configKeys[key])){ + merged[key] = merge(configs[key], configKeys[key], defaults[key]) + }else{ + if(configs[key] != null) + merged[key] = configs[key] + } + } + return merged + } + @NonCPS def static merge(Map parameters, List parameterKeys, Map configurationMap, List configurationKeys, Map defaults=[:]){ Map merged = merge(configurationMap, configurationKeys, defaults) @@ -20,6 +36,15 @@ class ConfigurationMerger { return merged } + @NonCPS + def static mergeDeepStructure(Map parameters, Map parameterKeys, Map configuration, Map configurationKeys, Map defaults=[:]){ + Map merged = [:] + merged.putAll(defaults) + merged = merge(configuration, configurationKeys, merged) + merged = merge(parameters, parameterKeys, merged) + return merged + } + @NonCPS def static mergeWithPipelineData(Map parameters, List parameterKeys, Map pipelineDataMap, @@ -50,4 +75,9 @@ class ConfigurationMerger { return filteredMap.subMap(keys) } + + @NonCPS + def static isMap(object){ + return object in Map + } } diff --git a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy index 544f51588..9529f5e04 100644 --- a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy +++ b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy @@ -39,4 +39,17 @@ class ConfigurationMergerTest { Assert.assertEquals('', merged.flags) Assert.assertEquals('1.2.3', merged.artifactVersion) } + + @Test + void testMergeDeepStructure(){ + Map defaults = [fruits: [apples: 1, oranges: 10, bananaaas: 0]] + Map configuration = [fruits: [bananaaas: 50, cucumbers: 1000]] + Map configurationKeys = [fruits: [apples: null, oranges: null, bananaaas: null]] + Map parameters = [fruits: [apples: 18]] + Map parameterKeys = [fruits: [apples: null, oranges: null, bananaaas: null]] + Map merged = ConfigurationMerger.mergeDeepStructure(parameters, parameterKeys, configuration, configurationKeys, defaults) + Assert.assertEquals(50, merged.fruits.bananaaas) + Assert.assertEquals(18, merged.fruits.apples) + Assert.assertEquals(null, merged.fruits.cucumbers) + } } From 192d96d08248e6dd6edb6b702a72ecd2dcec0878 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Fri, 2 Feb 2018 09:30:31 +0100 Subject: [PATCH 11/44] add MapUtils --- src/com/sap/piper/ConfigurationMerger.groovy | 9 +++------ src/com/sap/piper/MapUtils.groovy | 10 ++++++++++ test/groovy/com/sap/piper/MapUtilsTest.groovy | 13 +++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 src/com/sap/piper/MapUtils.groovy create mode 100644 test/groovy/com/sap/piper/MapUtilsTest.groovy diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index cf1513313..172f51785 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -2,6 +2,8 @@ package com.sap.piper import com.cloudbees.groovy.cps.NonCPS +import com.sap.piper.MapUtils + class ConfigurationMerger { @NonCPS def static merge(Map configs, List configKeys, Map defaults=[:]) { @@ -18,7 +20,7 @@ class ConfigurationMerger { merged.putAll(defaults) if(configs != null) for(String key : configKeys.keySet()){ - if(isMap(configKeys[key])){ + if(MapUtils.isMap(configKeys[key])){ merged[key] = merge(configs[key], configKeys[key], defaults[key]) }else{ if(configs[key] != null) @@ -75,9 +77,4 @@ class ConfigurationMerger { return filteredMap.subMap(keys) } - - @NonCPS - def static isMap(object){ - return object in Map - } } diff --git a/src/com/sap/piper/MapUtils.groovy b/src/com/sap/piper/MapUtils.groovy new file mode 100644 index 000000000..e42b5aaff --- /dev/null +++ b/src/com/sap/piper/MapUtils.groovy @@ -0,0 +1,10 @@ +package com.sap.piper + +import com.cloudbees.groovy.cps.NonCPS + +class MapUtils implements Serializable { + @NonCPS + static isMap(object){ + return object in Map + } +} diff --git a/test/groovy/com/sap/piper/MapUtilsTest.groovy b/test/groovy/com/sap/piper/MapUtilsTest.groovy new file mode 100644 index 000000000..0cc7f9e67 --- /dev/null +++ b/test/groovy/com/sap/piper/MapUtilsTest.groovy @@ -0,0 +1,13 @@ +package com.sap.piper + +import org.junit.Assert +import org.junit.Test + +class MapUtilsTest { + + @Test + void testIsMap(){ + Assert.assertTrue('Map is not recognized as Map', MapUtils.isMap([:])) + Assert.assertTrue('String is recognized as Map', !MapUtils.isMap('I am not a Map')) + } +} From 8568ebbc687dbecc456dc8b8988a0058d034ea32 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Sun, 4 Feb 2018 08:40:50 +0100 Subject: [PATCH 12/44] Merge commit '0a42fe8b1d7292ca8fc2a4595b4b9dcbb98fd556' into jacocoCodeCoverage # Conflicts: # pom.xml --- pom.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pom.xml b/pom.xml index 424aa110a..5dbbeb468 100644 --- a/pom.xml +++ b/pom.xml @@ -207,20 +207,6 @@ org.eluder.coveralls coveralls-maven-plugin 4.3.0 - - $COVERALLS_REPO_TOKEN - - - - post-unit-test - package - report - - - post-integration-test - report - - From efe116c0285f565a774a44f69d89b029e27ebfe9 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Sun, 4 Feb 2018 08:41:31 +0100 Subject: [PATCH 13/44] add after success to travis config --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index bf129433c..c151a9a7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,5 @@ cache: directories: - $HOME/.m2 - $HOME/.cache/pip +after_success: + - mvn clean test -DrepoToken=$COVERALL_REPO_TOKEN jacoco:report coveralls:report From 1610d163e2b80863d70cbef290efb3014996141e Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Sun, 4 Feb 2018 09:16:29 +0100 Subject: [PATCH 14/44] remove unused coveralls config file --- .coveralls.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index 451d00976..000000000 --- a/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -repo_token: $COVERALLS_REPO_TOKEN From baf231ce590918d6a81e400a7cf8b62b7efd4497 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Sun, 4 Feb 2018 09:16:38 +0100 Subject: [PATCH 15/44] execute tests only once --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c151a9a7a..268f2be41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,4 @@ cache: - $HOME/.m2 - $HOME/.cache/pip after_success: - - mvn clean test -DrepoToken=$COVERALL_REPO_TOKEN jacoco:report coveralls:report + - mvn -DrepoToken=$COVERALL_REPO_TOKEN jacoco:report coveralls:report From fc2cb4e72255ee6b7835c425b7bb01cb9246b8b8 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Sun, 4 Feb 2018 09:27:59 +0100 Subject: [PATCH 16/44] add coverage badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c323a3a15..044868b4c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Build Status](https://travis-ci.org/SAP/jenkins-library.svg?branch=master)](https://travis-ci.org/SAP/jenkins-library) +[![Coverage Status](https://coveralls.io/repos/github/SAP/jenkins-library/badge.svg?branch=jacocoCodeCoverage)](https://coveralls.io/github/SAP/jenkins-library?branch=jacocoCodeCoverage) # Description @@ -47,7 +48,7 @@ provided pipeline library. # Requirements - * Java Runtime Environment 8 + * Java Runtime Environment 8 * Installation of Jenkins v 2.60.3 or higher running on Linux. We tested with debian-stretch. * Jenkins Plugins installed as described in the [Required From 308b566607be9b4cb87270b4403f7043e9066f0b Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Mon, 5 Feb 2018 08:32:07 +0100 Subject: [PATCH 17/44] correct env variable name --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 268f2be41..98ce5dac3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,4 @@ cache: - $HOME/.m2 - $HOME/.cache/pip after_success: - - mvn -DrepoToken=$COVERALL_REPO_TOKEN jacoco:report coveralls:report + - mvn -DrepoToken=$COVERALLS_REPO_TOKEN jacoco:report coveralls:report From adc77a66abe9a642b69732b63a7b5a4a99fbacff Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Mon, 5 Feb 2018 12:59:35 +0100 Subject: [PATCH 18/44] use full qualified plugin names --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e3061ef06..57e11c242 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ cache: - $HOME/.m2 - $HOME/.cache/pip after_success: - - mvn -DrepoToken=$COVERALLS_REPO_TOKEN jacoco:report coveralls:report + - mvn -DrepoToken=$COVERALLS_REPO_TOKEN org.jacoco:jacoco-maven-plugin:report org.eluder.coveralls:coveralls-maven-plugin:report notifications: slack: secure: UYzfd4QYLtAX39r8LzV1dYp7cKMhYRRjI/xswMEkR+RgdMWxVPPH3kcsNLwkdNGSPn1b8Aidz8YLss9JolrepWjwI283dK8EUthZAOw03+PmL5X/3nOJ7aGv0sxwYqF5ypltBrerTf6jtPUTcQdtao+0O8bgnzShc6nWWE4MLXonjOm1pZLRUo81un+0bzm8C2ABIeHC6xuZCRycXP5u1mW1nDLK3900uY1rxIDTSZKEzA0IzLQhE9uROvI1r48fW8cKJQQjMMO5PPorq+0eDl2YTE8rQr9ldvuRE7A/ubsOQR0N5F8iAv1JTZXuXGt62fw6eKDQ1h94suEk7X+baV0EwlfhsHXcI1MxRFwxNSr9k1WaVFfA4TrM8XYBAcW3JGRA51ZK3q4EcjpuxpupaA7kZDtH53W7ePzH2TIp6yknln1q+yfcsP7cGv38sSKpKwOyMgAPRElkZzcoo31kw/PLzKPXYJEovRqx/0lWzczbFSscsroNaGCavC02++bUnyUXW2W+PG4gDSBFVZjtrvTPKnZ6DpHXV97x6xC/CzyhFj/Nf+ao/J9IIfocnc4vXJojwS550KIvM7xCDJwa/+29dajj2l6dQqrcOe3UT3O5UGU9I0KkGEDMfkLOD71eRy58qiYz3y953e52DvvzWQJbvfuk8ubMO+Fmn4GyRz8= From eab6716797aa45deddfd881107dec33204443611 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Mon, 5 Feb 2018 19:32:50 +0100 Subject: [PATCH 19/44] use default map as base for merge (iteration) --- src/com/sap/piper/ConfigurationMerger.groovy | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 172f51785..2210e76d7 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -19,14 +19,11 @@ class ConfigurationMerger { Map merged = [:] merged.putAll(defaults) if(configs != null) - for(String key : configKeys.keySet()){ - if(MapUtils.isMap(configKeys[key])){ + for(String key : defaults.keySet()) + if(MapUtils.isMap(defaults[key])) merged[key] = merge(configs[key], configKeys[key], defaults[key]) - }else{ - if(configs[key] != null) - merged[key] = configs[key] - } - } + else + merged[key] = configs[key] return merged } From 20cbbfc26cb409b7a6030d32f9e684fd121f705a Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Mon, 5 Feb 2018 19:39:13 +0100 Subject: [PATCH 20/44] filter by keyset and null --- src/com/sap/piper/ConfigurationMerger.groovy | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 2210e76d7..21d4e1bb1 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -18,12 +18,13 @@ class ConfigurationMerger { def static merge(Map configs, Map configKeys, Map defaults = [:]) { Map merged = [:] merged.putAll(defaults) - if(configs != null) + if(configs != null && configKeys) for(String key : defaults.keySet()) - if(MapUtils.isMap(defaults[key])) - merged[key] = merge(configs[key], configKeys[key], defaults[key]) - else - merged[key] = configs[key] + if(configKeys.keySet().contains(key)) + if(MapUtils.isMap(defaults[key])) + merged[key] = merge(configs[key], configKeys[key], defaults[key]) + else if(configs[key] != null) + merged[key] = configs[key] return merged } From 88d09eee63f7655e664f75d77c474e4db8e64391 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Mon, 5 Feb 2018 19:54:04 +0100 Subject: [PATCH 21/44] filter by keyset --- src/com/sap/piper/ConfigurationMerger.groovy | 14 ++++++++------ .../com/sap/piper/ConfigurationMergerTest.groovy | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 21d4e1bb1..1a5c0b5f0 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -18,13 +18,15 @@ class ConfigurationMerger { def static merge(Map configs, Map configKeys, Map defaults = [:]) { Map merged = [:] merged.putAll(defaults) - if(configs != null && configKeys) + + if(configs != null && configKeys){ + configs = configs.subMap(configKeys.keySet()) for(String key : defaults.keySet()) - if(configKeys.keySet().contains(key)) - if(MapUtils.isMap(defaults[key])) - merged[key] = merge(configs[key], configKeys[key], defaults[key]) - else if(configs[key] != null) - merged[key] = configs[key] + if(MapUtils.isMap(defaults[key])) + merged[key] = merge(configs[key], configKeys[key], defaults[key]) + else if(configs[key] != null) + merged[key] = configs[key] + } return merged } diff --git a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy index 9529f5e04..af15e18de 100644 --- a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy +++ b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy @@ -50,6 +50,7 @@ class ConfigurationMergerTest { Map merged = ConfigurationMerger.mergeDeepStructure(parameters, parameterKeys, configuration, configurationKeys, defaults) Assert.assertEquals(50, merged.fruits.bananaaas) Assert.assertEquals(18, merged.fruits.apples) + Assert.assertEquals(10, merged.fruits.oranges) Assert.assertEquals(null, merged.fruits.cucumbers) } } From edf3deaa9c78c172c4cc51b67b61e3e9ff4be176 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Mon, 5 Feb 2018 20:31:30 +0100 Subject: [PATCH 22/44] rename method --- src/com/sap/piper/ConfigurationMerger.groovy | 11 +++++++---- .../com/sap/piper/ConfigurationMergerTest.groovy | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 1a5c0b5f0..60150eac0 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -39,10 +39,13 @@ class ConfigurationMerger { } @NonCPS - def static mergeDeepStructure(Map parameters, Map parameterKeys, Map configuration, Map configurationKeys, Map defaults=[:]){ - Map merged = [:] - merged.putAll(defaults) - merged = merge(configuration, configurationKeys, merged) + def static merge( + Map parameters, Map parameterKeys, + Map configuration, Map configurationKeys, + Map defaults=[:] + ){ + Map merged + merged = merge(configuration, configurationKeys, defaults) merged = merge(parameters, parameterKeys, merged) return merged } diff --git a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy index af15e18de..f58050f8f 100644 --- a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy +++ b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy @@ -47,7 +47,7 @@ class ConfigurationMergerTest { Map configurationKeys = [fruits: [apples: null, oranges: null, bananaaas: null]] Map parameters = [fruits: [apples: 18]] Map parameterKeys = [fruits: [apples: null, oranges: null, bananaaas: null]] - Map merged = ConfigurationMerger.mergeDeepStructure(parameters, parameterKeys, configuration, configurationKeys, defaults) + Map merged = ConfigurationMerger.merge(parameters, parameterKeys, configuration, configurationKeys, defaults) Assert.assertEquals(50, merged.fruits.bananaaas) Assert.assertEquals(18, merged.fruits.apples) Assert.assertEquals(10, merged.fruits.oranges) From 0566cab5db134f7fc47bbd2dd6d51f88280f384f Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Tue, 6 Feb 2018 08:37:56 +0100 Subject: [PATCH 23/44] extend map helper --- src/com/sap/piper/MapUtils.groovy | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/com/sap/piper/MapUtils.groovy b/src/com/sap/piper/MapUtils.groovy index e42b5aaff..dccfea6f9 100644 --- a/src/com/sap/piper/MapUtils.groovy +++ b/src/com/sap/piper/MapUtils.groovy @@ -7,4 +7,13 @@ class MapUtils implements Serializable { static isMap(object){ return object in Map } + + @NonCPS + static fromList(List list){ + Map map = [:] + for(String key : list){ + map.put(key, null) + } + return map + } } From 6e3bfac5c88eb5c3c1292b53984950eb55baea44 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Tue, 6 Feb 2018 08:41:28 +0100 Subject: [PATCH 24/44] consolidate marge methods --- src/com/sap/piper/ConfigurationMerger.groovy | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 60150eac0..e421ad2a7 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -7,11 +7,7 @@ import com.sap.piper.MapUtils class ConfigurationMerger { @NonCPS def static merge(Map configs, List configKeys, Map defaults=[:]) { - Map merged = [:] - merged.putAll(defaults) - merged.putAll(filterByKeyAndNull(configs, configKeys)) - - return merged + return merge(configs, MapUtils.fromList(configKeys), defaults) } @NonCPS @@ -31,11 +27,15 @@ class ConfigurationMerger { } @NonCPS - def static merge(Map parameters, List parameterKeys, Map configurationMap, List configurationKeys, Map defaults=[:]){ - Map merged = merge(configurationMap, configurationKeys, defaults) - merged.putAll(filterByKeyAndNull(parameters, parameterKeys)) - - return merged + def static merge( + Map parameters, List parameterKeys, + Map configuration, List configurationKeys, + Map defaults=[:] + ){ + return merge( + parameters, MapUtils.fromList(parameterKeys), + configuration, MapUtils.fromList(configurationKeys), + defaults) } @NonCPS From 6cd4a9076a3912cc2c9954bac32de1aa6ee8ffb5 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Tue, 6 Feb 2018 09:57:52 +0100 Subject: [PATCH 25/44] correct docs command return to workspace --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bf129433c..55e5cceb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ install: - pip install --user mkdocs mkdocs-material script: - mvn test -B -- if [[ "${TRAVIS_PULL_REQUEST}" != "false" ]]; then cd documentation && mkdocs build --clean --verbose --strict; fi; +- if [[ "${TRAVIS_PULL_REQUEST}" != "false" ]]; then cd documentation && mkdocs build --clean --verbose --strict && cd ..; fi; cache: directories: - $HOME/.m2 From 2a6c0d5f347e2fc2c54dd55093d004060c139d35 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Tue, 6 Feb 2018 13:44:03 +0100 Subject: [PATCH 26/44] use key map to iterate over parameters, not defaults key map --- src/com/sap/piper/ConfigurationMerger.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index e421ad2a7..4663ce7ae 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -17,8 +17,8 @@ class ConfigurationMerger { if(configs != null && configKeys){ configs = configs.subMap(configKeys.keySet()) - for(String key : defaults.keySet()) - if(MapUtils.isMap(defaults[key])) + for(String key : configKeys.keySet()) + if(MapUtils.isMap(configKeys[key])) merged[key] = merge(configs[key], configKeys[key], defaults[key]) else if(configs[key] != null) merged[key] = configs[key] From 9cb6f5367860d3b22b1dc5d9f40ee0ac76fe9461 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Wed, 31 Jan 2018 17:35:06 +0100 Subject: [PATCH 27/44] remove unused code --- test/groovy/MTABuildTest.groovy | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 994bec0a9..1418d3527 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -30,8 +30,6 @@ public class MTABuildTest extends BasePipelineTest { def currentDir - def otherDir - def mtaBuildShEnv def mtaBuildScript def cpe @@ -40,26 +38,14 @@ public class MTABuildTest extends BasePipelineTest { void init() { currentDir = tmp.newFolder().toURI().getPath()[0..-2] //omit final '/' - otherDir = tmp.newFolder().toURI().getPath()[0..-2] //omit final '/' helper.registerAllowedMethod('readYaml', [Map], { m -> return new Yaml().load((m.file as File).text) }) - helper.registerAllowedMethod("dir", [String, Closure], { - s, c -> - currentDir = "${currentDir}/${s}" - c() - }) helper.registerAllowedMethod('pwd', [], { currentDir } ) - helper.registerAllowedMethod("withEnv", [List.class, Closure.class], - { l, c -> - mtaBuildShEnv = l - c() - }) binding.setVariable('PATH', '/usr/bin') - binding.setVariable('JAVA_HOME', '/opt/java') binding.setVariable('env', [:]) mtaBuildScript = loadScript("mtaBuild.groovy").mtaBuild From 4aa4a1d2f54bf0857c322fd01bf51ac88410a178 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 11:49:53 +0100 Subject: [PATCH 28/44] remove unused cpe --- test/groovy/MTABuildTest.groovy | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 1418d3527..3d42b3340 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -60,8 +60,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << defaultMtaYaml() - def mtarFilePath = mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], - buildTarget: 'NEO') + def mtarFilePath = mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ @@ -113,7 +112,7 @@ public class MTABuildTest extends BasePipelineTest { helper.registerAllowedMethod('pwd', [], { newDirPath } ) - def mtarFilePath = mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], buildTarget: 'NEO') + def mtarFilePath = mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/newDir\/mta.yaml"$/ @@ -131,7 +130,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << defaultMtaYaml() - def mtarFilePath = mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], buildTarget: 'NEO') + def mtarFilePath = mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ @@ -168,8 +167,7 @@ public class MTABuildTest extends BasePipelineTest { public void noMtaPresentTest(){ thrown.expect(FileNotFoundException) - mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], - buildTarget: 'NEO') + mtaBuildScript.call(buildTarget: 'NEO') } @@ -180,8 +178,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << badMtaYaml() - mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], - buildTarget: 'NEO') + mtaBuildScript.call(buildTarget: 'NEO') } @@ -192,8 +189,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << noIdMtaYaml() - mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], - buildTarget: 'NEO') + mtaBuildScript.call(buildTarget: 'NEO') } @@ -204,7 +200,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call(script: [commonPipelineEnvironment: cpe]) + mtaBuildScript.call() } private defaultMtaYaml(){ From 7f3f76a8ad23d3a4b9f32bbd5c087474b7374603 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 11:54:53 +0100 Subject: [PATCH 29/44] remove duplicated mtarFilePath assertions mtarFile Path must be checked only when it is in the scope of the unit test. --- test/groovy/MTABuildTest.groovy | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 3d42b3340..01c35e112 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -60,7 +60,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << defaultMtaYaml() - def mtarFilePath = mtaBuildScript.call(buildTarget: 'NEO') + mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ @@ -68,8 +68,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') - assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" - assert jlr.log.contains( "[mtaBuild] MTA JAR \"/opt/mta/mta.jar\" retrieved from environment.") } @@ -130,7 +128,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << defaultMtaYaml() - def mtarFilePath = mtaBuildScript.call(buildTarget: 'NEO') + mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ @@ -138,8 +136,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[1].contains(' -jar mta.jar --mtar ') - assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" - assert jlr.log.contains( "[mtaBuild] Using MTA JAR from current working directory." ) } @@ -149,7 +145,7 @@ public class MTABuildTest extends BasePipelineTest { new File("${currentDir}/mta.yaml") << defaultMtaYaml() - def mtarFilePath = mtaBuildScript.call(mtaJarLocation: '/mylocation/mta', buildTarget: 'NEO') + mtaBuildScript.call(mtaJarLocation: '/mylocation/mta', buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ @@ -157,8 +153,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[1].contains(' -jar /mylocation/mta/mta.jar --mtar ') - assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" - assert jlr.log.contains("[mtaBuild] MTA JAR \"/mylocation/mta/mta.jar\" retrieved from parameters.".toString()) } From 5d60bc8199071eff496d332ad41b13e764db8099 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 15:16:52 +0100 Subject: [PATCH 30/44] add environment PATH test Adds an unit test to test that the environment PATH is set and removes duplicate PATH assertions. --- test/groovy/MTABuildTest.groovy | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 01c35e112..6ef78296f 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -53,6 +53,17 @@ public class MTABuildTest extends BasePipelineTest { } + @Test + public void environmentPathTest(){ + + new File("${currentDir}/mta.yaml") << defaultMtaYaml() + + mtaBuildScript.call(buildTarget: 'NEO') + + assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") + } + + @Test public void straightForwardTest(){ @@ -64,8 +75,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") - assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') assert jlr.log.contains( "[mtaBuild] MTA JAR \"/opt/mta/mta.jar\" retrieved from environment.") @@ -86,8 +95,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") - assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" @@ -114,8 +121,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/newDir\/mta.yaml"$/ - assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") - assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') assert mtarFilePath == "${currentDir}/${newDirName}/com.mycompany.northwind.mtar" @@ -132,8 +137,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") - assert jscr.shell[1].contains(' -jar mta.jar --mtar ') assert jlr.log.contains( "[mtaBuild] Using MTA JAR from current working directory." ) @@ -149,8 +152,6 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") - assert jscr.shell[1].contains(' -jar /mylocation/mta/mta.jar --mtar ') assert jlr.log.contains("[mtaBuild] MTA JAR \"/mylocation/mta/mta.jar\" retrieved from parameters.".toString()) From 868d13749cd412d47e1f4664aca08eedce2ef465 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 15:28:16 +0100 Subject: [PATCH 31/44] add mtaJarLocation from environment test Adds a test to check if the mtaJarLocation is read from the environment and removes all duplicate assertions. --- test/groovy/MTABuildTest.groovy | 35 +++++++++++++++------------------ 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 6ef78296f..8b23f8630 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -46,7 +46,6 @@ public class MTABuildTest extends BasePipelineTest { helper.registerAllowedMethod('pwd', [], { currentDir } ) binding.setVariable('PATH', '/usr/bin') - binding.setVariable('env', [:]) mtaBuildScript = loadScript("mtaBuild.groovy").mtaBuild cpe = loadScript('commonPipelineEnvironment.groovy').commonPipelineEnvironment @@ -67,25 +66,17 @@ public class MTABuildTest extends BasePipelineTest { @Test public void straightForwardTest(){ - binding.getVariable('env')['MTA_JAR_LOCATION'] = '/opt/mta' - new File("${currentDir}/mta.yaml") << defaultMtaYaml() mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - - assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') - - assert jlr.log.contains( "[mtaBuild] MTA JAR \"/opt/mta/mta.jar\" retrieved from environment.") } @Test public void mtarFilePathFromCommonPipelineEnviromentTest(){ - binding.getVariable('env')['MTA_JAR_LOCATION'] = '/opt/mta' - new File("${currentDir}/mta.yaml") << defaultMtaYaml() mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], @@ -95,19 +86,13 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') - assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" - - assert jlr.log.contains("[mtaBuild] MTA JAR \"/opt/mta/mta.jar\" retrieved from environment.") } @Test public void mtaBuildWithSurroundingDirTest(){ - binding.getVariable('env')['MTA_JAR_LOCATION'] = '/opt/mta' - def newDirName = 'newDir' def newDirPath = "${currentDir}/${newDirName}" def newDir = new File(newDirPath) @@ -121,11 +106,7 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/newDir\/mta.yaml"$/ - assert jscr.shell[1].contains(' -jar /opt/mta/mta.jar --mtar ') - assert mtarFilePath == "${currentDir}/${newDirName}/com.mycompany.northwind.mtar" - - assert jlr.log.contains("[mtaBuild] MTA JAR \"/opt/mta/mta.jar\" retrieved from environment.") } @Test @@ -198,6 +179,22 @@ public class MTABuildTest extends BasePipelineTest { mtaBuildScript.call() } + + @Test + void mtaJarLocationFromEnvironmentTest(){ + + binding.setVariable('env', [:]) + binding.getVariable('env')['MTA_JAR_LOCATION'] = '/env/mta' + + new File("${currentDir}/mta.yaml") << defaultMtaYaml() + + mtaBuildScript.call(buildTarget: 'NEO') + + assert jscr.shell[1].contains('-jar /env/mta/mta.jar --mtar') + assert jlr.log.contains('[mtaBuild] MTA JAR "/env/mta/mta.jar" retrieved from environment.') + } + + private defaultMtaYaml(){ return ''' _schema-version: "2.0.0" From 8075157ea29f6f2eaab2b0cd245fc0ee7ec94722 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 15:30:21 +0100 Subject: [PATCH 32/44] rename mtaHome with mtaJarLocation --- test/groovy/MTABuildTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 8b23f8630..7f1ee6a14 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -110,7 +110,7 @@ public class MTABuildTest extends BasePipelineTest { } @Test - void mtaHomeNotSetTest() { + void mtaJarLocationNotSetTest() { new File("${currentDir}/mta.yaml") << defaultMtaYaml() @@ -125,7 +125,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - void mtaHomeAsParameterTest() { + void mtaJarLocationAsParameterTest() { new File("${currentDir}/mta.yaml") << defaultMtaYaml() From cafa0a703bbd16b5789d40d045464604be2a3234 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 15:39:18 +0100 Subject: [PATCH 33/44] format String as String not GString See: https://github.com/SAP/jenkins-library/blob/master/CONTRIBUTING.md#use-single-quotes-for-strings-and-constants --- test/groovy/MTABuildTest.groovy | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 7f1ee6a14..8e26c40f2 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -47,7 +47,7 @@ public class MTABuildTest extends BasePipelineTest { binding.setVariable('PATH', '/usr/bin') - mtaBuildScript = loadScript("mtaBuild.groovy").mtaBuild + mtaBuildScript = loadScript('mtaBuild.groovy').mtaBuild cpe = loadScript('commonPipelineEnvironment.groovy').commonPipelineEnvironment } @@ -59,7 +59,7 @@ public class MTABuildTest extends BasePipelineTest { mtaBuildScript.call(buildTarget: 'NEO') - assert jscr.shell[1].contains("PATH=./node_modules/.bin:/usr/bin") + assert jscr.shell[1].contains('PATH=./node_modules/.bin:/usr/bin') } @@ -120,7 +120,7 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[1].contains(' -jar mta.jar --mtar ') - assert jlr.log.contains( "[mtaBuild] Using MTA JAR from current working directory." ) + assert jlr.log.contains('[mtaBuild] Using MTA JAR from current working directory.') } @@ -135,7 +135,7 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[1].contains(' -jar /mylocation/mta/mta.jar --mtar ') - assert jlr.log.contains("[mtaBuild] MTA JAR \"/mylocation/mta/mta.jar\" retrieved from parameters.".toString()) + assert jlr.log.contains('[mtaBuild] MTA JAR "/mylocation/mta/mta.jar" retrieved from parameters.') } @@ -172,7 +172,7 @@ public class MTABuildTest extends BasePipelineTest { @Test public void noBuildTargetTest(){ thrown.expect(Exception) - thrown.expectMessage("ERROR - NO VALUE AVAILABLE FOR buildTarget") + thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTarget') new File("${currentDir}/mta.yaml") << defaultMtaYaml() From 69d0050e0c6b155090d15ab49748873091e5025b Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 16:45:24 +0100 Subject: [PATCH 34/44] remove blanks --- test/groovy/MTABuildTest.groovy | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 8e26c40f2..be1522a2d 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -200,10 +200,10 @@ public class MTABuildTest extends BasePipelineTest { _schema-version: "2.0.0" ID: "com.mycompany.northwind" version: 1.0.0 - + parameters: hcp-deployer-version: "1.0.0" - + modules: - name: "fiorinorthwind" type: html5 @@ -221,10 +221,10 @@ public class MTABuildTest extends BasePipelineTest { _schema-version: "2.0.0 ID: "com.mycompany.northwind" version: 1.0.0 - + parameters: hcp-deployer-version: "1.0.0" - + modules: - name: "fiorinorthwind" type: html5 @@ -241,10 +241,10 @@ public class MTABuildTest extends BasePipelineTest { return ''' _schema-version: "2.0.0" version: 1.0.0 - + parameters: hcp-deployer-version: "1.0.0" - + modules: - name: "fiorinorthwind" type: html5 From 436063660951417c30e128a94a77aa863286f78d Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 16:57:00 +0100 Subject: [PATCH 35/44] add sed test Removes straightForwardTest that has not a clear scope since it test all that it is tested in the other tests. Adds sed test. Removes duplicated sed assertions. --- test/groovy/MTABuildTest.groovy | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index be1522a2d..1b5886f1e 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -30,6 +30,7 @@ public class MTABuildTest extends BasePipelineTest { def currentDir + def mtaYaml def mtaBuildScript def cpe @@ -38,6 +39,8 @@ public class MTABuildTest extends BasePipelineTest { void init() { currentDir = tmp.newFolder().toURI().getPath()[0..-2] //omit final '/' + mtaYaml = new File("${currentDir}/mta.yaml") + mtaYaml << defaultMtaYaml() helper.registerAllowedMethod('readYaml', [Map], { m -> @@ -55,8 +58,6 @@ public class MTABuildTest extends BasePipelineTest { @Test public void environmentPathTest(){ - new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[1].contains('PATH=./node_modules/.bin:/usr/bin') @@ -64,9 +65,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void straightForwardTest(){ - - new File("${currentDir}/mta.yaml") << defaultMtaYaml() + public void sedTest(){ mtaBuildScript.call(buildTarget: 'NEO') @@ -77,15 +76,11 @@ public class MTABuildTest extends BasePipelineTest { @Test public void mtarFilePathFromCommonPipelineEnviromentTest(){ - new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], buildTarget: 'NEO') def mtarFilePath = cpe.getMtarFilePath() - assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" } @@ -112,12 +107,8 @@ public class MTABuildTest extends BasePipelineTest { @Test void mtaJarLocationNotSetTest() { - new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call(buildTarget: 'NEO') - assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains(' -jar mta.jar --mtar ') assert jlr.log.contains('[mtaBuild] Using MTA JAR from current working directory.') @@ -127,12 +118,8 @@ public class MTABuildTest extends BasePipelineTest { @Test void mtaJarLocationAsParameterTest() { - new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call(mtaJarLocation: '/mylocation/mta', buildTarget: 'NEO') - assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/mta.yaml"$/ - assert jscr.shell[1].contains(' -jar /mylocation/mta/mta.jar --mtar ') assert jlr.log.contains('[mtaBuild] MTA JAR "/mylocation/mta/mta.jar" retrieved from parameters.') @@ -141,6 +128,8 @@ public class MTABuildTest extends BasePipelineTest { @Test public void noMtaPresentTest(){ + + mtaYaml.delete() thrown.expect(FileNotFoundException) mtaBuildScript.call(buildTarget: 'NEO') @@ -152,7 +141,7 @@ public class MTABuildTest extends BasePipelineTest { thrown.expect(ParserException) thrown.expectMessage('while parsing a block mapping') - new File("${currentDir}/mta.yaml") << badMtaYaml() + mtaYaml.text = badMtaYaml() mtaBuildScript.call(buildTarget: 'NEO') } @@ -163,7 +152,7 @@ public class MTABuildTest extends BasePipelineTest { thrown.expect(AbortException) thrown.expectMessage("Property 'ID' not found in mta.yaml file at: '") - new File("${currentDir}/mta.yaml") << noIdMtaYaml() + mtaYaml.text = noIdMtaYaml() mtaBuildScript.call(buildTarget: 'NEO') } @@ -174,8 +163,6 @@ public class MTABuildTest extends BasePipelineTest { thrown.expect(Exception) thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTarget') - new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call() } @@ -186,8 +173,6 @@ public class MTABuildTest extends BasePipelineTest { binding.setVariable('env', [:]) binding.getVariable('env')['MTA_JAR_LOCATION'] = '/env/mta' - new File("${currentDir}/mta.yaml") << defaultMtaYaml() - mtaBuildScript.call(buildTarget: 'NEO') assert jscr.shell[1].contains('-jar /env/mta/mta.jar --mtar') From ae66a5cbcad8785e5d63d62a60d85d81c028f908 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 17:15:46 +0100 Subject: [PATCH 36/44] add new lines to keep format --- test/groovy/MTABuildTest.groovy | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 1b5886f1e..457edda13 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -104,6 +104,7 @@ public class MTABuildTest extends BasePipelineTest { assert mtarFilePath == "${currentDir}/${newDirName}/com.mycompany.northwind.mtar" } + @Test void mtaJarLocationNotSetTest() { @@ -138,6 +139,7 @@ public class MTABuildTest extends BasePipelineTest { @Test public void badMtaTest(){ + thrown.expect(ParserException) thrown.expectMessage('while parsing a block mapping') @@ -149,6 +151,7 @@ public class MTABuildTest extends BasePipelineTest { @Test public void noIdInMtaTest(){ + thrown.expect(AbortException) thrown.expectMessage("Property 'ID' not found in mta.yaml file at: '") @@ -160,6 +163,7 @@ public class MTABuildTest extends BasePipelineTest { @Test public void noBuildTargetTest(){ + thrown.expect(Exception) thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTarget') From 615f8deb1d7f23764c9939af82d8cf5bd3aea4a0 Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 17:16:53 +0100 Subject: [PATCH 37/44] add blanks to keep format --- test/groovy/MTABuildTest.groovy | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 457edda13..53cb8ba4d 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -56,7 +56,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void environmentPathTest(){ + public void environmentPathTest() { mtaBuildScript.call(buildTarget: 'NEO') @@ -65,7 +65,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void sedTest(){ + public void sedTest() { mtaBuildScript.call(buildTarget: 'NEO') @@ -74,7 +74,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void mtarFilePathFromCommonPipelineEnviromentTest(){ + public void mtarFilePathFromCommonPipelineEnviromentTest() { mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], buildTarget: 'NEO') @@ -86,7 +86,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void mtaBuildWithSurroundingDirTest(){ + public void mtaBuildWithSurroundingDirTest() { def newDirName = 'newDir' def newDirPath = "${currentDir}/${newDirName}" @@ -128,7 +128,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void noMtaPresentTest(){ + public void noMtaPresentTest() { mtaYaml.delete() thrown.expect(FileNotFoundException) @@ -138,7 +138,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void badMtaTest(){ + public void badMtaTest() { thrown.expect(ParserException) thrown.expectMessage('while parsing a block mapping') @@ -150,7 +150,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void noIdInMtaTest(){ + public void noIdInMtaTest() { thrown.expect(AbortException) thrown.expectMessage("Property 'ID' not found in mta.yaml file at: '") @@ -162,7 +162,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void noBuildTargetTest(){ + public void noBuildTargetTest() { thrown.expect(Exception) thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTarget') @@ -172,7 +172,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - void mtaJarLocationFromEnvironmentTest(){ + void mtaJarLocationFromEnvironmentTest() { binding.setVariable('env', [:]) binding.getVariable('env')['MTA_JAR_LOCATION'] = '/env/mta' @@ -184,7 +184,7 @@ public class MTABuildTest extends BasePipelineTest { } - private defaultMtaYaml(){ + private defaultMtaYaml() { return ''' _schema-version: "2.0.0" ID: "com.mycompany.northwind" @@ -205,7 +205,7 @@ public class MTABuildTest extends BasePipelineTest { ''' } - private badMtaYaml(){ + private badMtaYaml() { return ''' _schema-version: "2.0.0 ID: "com.mycompany.northwind" @@ -226,7 +226,7 @@ public class MTABuildTest extends BasePipelineTest { ''' } - private noIdMtaYaml(){ + private noIdMtaYaml() { return ''' _schema-version: "2.0.0" version: 1.0.0 From 334251ec82cabadd7c7e4559c6f06022ab13feaa Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Mon, 5 Feb 2018 17:22:03 +0100 Subject: [PATCH 38/44] remove curly braces when not needed See: https://github.com/SAP/jenkins-library/blob/master/CONTRIBUTING.md#do-not-use-curly-braces--for-variables-or-variableproperty --- test/groovy/MTABuildTest.groovy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index 53cb8ba4d..e33eb6bbd 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -39,7 +39,7 @@ public class MTABuildTest extends BasePipelineTest { void init() { currentDir = tmp.newFolder().toURI().getPath()[0..-2] //omit final '/' - mtaYaml = new File("${currentDir}/mta.yaml") + mtaYaml = new File("$currentDir/mta.yaml") mtaYaml << defaultMtaYaml() helper.registerAllowedMethod('readYaml', [Map], { @@ -81,7 +81,7 @@ public class MTABuildTest extends BasePipelineTest { def mtarFilePath = cpe.getMtarFilePath() - assert mtarFilePath == "${currentDir}/com.mycompany.northwind.mtar" + assert mtarFilePath == "$currentDir/com.mycompany.northwind.mtar" } @@ -89,7 +89,7 @@ public class MTABuildTest extends BasePipelineTest { public void mtaBuildWithSurroundingDirTest() { def newDirName = 'newDir' - def newDirPath = "${currentDir}/${newDirName}" + def newDirPath = "$currentDir/$newDirName" def newDir = new File(newDirPath) newDir.mkdirs() @@ -101,7 +101,7 @@ public class MTABuildTest extends BasePipelineTest { assert jscr.shell[0] =~ /sed -ie "s\/\\\$\{timestamp\}\/`date \+%Y%m%d%H%M%S`\/g" ".*\/newDir\/mta.yaml"$/ - assert mtarFilePath == "${currentDir}/${newDirName}/com.mycompany.northwind.mtar" + assert mtarFilePath == "$currentDir/$newDirName/com.mycompany.northwind.mtar" } From 42db55d5a50d856157329c8e7f21c72d52af38bc Mon Sep 17 00:00:00 2001 From: Alejandra Ferreiro Vidal Date: Tue, 6 Feb 2018 11:51:04 +0100 Subject: [PATCH 39/44] remove public when not needed See: https://github.com/SAP/jenkins-library/blob/master/CONTRIBUTING.md#do-not-use-a-visibility-modifier-for-public-classes-and-methods --- test/groovy/MTABuildTest.groovy | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/groovy/MTABuildTest.groovy b/test/groovy/MTABuildTest.groovy index e33eb6bbd..e678aec8e 100644 --- a/test/groovy/MTABuildTest.groovy +++ b/test/groovy/MTABuildTest.groovy @@ -56,7 +56,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void environmentPathTest() { + void environmentPathTest() { mtaBuildScript.call(buildTarget: 'NEO') @@ -65,7 +65,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void sedTest() { + void sedTest() { mtaBuildScript.call(buildTarget: 'NEO') @@ -74,7 +74,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void mtarFilePathFromCommonPipelineEnviromentTest() { + void mtarFilePathFromCommonPipelineEnviromentTest() { mtaBuildScript.call(script: [commonPipelineEnvironment: cpe], buildTarget: 'NEO') @@ -86,7 +86,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void mtaBuildWithSurroundingDirTest() { + void mtaBuildWithSurroundingDirTest() { def newDirName = 'newDir' def newDirPath = "$currentDir/$newDirName" @@ -128,7 +128,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void noMtaPresentTest() { + void noMtaPresentTest() { mtaYaml.delete() thrown.expect(FileNotFoundException) @@ -138,7 +138,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void badMtaTest() { + void badMtaTest() { thrown.expect(ParserException) thrown.expectMessage('while parsing a block mapping') @@ -150,7 +150,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void noIdInMtaTest() { + void noIdInMtaTest() { thrown.expect(AbortException) thrown.expectMessage("Property 'ID' not found in mta.yaml file at: '") @@ -162,7 +162,7 @@ public class MTABuildTest extends BasePipelineTest { @Test - public void noBuildTargetTest() { + void noBuildTargetTest() { thrown.expect(Exception) thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTarget') From 6300008fe219dfada563f30f1afe0d828a4252e4 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 7 Feb 2018 12:01:46 +0100 Subject: [PATCH 40/44] adopt tests --- .../com/sap/piper/ConfigurationMergerTest.groovy | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy index f58050f8f..1cccc02a9 100644 --- a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy +++ b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy @@ -44,13 +44,15 @@ class ConfigurationMergerTest { void testMergeDeepStructure(){ Map defaults = [fruits: [apples: 1, oranges: 10, bananaaas: 0]] Map configuration = [fruits: [bananaaas: 50, cucumbers: 1000]] - Map configurationKeys = [fruits: [apples: null, oranges: null, bananaaas: null]] - Map parameters = [fruits: [apples: 18]] - Map parameterKeys = [fruits: [apples: null, oranges: null, bananaaas: null]] + List configurationKeys = ['fruits'] + Map parameters = [fruits: [apples: 18], veggie: []] + List parameterKeys = ['fruits'] Map merged = ConfigurationMerger.merge(parameters, parameterKeys, configuration, configurationKeys, defaults) Assert.assertEquals(50, merged.fruits.bananaaas) Assert.assertEquals(18, merged.fruits.apples) Assert.assertEquals(10, merged.fruits.oranges) - Assert.assertEquals(null, merged.fruits.cucumbers) + Assert.assertEquals(1000, merged.fruits.cucumbers) + //Assert.assertEquals(null, merged.fruits.cucumbers) + Assert.assertEquals(null, merged.veggie) } } From 87a3a77f440ed3dec28706edeeb9e6f2aaea43b5 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 7 Feb 2018 12:07:52 +0100 Subject: [PATCH 41/44] rework config merge --- src/com/sap/piper/ConfigurationMerger.groovy | 60 +++++--------------- 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/src/com/sap/piper/ConfigurationMerger.groovy b/src/com/sap/piper/ConfigurationMerger.groovy index 4663ce7ae..82d489154 100644 --- a/src/com/sap/piper/ConfigurationMerger.groovy +++ b/src/com/sap/piper/ConfigurationMerger.groovy @@ -6,23 +6,18 @@ import com.sap.piper.MapUtils class ConfigurationMerger { @NonCPS - def static merge(Map configs, List configKeys, Map defaults=[:]) { - return merge(configs, MapUtils.fromList(configKeys), defaults) - } - - @NonCPS - def static merge(Map configs, Map configKeys, Map defaults = [:]) { + def static merge(Map configs, List configKeys, Map defaults) { + Map filteredConfig = configKeys?configs.subMap(configKeys):configs Map merged = [:] + merged.putAll(defaults) - if(configs != null && configKeys){ - configs = configs.subMap(configKeys.keySet()) - for(String key : configKeys.keySet()) - if(MapUtils.isMap(configKeys[key])) - merged[key] = merge(configs[key], configKeys[key], defaults[key]) - else if(configs[key] != null) - merged[key] = configs[key] - } + for(String key : filteredConfig.keySet()) + if(MapUtils.isMap(filteredConfig[key])) + merged[key] = merge(filteredConfig[key], null, defaults[key]) + else if(filteredConfig[key] != null) + merged[key] = filteredConfig[key] + // else: keep defaults value and omit null values from config return merged } @@ -31,18 +26,6 @@ class ConfigurationMerger { Map parameters, List parameterKeys, Map configuration, List configurationKeys, Map defaults=[:] - ){ - return merge( - parameters, MapUtils.fromList(parameterKeys), - configuration, MapUtils.fromList(configurationKeys), - defaults) - } - - @NonCPS - def static merge( - Map parameters, Map parameterKeys, - Map configuration, Map configurationKeys, - Map defaults=[:] ){ Map merged merged = merge(configuration, configurationKeys, defaults) @@ -56,28 +39,11 @@ class ConfigurationMerger { Map configurationMap, List configurationKeys, Map stepDefaults=[:] ){ - Map merged = [:] - merged.putAll(stepDefaults) - merged.putAll(filterByKeyAndNull(configurationMap, configurationKeys)) - merged.putAll(pipelineDataMap) - merged.putAll(filterByKeyAndNull(parameters, parameterKeys)) + Map merged + merged = merge(configurationMap, configurationKeys, stepDefaults) + merged = merge(pipelineDataMap, null, merged) + merged = merge(parameters, parameterKeys, merged) return merged } - - @NonCPS - private static filterByKeyAndNull(Map map, List keys) { - Map filteredMap = map.findAll { - if(it.value == null){ - return false - } - return true - } - - if(keys == null) { - return filteredMap - } - - return filteredMap.subMap(keys) - } } From f6d13033171577f5127d3fd7c560c3269eba1e0b Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 7 Feb 2018 12:08:01 +0100 Subject: [PATCH 42/44] remove obsolete method --- src/com/sap/piper/MapUtils.groovy | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/com/sap/piper/MapUtils.groovy b/src/com/sap/piper/MapUtils.groovy index dccfea6f9..e42b5aaff 100644 --- a/src/com/sap/piper/MapUtils.groovy +++ b/src/com/sap/piper/MapUtils.groovy @@ -7,13 +7,4 @@ class MapUtils implements Serializable { static isMap(object){ return object in Map } - - @NonCPS - static fromList(List list){ - Map map = [:] - for(String key : list){ - map.put(key, null) - } - return map - } } From fbd03a88dafa8daa78bb482d47c3ef7bbb01b843 Mon Sep 17 00:00:00 2001 From: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Date: Wed, 7 Feb 2018 13:17:33 +0100 Subject: [PATCH 43/44] Step for automatic versioning (#65) It contains: * versioning step artifactSetVersion * versioning implementation for Maven & Docker * enhancements to commonPipelineEnvironment * extended default configuration * new utils object for git-related tasks * automated tests incl. new Rules and resources * incorporated PR feedback * step documentation --- .../docs/steps/artifactSetVersion.md | 75 ++++++++++ documentation/mkdocs.yml | 1 + resources/default_pipeline_environment.yml | 9 ++ src/com/sap/piper/GitUtils.groovy | 7 + .../versioning/ArtifactVersioning.groovy | 30 ++++ .../DockerArtifactVersioning.groovy | 50 +++++++ .../versioning/MavenArtifactVersioning.groovy | 18 +++ test/groovy/ArtifactSetVersionTest.groovy | 115 +++++++++++++++ test/groovy/com/sap/piper/GitUtilsTest.groovy | 47 ++++++ .../versioning/ArtifactVersioningTest.groovy | 28 ++++ .../DockerArtifactVersioningTest.groovy | 71 +++++++++ .../MavenArtifactVersioningTest.groovy | 54 +++++++ test/groovy/util/JenkinsReadFileRule.groovy | 41 ++++++ .../util/JenkinsReadMavenPomRule.groovy | 66 +++++++++ test/groovy/util/JenkinsShellCallRule.groovy | 15 +- test/groovy/util/JenkinsWriteFileRule.groovy | 34 +++++ .../DockerArtifactVersioning/Dockerfile | 5 + .../resources/MavenArtifactVersioning/pom.xml | 8 + .../MavenArtifactVersioning/snapshot/pom.xml | 8 + vars/artifactSetVersion.groovy | 138 ++++++++++++++++++ vars/commonPipelineEnvironment.groovy | 31 ++++ 21 files changed, 850 insertions(+), 1 deletion(-) create mode 100644 documentation/docs/steps/artifactSetVersion.md create mode 100644 src/com/sap/piper/GitUtils.groovy create mode 100644 src/com/sap/piper/versioning/ArtifactVersioning.groovy create mode 100644 src/com/sap/piper/versioning/DockerArtifactVersioning.groovy create mode 100644 src/com/sap/piper/versioning/MavenArtifactVersioning.groovy create mode 100644 test/groovy/ArtifactSetVersionTest.groovy create mode 100644 test/groovy/com/sap/piper/GitUtilsTest.groovy create mode 100644 test/groovy/com/sap/piper/versioning/ArtifactVersioningTest.groovy create mode 100644 test/groovy/com/sap/piper/versioning/DockerArtifactVersioningTest.groovy create mode 100644 test/groovy/com/sap/piper/versioning/MavenArtifactVersioningTest.groovy create mode 100644 test/groovy/util/JenkinsReadFileRule.groovy create mode 100644 test/groovy/util/JenkinsReadMavenPomRule.groovy create mode 100644 test/groovy/util/JenkinsWriteFileRule.groovy create mode 100644 test/resources/DockerArtifactVersioning/Dockerfile create mode 100644 test/resources/MavenArtifactVersioning/pom.xml create mode 100644 test/resources/MavenArtifactVersioning/snapshot/pom.xml create mode 100644 vars/artifactSetVersion.groovy diff --git a/documentation/docs/steps/artifactSetVersion.md b/documentation/docs/steps/artifactSetVersion.md new file mode 100644 index 000000000..4af50bbf3 --- /dev/null +++ b/documentation/docs/steps/artifactSetVersion.md @@ -0,0 +1,75 @@ +# artifactSetVersion + +## Description +The continuous delivery process requires that each build is done with a unique version number. + +The version generated using this step will contain: + +* Version (major.minor.patch) from descriptor file in master repository is preserved. Developers should be able to autonomously decide on increasing either part of this version number. +* Timestamp +* CommitId (by default the long version of the hash) + +After conducting automatic versioning the new version is pushed as a new tag into the source code repository (e.g. GitHub) + +## Prerequsites +none + +## Parameters + +| parameter | mandatory | default | possible values | +| ----------|-----------|---------|-----------------| +| script | no | empty `commonPipelineEnvironment` | | +| buildTool | no | maven | maven, docker | +| dockerVersionSource | no | `''` | FROM, (ENV name),appVersion | +| filePath | no | buildTool=`maven`: pom.xml
docker: Dockerfile | | +| gitCommitId | no | `GitUtils.getGitCommitId()` | | +| gitCredentialsId | yes | as defined in custom configuration | | +| gitUserEMail | no | | | +| gitUserName | no | | | +| gitSshUrl | yes | | | +| tagPrefix | no | 'build_' | | +| timestamp | no | current time in format according to `timestampTemplate` | | +| timestampTemplate | no | `%Y%m%d%H%M%S` | | +| versioningTemplate | no | depending on `buildTool`
maven: `${version}-${timestamp}${commitId?"_"+commitId:""}` | | + +* `script` defines the global script environment of the Jenkinsfile run. Typically `this` is passed to this parameter. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for retrieving e.g. configuration parameters. +* `buildTool` defines the tool which is used for building the artifact. +* `dockerVersionSource` specifies the source to be used for the main version which is used for generating the automatic version. + + * This can either be the version of the base image - as retrieved from the `FROM` statement within the Dockerfile, e.g. `FROM jenkins:2.46.2` + * Alternatively the name of an environment variable defined in the Docker image can be used which contains the version number, e.g. `ENV MY_VERSION 1.2.3` + * The third option `appVersion` applies only to the artifactType `appContainer`. Here the version of the app which is packaged into the container will be used as version for the container itself. + +* Using `filePath` you could define a custom path to the descriptor file. +* `gitCommitId` defines the version prefix of the automatically generated version. By default it will take the long commitId hash. You could pass any other string (e.g. the short commitId hash) to be used. In case you don't want to have the gitCommitId added to the automatic versioning string you could set the value to an empty string: `''`. +* `gitCredentialsId`defines the ssh git credentials to be used for writing the tag. +* The parameters `gitUserName` and `gitUserEMail` allow to overwrite the global git settings available on your Jenkins server +* `gitSshUrl` defines the git ssh url to the source code repository. +* `tagPrefix` defines the prefix wich is used for the git tag which is written during the versioning run. +* `timestamp` defines the timestamp to be used in the automatic version string. You could overwrite the default behavior by explicitly setting this string. + +## Step configuration +Following parameters can also be specified as step parameters using the global configuration file: + +* `artifactType` +* `buildTool` +* `dockerVersionSource` +* `filePath` +* `gitCredentialsId` +* `gitUserEMail` +* `gitUserName` +* `gitSshUrl` +* `tagPrefix` +* `timestamp` +* `timestampTemplate` +* `versioningTemplate` + +## Explanation of pipeline step + +Pipeline step: + +```groovy +artifactSetVersion script: this, buildTool: 'maven' +``` + + diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml index b3791bda0..ccd7d3f99 100644 --- a/documentation/mkdocs.yml +++ b/documentation/mkdocs.yml @@ -2,6 +2,7 @@ site_name: Jenkins 2.0 Pipelines pages: - Home: index.md - 'Library steps': + - artifactSetVersion: steps/artifactSetVersion.md - commonPipelineEnvironment: steps/commonPipelineEnvironment.md - dockerExecute: steps/dockerExecute.md - durationMeasure: steps/durationMeasure.md diff --git a/resources/default_pipeline_environment.yml b/resources/default_pipeline_environment.yml index 0a89880df..21c806922 100644 --- a/resources/default_pipeline_environment.yml +++ b/resources/default_pipeline_environment.yml @@ -4,6 +4,15 @@ general: #Steps Specific Configuration steps: + artifactSetVersion: + timestampTemplate: '%Y%m%d%H%M%S' + tagPrefix: 'build_' + maven: + filePath: 'pom.xml' + versioningTemplate: '${version}-${timestamp}${commitId?"_"+commitId:""}' + docker: + filePath: 'Dockerfile' + versioningTemplate: '${version}-${timestamp}${commitId?"_"+commitId:""}' mavenExecute: dockerImage: 'maven:3.5-jdk-7' influxWriteData: diff --git a/src/com/sap/piper/GitUtils.groovy b/src/com/sap/piper/GitUtils.groovy new file mode 100644 index 000000000..ed4592cb1 --- /dev/null +++ b/src/com/sap/piper/GitUtils.groovy @@ -0,0 +1,7 @@ +package com.sap.piper + +import com.cloudbees.groovy.cps.NonCPS + +def getGitCommitId() { + return sh(returnStdout: true, script: 'git rev-parse HEAD').trim() +} diff --git a/src/com/sap/piper/versioning/ArtifactVersioning.groovy b/src/com/sap/piper/versioning/ArtifactVersioning.groovy new file mode 100644 index 000000000..f16cbbf54 --- /dev/null +++ b/src/com/sap/piper/versioning/ArtifactVersioning.groovy @@ -0,0 +1,30 @@ +package com.sap.piper.versioning + +abstract class ArtifactVersioning implements Serializable { + + final protected script + final protected Map configuration + + protected ArtifactVersioning(script, configuration) { + this.script = script + this.configuration = configuration + } + + public static getArtifactVersioning(buildTool, script, configuration) { + switch (buildTool) { + case 'maven': + return new MavenArtifactVersioning(script, configuration) + case 'docker': + return new DockerArtifactVersioning(script, configuration) + default: + throw new IllegalArgumentException("No versioning implementation for buildTool: ${buildTool} available.") + } + } + + abstract setVersion(version) + abstract getVersion() + + protected echo(msg){ + script.echo("[${this.getClass().getSimpleName()}] ${msg}") + } +} diff --git a/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy b/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy new file mode 100644 index 000000000..65cd4eabf --- /dev/null +++ b/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy @@ -0,0 +1,50 @@ +package com.sap.piper.versioning + +class DockerArtifactVersioning extends ArtifactVersioning { + protected DockerArtifactVersioning(script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + if (configuration.dockerVersionSource == 'FROM') + return getVersionFromDockerBaseImageTag(configuration.filePath) + else + //standard assumption: version is assigned to an env variable + return getVersionFromDockerEnvVariable(configuration.filePath, configuration.dockerVersionSource) + } + + @Override + def setVersion(version) { + def dockerVersionDir = (configuration.dockerVersionDir?dockerVersionDir:'') + script.dir(dockerVersionDir) { + script.writeFile file:'VERSION', text: version + } + } + + def getVersionFromDockerEnvVariable(filePath, envVarName) { + def lines = script.readFile(filePath).split('\n') + def version = '' + for (def i = 0; i < lines.size(); i++) { + if (lines[i].startsWith('ENV') && lines[i].split(' ')[1] == envVarName) { + version = lines[i].split(' ')[2] + break + } + } + echo("Version from Docker environment variable ${envVarName}: ${version}") + return version.trim() + } + + def getVersionFromDockerBaseImageTag(filePath) { + def lines = script.readFile(filePath).split('\n') + def version = null + for (def i = 0; i < lines.size(); i++) { + if (lines[i].startsWith('FROM') && lines[i].indexOf(':') > 0) { + version = lines[i].split(':')[1] + break + } + } + echo("Version from Docker base image tag: ${version}") + return version.trim() + } +} diff --git a/src/com/sap/piper/versioning/MavenArtifactVersioning.groovy b/src/com/sap/piper/versioning/MavenArtifactVersioning.groovy new file mode 100644 index 000000000..db77b5b9d --- /dev/null +++ b/src/com/sap/piper/versioning/MavenArtifactVersioning.groovy @@ -0,0 +1,18 @@ +package com.sap.piper.versioning + +class MavenArtifactVersioning extends ArtifactVersioning { + protected MavenArtifactVersioning (script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + def mavenPom = script.readMavenPom (file: configuration.filePath) + return mavenPom.getVersion().replaceAll(/-SNAPSHOT$/, "") + } + + @Override + def setVersion(version) { + script.sh "mvn versions:set -DnewVersion=${version} --file ${configuration.filePath}" + } +} diff --git a/test/groovy/ArtifactSetVersionTest.groovy b/test/groovy/ArtifactSetVersionTest.groovy new file mode 100644 index 000000000..6a11c62b6 --- /dev/null +++ b/test/groovy/ArtifactSetVersionTest.groovy @@ -0,0 +1,115 @@ +#!groovy +import com.lesfurets.jenkins.unit.BasePipelineTest +import com.sap.piper.DefaultValueCache +import com.sap.piper.GitUtils +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.rules.RuleChain +import util.JenkinsLoggingRule +import util.JenkinsReadMavenPomRule +import util.JenkinsShellCallRule +import util.JenkinsWriteFileRule +import util.Rules + +import static org.junit.Assert.assertEquals + +class ArtifactSetVersionTest extends BasePipelineTest { + + Script artifactSetVersionScript + + def cpe + def gitUtils + def sshAgentList = [] + + ExpectedException thrown = ExpectedException.none() + JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + JenkinsShellCallRule jscr = new JenkinsShellCallRule(this) + JenkinsWriteFileRule jwfr = new JenkinsWriteFileRule(this) + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(thrown) + .around(jlr) + .around(jscr) + .around(new JenkinsReadMavenPomRule(this, 'test/resources/MavenArtifactVersioning')) + .around(jwfr) + + @Before + void init() throws Throwable { + + helper.registerAllowedMethod("sshagent", [List.class, Closure.class], { list, closure -> + sshAgentList = list + return closure() + }) + + jscr.setReturnValue('git rev-parse HEAD', 'testCommitId') + jscr.setReturnValue("date +'%Y%m%d%H%M%S'", '20180101010203') + jscr.setReturnValue('git diff --quiet HEAD', 0) + + cpe = loadScript('commonPipelineEnvironment.groovy').commonPipelineEnvironment + artifactSetVersionScript = loadScript("artifactSetVersion.groovy") + + gitUtils = new GitUtils() + prepareObjectInterceptors(gitUtils) + } + + @Test + void testVersioning() { + artifactSetVersionScript.call(script: [commonPipelineEnvironment: cpe], juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl') + + assertEquals('1.2.3-20180101010203_testCommitId', cpe.getArtifactVersion()) + assertEquals('testCommitId', cpe.getGitCommitId()) + + assertEquals('mvn versions:set -DnewVersion=1.2.3-20180101010203_testCommitId --file pom.xml', jscr.shell[3]) + assertEquals('git add .', jscr.shell[4]) + assertEquals ("git commit -m 'update version 1.2.3-20180101010203_testCommitId'", jscr.shell[5]) + assertEquals ("git remote set-url origin myGitSshUrl", jscr.shell[6]) + assertEquals ("git tag build_1.2.3-20180101010203_testCommitId", jscr.shell[7]) + assertEquals ("git push origin build_1.2.3-20180101010203_testCommitId", jscr.shell[8]) + } + + @Test + void testVersioningCustomGitUserAndEMail() { + artifactSetVersionScript.call(script: [commonPipelineEnvironment: cpe], juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl', gitUserEMail: 'test@test.com', gitUserName: 'test') + + assertEquals ('git -c user.email="test@test.com" -c user.name "test" commit -m \'update version 1.2.3-20180101010203_testCommitId\'', jscr.shell[5]) + } + + @Test + void testVersioningWithTimestamp() { + artifactSetVersionScript.call(script: [commonPipelineEnvironment: cpe], juStabGitUtils: gitUtils, buildTool: 'maven', timestamp: '2018') + assertEquals('1.2.3-2018_testCommitId', cpe.getArtifactVersion()) + } + + @Test + void testVersioningNoBuildTool() { + thrown.expect(Exception) + thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTool') + artifactSetVersionScript.call(script: [commonPipelineEnvironment: cpe], juStabGitUtils: gitUtils) + } + + @Test + void testVersioningWithCustomTemplate() { + artifactSetVersionScript.call(script: [commonPipelineEnvironment: cpe], juStabGitUtils: gitUtils, buildTool: 'maven', versioningTemplate: '${version}-xyz') + assertEquals('1.2.3-xyz', cpe.getArtifactVersion()) + } + + @Test + void testVersioningWithTypeAppContainer() { + cpe.setArtifactVersion('1.2.3-xyz') + artifactSetVersionScript.call(script: [commonPipelineEnvironment: cpe], juStabGitUtils: gitUtils, buildTool: 'docker', artifactType: 'appContainer', dockerVersionSource: 'appVersion') + assertEquals('1.2.3-xyz', cpe.getArtifactVersion()) + assertEquals('1.2.3-xyz', jwfr.files['VERSION']) + } + + void prepareObjectInterceptors(object) { + object.metaClass.invokeMethod = helper.getMethodInterceptor() + object.metaClass.static.invokeMethod = helper.getMethodInterceptor() + object.metaClass.methodMissing = helper.getMethodMissingInterceptor() + } + + +} diff --git a/test/groovy/com/sap/piper/GitUtilsTest.groovy b/test/groovy/com/sap/piper/GitUtilsTest.groovy new file mode 100644 index 000000000..8ffff2d24 --- /dev/null +++ b/test/groovy/com/sap/piper/GitUtilsTest.groovy @@ -0,0 +1,47 @@ +package com.sap.piper + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.rules.RuleChain +import util.JenkinsReadMavenPomRule +import util.JenkinsShellCallRule +import util.Rules +import util.SharedLibraryCreator + +import static org.junit.Assert.assertEquals + +class GitUtilsTest extends BasePipelineTest { + + JenkinsShellCallRule jscr = new JenkinsShellCallRule(this) + ExpectedException thrown = ExpectedException.none() + + @Rule + public RuleChain ruleChain = Rules.getCommonRules(this).around(jscr).around(thrown) + + GitUtils gitUtils + + @Before + void init() throws Exception { + gitUtils = new GitUtils() + prepareObjectInterceptors(gitUtils) + + jscr.setReturnValue('git rev-parse HEAD', 'testCommitId') + } + + void prepareObjectInterceptors(object) { + object.metaClass.invokeMethod = helper.getMethodInterceptor() + object.metaClass.static.invokeMethod = helper.getMethodInterceptor() + object.metaClass.methodMissing = helper.getMethodMissingInterceptor() + } + + @Test + void testGetGitCommitId() { + + assertEquals('testCommitId', gitUtils.getGitCommitId()) + + } + +} diff --git a/test/groovy/com/sap/piper/versioning/ArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/ArtifactVersioningTest.groovy new file mode 100644 index 000000000..6bc8b1923 --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/ArtifactVersioningTest.groovy @@ -0,0 +1,28 @@ +package com.sap.piper.versioning + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException + +import static org.junit.Assert.assertTrue +import static org.junit.Assert.assertEquals + +class ArtifactVersioningTest { + + @Rule + public ExpectedException thrown = ExpectedException.none() + + @Test + void testInstatiateFactoryMethod() { + def versionObj = ArtifactVersioning.getArtifactVersioning( 'maven', this, [:]) + assertTrue(versionObj instanceof MavenArtifactVersioning) + } + + @Test + void testInstatiateFactoryMethodWithInvalidToolId() { + thrown.expect(IllegalArgumentException) + thrown.expectMessage('No versioning implementation for buildTool: invalid available.') + ArtifactVersioning.getArtifactVersioning('invalid', this, [:]) + } +} diff --git a/test/groovy/com/sap/piper/versioning/DockerArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/DockerArtifactVersioningTest.groovy new file mode 100644 index 000000000..8af044237 --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/DockerArtifactVersioningTest.groovy @@ -0,0 +1,71 @@ +package com.sap.piper.versioning + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.rules.RuleChain +import util.JenkinsLoggingRule +import util.JenkinsReadFileRule +import util.JenkinsReadMavenPomRule +import util.JenkinsShellCallRule +import util.JenkinsWriteFileRule +import util.Rules + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertTrue + +class DockerArtifactVersioningTest extends BasePipelineTest{ + + DockerArtifactVersioning av + + String passedDir + + JenkinsReadFileRule jrfr = new JenkinsReadFileRule(this, 'test/resources/DockerArtifactVersioning') + JenkinsWriteFileRule jwfr = new JenkinsWriteFileRule(this) + JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + ExpectedException thrown = ExpectedException.none() + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(jrfr) + .around(jwfr) + .around(jlr) + .around(thrown) + + @Before + public void init() { + + helper.registerAllowedMethod("dir", [String.class, Closure.class], { s, closure -> + passedDir = s + return closure() + }) + + prepareObjectInterceptors(this) + } + + @Test + void testVersioningFrom() { + av = new DockerArtifactVersioning(this, [filePath: 'Dockerfile', dockerVersionSource: 'FROM']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertEquals('1.2.3-20180101', jwfr.files['VERSION']) + assertTrue(jlr.log.contains('[DockerArtifactVersioning] Version from Docker base image tag: 1.2.3')) + } + + @Test + void testVersioningEnv() { + av = new DockerArtifactVersioning(this, [filePath: 'Dockerfile', dockerVersionSource: 'TEST']) + assertEquals('2.3.4', av.getVersion()) + assertTrue(jlr.log.contains('[DockerArtifactVersioning] Version from Docker environment variable TEST: 2.3.4')) + } + + + void prepareObjectInterceptors(object) { + object.metaClass.invokeMethod = helper.getMethodInterceptor() + object.metaClass.static.invokeMethod = helper.getMethodInterceptor() + object.metaClass.methodMissing = helper.getMethodMissingInterceptor() + } +} diff --git a/test/groovy/com/sap/piper/versioning/MavenArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/MavenArtifactVersioningTest.groovy new file mode 100644 index 000000000..69901ec57 --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/MavenArtifactVersioningTest.groovy @@ -0,0 +1,54 @@ +package com.sap.piper.versioning + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.rules.RuleChain +import util.JenkinsReadMavenPomRule +import util.JenkinsShellCallRule +import util.Rules + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertTrue + +class MavenArtifactVersioningTest extends BasePipelineTest{ + + MavenArtifactVersioning av + + JenkinsShellCallRule jscr = new JenkinsShellCallRule(this) + ExpectedException thrown = ExpectedException.none() + + @Rule + public RuleChain ruleChain = Rules.getCommonRules(this).around(jscr).around(thrown).around(new JenkinsReadMavenPomRule(this, 'test/resources/MavenArtifactVersioning')) + + @Before + public void init() { + prepareObjectInterceptors(this) + } + + @Test + void testVersioning() { + av = new MavenArtifactVersioning(this, [filePath: 'pom.xml']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertEquals('mvn versions:set -DnewVersion=1.2.3-20180101 --file pom.xml', jscr.shell[0]) + } + + + @Test + void testVersioningCustomFilePathSnapshot() { + av = new MavenArtifactVersioning(this, [filePath: 'snapshot/pom.xml']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertEquals('mvn versions:set -DnewVersion=1.2.3-20180101 --file snapshot/pom.xml', jscr.shell[0]) + } + + + void prepareObjectInterceptors(object) { + object.metaClass.invokeMethod = helper.getMethodInterceptor() + object.metaClass.static.invokeMethod = helper.getMethodInterceptor() + object.metaClass.methodMissing = helper.getMethodMissingInterceptor() + } +} diff --git a/test/groovy/util/JenkinsReadFileRule.groovy b/test/groovy/util/JenkinsReadFileRule.groovy new file mode 100644 index 000000000..d1e16d657 --- /dev/null +++ b/test/groovy/util/JenkinsReadFileRule.groovy @@ -0,0 +1,41 @@ +package util + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +class JenkinsReadFileRule implements TestRule { + + final BasePipelineTest testInstance + final String testRoot + + JenkinsReadFileRule(BasePipelineTest testInstance, String testRoot) { + this.testInstance = testInstance + this.testRoot = testRoot + } + + @Override + Statement apply(Statement base, Description description) { + return statement(base) + } + + private Statement statement(final Statement base) { + return new Statement() { + @Override + void evaluate() throws Throwable { + + testInstance.helper.registerAllowedMethod( 'readFile', [String.class], {s -> return (loadFile("${testRoot}/${s}")).getText('UTF-8')} ) + + testInstance.helper.registerAllowedMethod( 'readFile', [Map.class], {m -> return (loadFile("${testRoot}/${m.file}")).getText(m.encoding?m.encoding:'UTF-8')} ) + + base.evaluate() + } + } + } + + File loadFile(String path){ + return new File(path) + } + +} diff --git a/test/groovy/util/JenkinsReadMavenPomRule.groovy b/test/groovy/util/JenkinsReadMavenPomRule.groovy new file mode 100644 index 000000000..4c6d7f3a0 --- /dev/null +++ b/test/groovy/util/JenkinsReadMavenPomRule.groovy @@ -0,0 +1,66 @@ +package util + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +class JenkinsReadMavenPomRule implements TestRule { + + final BasePipelineTest testInstance + final String testRoot + + JenkinsReadMavenPomRule(BasePipelineTest testInstance, String testRoot) { + this.testInstance = testInstance + this.testRoot = testRoot + } + + @Override + Statement apply(Statement base, Description description) { + return statement(base) + } + + private Statement statement(final Statement base) { + return new Statement() { + @Override + void evaluate() throws Throwable { + + testInstance.helper.registerAllowedMethod('readMavenPom', [Map.class], {m -> return loadPom("${testRoot}/${m.file}")}) + + base.evaluate() + } + } + } + + MockPom loadPom( String path ){ + return new MockPom( path ) + } + + class MockPom { + def pom + MockPom(String path){ + def f = new File( path ) + if ( f.exists() ){ + this.pom = new XmlSlurper().parse(f) + } + else { + throw new FileNotFoundException( 'Failed to find file: ' + path ) + } + } + String getVersion(){ + return pom.version + } + String getGroupId(){ + return pom.groupId + } + String getArtifactId(){ + return pom.artifactId + } + String getPackaging(){ + return pom.packaging + } + String getName(){ + return pom.name + } + } +} diff --git a/test/groovy/util/JenkinsShellCallRule.groovy b/test/groovy/util/JenkinsShellCallRule.groovy index ce17ce7d6..0541f87ef 100644 --- a/test/groovy/util/JenkinsShellCallRule.groovy +++ b/test/groovy/util/JenkinsShellCallRule.groovy @@ -11,10 +11,16 @@ class JenkinsShellCallRule implements TestRule { List shell = [] + def returnValues = [:] + JenkinsShellCallRule(BasePipelineTest testInstance) { this.testInstance = testInstance } + def setReturnValue(script, value) { + returnValues[script] = value + } + @Override Statement apply(Statement base, Description description) { return statement(base) @@ -26,10 +32,17 @@ class JenkinsShellCallRule implements TestRule { void evaluate() throws Throwable { testInstance.helper.registerAllowedMethod("sh", [String.class], { - command -> + command -> shell.add(command.replaceAll(/\s+/," ").trim()) }) + testInstance.helper.registerAllowedMethod("sh", [Map.class], { + m -> + shell.add(m.script.replaceAll(/\s+/," ").trim()) + if (m.returnStdout || m.returnStatus) + return returnValues[m.script] + }) + base.evaluate() } } diff --git a/test/groovy/util/JenkinsWriteFileRule.groovy b/test/groovy/util/JenkinsWriteFileRule.groovy new file mode 100644 index 000000000..6a59dcf32 --- /dev/null +++ b/test/groovy/util/JenkinsWriteFileRule.groovy @@ -0,0 +1,34 @@ +package util + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +class JenkinsWriteFileRule implements TestRule { + + final BasePipelineTest testInstance + + Map files = [:] + + JenkinsWriteFileRule(BasePipelineTest testInstance) { + this.testInstance = testInstance + } + + @Override + Statement apply(Statement base, Description description) { + return statement(base) + } + + private Statement statement(final Statement base) { + return new Statement() { + @Override + void evaluate() throws Throwable { + + testInstance.helper.registerAllowedMethod( 'writeFile', [Map.class], {m -> files[m.file] = m.text.toString()}) + + base.evaluate() + } + } + } +} diff --git a/test/resources/DockerArtifactVersioning/Dockerfile b/test/resources/DockerArtifactVersioning/Dockerfile new file mode 100644 index 000000000..0ddb8e2bb --- /dev/null +++ b/test/resources/DockerArtifactVersioning/Dockerfile @@ -0,0 +1,5 @@ +FROM rootImage:1.2.3 + +USER root + +ENV TEST 2.3.4 diff --git a/test/resources/MavenArtifactVersioning/pom.xml b/test/resources/MavenArtifactVersioning/pom.xml new file mode 100644 index 000000000..3f9487ae1 --- /dev/null +++ b/test/resources/MavenArtifactVersioning/pom.xml @@ -0,0 +1,8 @@ + + 4.0.0 + com.sap.piper + library-test + war + 1.2.3 + library-test + diff --git a/test/resources/MavenArtifactVersioning/snapshot/pom.xml b/test/resources/MavenArtifactVersioning/snapshot/pom.xml new file mode 100644 index 000000000..241042583 --- /dev/null +++ b/test/resources/MavenArtifactVersioning/snapshot/pom.xml @@ -0,0 +1,8 @@ + + 4.0.0 + com.sap.piper + library-test + war + 1.2.3-SNAPSHOT + library-test + diff --git a/vars/artifactSetVersion.groovy b/vars/artifactSetVersion.groovy new file mode 100644 index 000000000..8b75014d8 --- /dev/null +++ b/vars/artifactSetVersion.groovy @@ -0,0 +1,138 @@ +import com.sap.piper.ConfigurationLoader +import com.sap.piper.ConfigurationMerger +import com.sap.piper.GitUtils +import com.sap.piper.Utils +import com.sap.piper.versioning.ArtifactVersioning + +import groovy.text.SimpleTemplateEngine + +def call(Map parameters = [:]) { + + def stepName = 'artifactSetVersion' + + handlePipelineStepErrors (stepName: stepName, stepParameters: parameters) { + + def gitUtils = parameters.juStabGitUtils + if (gitUtils == null) { + gitUtils = new GitUtils() + } + + if (sh(returnStatus: true, script: 'git diff --quiet HEAD') != 0) + error "[${stepName}] Files in the workspace have been changed previously - aborting ${stepName}" + + def script = parameters.script + if (script == null) + script = [commonPipelineEnvironment: commonPipelineEnvironment] + + prepareDefaultValues script: script + + final Map stepDefaults = ConfigurationLoader.defaultStepConfiguration(script, stepName) + final Map stepConfiguration = ConfigurationLoader.stepConfiguration(script, stepName) + + List parameterKeys = [ + 'artifactType', + 'buildTool', + 'dockerVersionSource', + 'filePath', + 'gitCommitId', + 'gitCredentialsId', + 'gitUserEMail', + 'gitUserName', + 'gitSshUrl', + 'tagPrefix', + 'timestamp', + 'timestampTemplate', + 'versioningTemplate' + ] + Map pipelineDataMap = [ + gitCommitId: gitUtils.getGitCommitId() + ] + List stepConfigurationKeys = [ + 'artifactType', + 'buildTool', + 'dockerVersionSource', + 'filePath', + 'gitCredentialsId', + 'gitUserEMail', + 'gitUserName', + 'gitSshUrl', + 'tagPrefix', + 'timestamp', + 'timestampTemplate', + 'versioningTemplate' + ] + + Map configuration = ConfigurationMerger.mergeWithPipelineData(parameters, parameterKeys, pipelineDataMap, stepConfiguration, stepConfigurationKeys, stepDefaults) + + def utils = new Utils() + def buildTool = utils.getMandatoryParameter(configuration, 'buildTool') + + if (!configuration.filePath) + configuration.filePath = configuration[buildTool].filePath //use default configuration + + def newVersion + def artifactVersioning = ArtifactVersioning.getArtifactVersioning(buildTool, this, configuration) + + if(configuration.artifactType == 'appContainer' && configuration.dockerVersionSource == 'appVersion'){ + if (script.commonPipelineEnvironment.getArtifactVersion()) + //replace + sign if available since + is not allowed in a Docker tag + newVersion = script.commonPipelineEnvironment.getArtifactVersion().replace('+', '_') + else + error ("[${stepName}] No artifact version available for 'dockerVersionSource: appVersion' -> executeBuild needs to run for the application artifact first to set the artifactVersion for the application artifact.'") + } else { + def currentVersion = artifactVersioning.getVersion() + + def timestamp = configuration.timestamp ? configuration.timestamp : getTimestamp(configuration.timestampTemplate) + + def versioningTemplate = configuration.versioningTemplate ? configuration.versioningTemplate : configuration[configuration.buildTool].versioningTemplate + //defined in default configuration + def binding = [version: currentVersion, timestamp: timestamp, commitId: configuration.gitCommitId] + def templatingEngine = new SimpleTemplateEngine() + def template = templatingEngine.createTemplate(versioningTemplate).make(binding) + newVersion = template.toString() + } + + artifactVersioning.setVersion(newVersion) + + sh 'git add .' + + def gitCommitId + + sshagent([configuration.gitCredentialsId]) { + def gitUserMailConfig = '' + if (configuration.gitUserName && configuration.gitUserEMail) + gitUserMailConfig = "-c user.email=\"${configuration.gitUserEMail}\" -c user.name \"${configuration.gitUserName}\"" + + try { + sh "git ${gitUserMailConfig} commit -m 'update version ${newVersion}'" + } catch (e) { + error "[${stepName}]git commit failed: ${e}" + } + sh "git remote set-url origin ${configuration.gitSshUrl}" + sh "git tag ${configuration.tagPrefix}${newVersion}" + sh "git push origin ${configuration.tagPrefix}${newVersion}" + + gitCommitId = gitUtils.getGitCommitId() + + } + + if(buildTool == 'docker' && configuration.artifactType == 'appContainer') { + script.commonPipelineEnvironment.setAppContainerProperty('artifactVersion', newVersion) + script.commonPipelineEnvironment.setAppContainerProperty('gitCommitId', gitCommitId) + } else { + //standard case + script.commonPipelineEnvironment.setArtifactVersion(newVersion) + script.commonPipelineEnvironment.setGitCommitId(gitCommitId) + } + echo "[${stepName}]New version: ${newVersion}" + } +} + +def getTimestamp(pattern){ + return sh(returnStdout: true, script: "date +'${pattern}'").trim() +} + + + + + diff --git a/vars/commonPipelineEnvironment.groovy b/vars/commonPipelineEnvironment.groovy index c2807a92e..1ff5bdea6 100644 --- a/vars/commonPipelineEnvironment.groovy +++ b/vars/commonPipelineEnvironment.groovy @@ -4,6 +4,13 @@ class commonPipelineEnvironment implements Serializable { //stores version of the artifact which is build during pipeline run def artifactVersion + //stores the gitCommitId as well as additional git information for the build during pipeline run + private String gitCommitId + private String gitSshUrl + + //stores properties for a pipeline which build an artifact and then bundles it into a container + private Map appContainerProperties = [:] + Map configuration = [:] Map defaultConfiguration = [:] @@ -14,6 +21,14 @@ class commonPipelineEnvironment implements Serializable { private String mtarFilePath + def setAppContainerProperty(property, value) { + appContainerProperties[property] = value + } + + def getAppContainerProperty(property) { + return appContainerProperties[property] + } + def setArtifactVersion(version) { artifactVersion = version } @@ -41,6 +56,22 @@ class commonPipelineEnvironment implements Serializable { return configProperties[property] } + def setGitCommitId(commitId) { + gitCommitId = commitId + } + + def getGitCommitId() { + return gitCommitId + } + + def setGitSshUrl(url) { + gitSshUrl = url + } + + def getGitSshUrl() { + return gitSshUrl + } + def getInfluxCustomData() { return influxCustomData } From 3bf3a2a9f55640b3981875bd840a70db0f7e8090 Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Wed, 7 Feb 2018 22:53:47 +0100 Subject: [PATCH 44/44] Update ConfigurationMergerTest.groovy --- test/groovy/com/sap/piper/ConfigurationMergerTest.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy index 1cccc02a9..125b18712 100644 --- a/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy +++ b/test/groovy/com/sap/piper/ConfigurationMergerTest.groovy @@ -52,7 +52,6 @@ class ConfigurationMergerTest { Assert.assertEquals(18, merged.fruits.apples) Assert.assertEquals(10, merged.fruits.oranges) Assert.assertEquals(1000, merged.fruits.cucumbers) - //Assert.assertEquals(null, merged.fruits.cucumbers) Assert.assertEquals(null, merged.veggie) } }