From 74366631b556c2da0f36c06f009aabaa1a949497 Mon Sep 17 00:00:00 2001 From: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Date: Tue, 5 Feb 2019 15:37:59 +0100 Subject: [PATCH] Project "Piper" Template: framework and structure (#476) * Project "Piper" Template: framework and structure This is the first in a series of Pull-Requests to provide a fully functional Pipeline template into the library. This PR contains: * general Pipeline structure incl. tests * Pipeline initialization incl. tests * Hollow pipeline stages incl. tests * first set of default values * add gitUrls to commonPipelineEnvironment * set correct git information on commonPipelineEnvironment --- .../com.sap.piper/pipeline/stageDefaults.yml | 20 + .../com.sap.piper/pipeline/stashSettings.yml | 14 + resources/default_pipeline_environment.yml | 3 +- test/groovy/CommonStepsTest.groovy | 7 +- test/groovy/PiperStageWrapperTest.groovy | 2 +- .../PiperInitRunStageConfigurationTest.groovy | 394 ++++++++++++++++++ .../PiperPipelineStageAcceptanceTest.groovy | 42 ++ ...ipelineStageAdditionalUnitTestsTest.groovy | 42 ++ .../PiperPipelineStageBuildTest.groovy | 42 ++ .../PiperPipelineStageComplianceTest.groovy | 42 ++ .../PiperPipelineStageInitTest.groovy | 151 +++++++ .../PiperPipelineStageIntegrationTest.groovy | 42 ++ .../PiperPipelineStagePRVotingTest.groovy | 42 ++ .../PiperPipelineStagePerformanceTest.groovy | 42 ++ .../PiperPipelineStagePromoteTest.groovy | 42 ++ .../PiperPipelineStageReleaseTest.groovy | 42 ++ .../PiperPipelineStageSecurityTest.groovy | 42 ++ .../groovy/templates/PiperPipelineTest.groovy | 233 +++++++++++ test/groovy/util/JenkinsSetupRule.groovy | 1 + test/groovy/util/PipelineWhenException.groovy | 10 + vars/commonPipelineEnvironment.groovy | 17 + vars/piperInitRunStageConfiguration.groovy | 100 +++++ vars/piperPipeline.groovy | 90 ++++ vars/piperPipelineStageAcceptance.groovy | 36 ++ ...perPipelineStageAdditionalUnitTests.groovy | 36 ++ vars/piperPipelineStageBuild.groovy | 36 ++ vars/piperPipelineStageCompliance.groovy | 36 ++ vars/piperPipelineStageInit.groovy | 112 +++++ vars/piperPipelineStageIntegration.groovy | 36 ++ vars/piperPipelineStagePRVoting.groovy | 36 ++ vars/piperPipelineStagePerformance.groovy | 36 ++ vars/piperPipelineStagePromote.groovy | 36 ++ vars/piperPipelineStageRelease.groovy | 36 ++ vars/piperPipelineStageSecurity.groovy | 36 ++ 34 files changed, 1931 insertions(+), 3 deletions(-) create mode 100644 resources/com.sap.piper/pipeline/stageDefaults.yml create mode 100644 resources/com.sap.piper/pipeline/stashSettings.yml create mode 100644 test/groovy/templates/PiperInitRunStageConfigurationTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageAcceptanceTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageAdditionalUnitTestsTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageBuildTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageComplianceTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageInitTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageIntegrationTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStagePRVotingTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStagePerformanceTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStagePromoteTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageReleaseTest.groovy create mode 100644 test/groovy/templates/PiperPipelineStageSecurityTest.groovy create mode 100644 test/groovy/templates/PiperPipelineTest.groovy create mode 100644 test/groovy/util/PipelineWhenException.groovy create mode 100644 vars/piperInitRunStageConfiguration.groovy create mode 100644 vars/piperPipeline.groovy create mode 100644 vars/piperPipelineStageAcceptance.groovy create mode 100644 vars/piperPipelineStageAdditionalUnitTests.groovy create mode 100644 vars/piperPipelineStageBuild.groovy create mode 100644 vars/piperPipelineStageCompliance.groovy create mode 100644 vars/piperPipelineStageInit.groovy create mode 100644 vars/piperPipelineStageIntegration.groovy create mode 100644 vars/piperPipelineStagePRVoting.groovy create mode 100644 vars/piperPipelineStagePerformance.groovy create mode 100644 vars/piperPipelineStagePromote.groovy create mode 100644 vars/piperPipelineStageRelease.groovy create mode 100644 vars/piperPipelineStageSecurity.groovy diff --git a/resources/com.sap.piper/pipeline/stageDefaults.yml b/resources/com.sap.piper/pipeline/stageDefaults.yml new file mode 100644 index 000000000..18e79ce58 --- /dev/null +++ b/resources/com.sap.piper/pipeline/stageDefaults.yml @@ -0,0 +1,20 @@ +stages: + 'Pull-Request Voting': {} + Build: {} + 'Additional Unit Tests': {} + Integration: {} + Acceptance: + stepConditions: + cloudFoundryDeploy: + config: 'cfSpace' + newmanExecute: + filePatternFromConfig: 'newmanCollection' + config: 'testRepository' + uiVeri5ExecuteTests: + filePattern: '**/conf.js' + config: 'testRepository' + Security: {} + Performance: {} + Compliance: {} + Promote: {} + Release: {} diff --git a/resources/com.sap.piper/pipeline/stashSettings.yml b/resources/com.sap.piper/pipeline/stashSettings.yml new file mode 100644 index 000000000..436be0b6c --- /dev/null +++ b/resources/com.sap.piper/pipeline/stashSettings.yml @@ -0,0 +1,14 @@ +Init: + unstash: [] + stashes: + - name: "source" + includes: "**/*" + excludes: ".pipeline/**" + +'Central Build': + unstash: ['source'] + stashes: [] + +'Pull-Request Voting': + unstash: ['source'] + stashes: [] diff --git a/resources/default_pipeline_environment.yml b/resources/default_pipeline_environment.yml index ca0ffa493..1d235a3e9 100644 --- a/resources/default_pipeline_environment.yml +++ b/resources/default_pipeline_environment.yml @@ -5,7 +5,6 @@ #Project Setup general: - productiveBranch: 'master' collectTelemetryData: true changeManagement: type: 'NONE' # SOLMAN, CTS, NONE @@ -22,6 +21,8 @@ general: gitSshKeyCredentialsId: '' #needed to allow sshagent to run with local ssh key jenkinsKubernetes: jnlpAgent: 's4sdk/jenkins-agent-k8s:latest' + manualConfirmation: true + productiveBranch: 'master' #Steps Specific Configuration steps: diff --git a/test/groovy/CommonStepsTest.groovy b/test/groovy/CommonStepsTest.groovy index fb991a311..194461b56 100644 --- a/test/groovy/CommonStepsTest.groovy +++ b/test/groovy/CommonStepsTest.groovy @@ -47,6 +47,7 @@ public class CommonStepsTest extends BasePiperTest{ 'commonPipelineEnvironment', 'handlePipelineStepErrors', 'pipelineExecute', + 'piperPipeline', 'prepareDefaultValues', 'setupCommonPipelineEnvironment', 'toolValidate', @@ -103,6 +104,7 @@ public class CommonStepsTest extends BasePiperTest{ 'toolValidate', // step is intended to be configured by other steps 'durationMeasure', // only expects parameters via signature 'prepareDefaultValues', // special step (infrastructure) + 'piperPipeline', // special step (infrastructure) 'pipelineStashFilesAfterBuild', // intended to be called from pipelineStashFiles 'pipelineStashFilesBeforeBuild', // intended to be called from pipelineStashFiles 'pipelineStashFiles', // only forwards to before/after step @@ -166,7 +168,10 @@ public class CommonStepsTest extends BasePiperTest{ @Test public void stepsWithWrongFieldNameTest() { - def whitelist = ['commonPipelineEnvironment'] + def whitelist = [ + 'commonPipelineEnvironment', + 'piperPipeline' + ] def stepsWithWrongStepName = [] diff --git a/test/groovy/PiperStageWrapperTest.groovy b/test/groovy/PiperStageWrapperTest.groovy index 9a66ea187..9bd507cab 100644 --- a/test/groovy/PiperStageWrapperTest.groovy +++ b/test/groovy/PiperStageWrapperTest.groovy @@ -113,7 +113,7 @@ class PiperStageWrapperTest extends BasePiperTest { assertThat(executed, is(true)) assertThat(loggingRule.log, containsString('[piperStageWrapper] Running project interceptor \'.pipeline/extensions/test.groovy\' for test.')) assertThat(loggingRule.log, containsString('Stage Name: test')) - assertThat(loggingRule.log, containsString('Config: [productiveBranch:master,')) + assertThat(loggingRule.log, containsString('Config: [')) assertThat(loggingRule.log, containsString('testBranch')) } } diff --git a/test/groovy/templates/PiperInitRunStageConfigurationTest.groovy b/test/groovy/templates/PiperInitRunStageConfigurationTest.groovy new file mode 100644 index 000000000..eb3b27cfd --- /dev/null +++ b/test/groovy/templates/PiperInitRunStageConfigurationTest.groovy @@ -0,0 +1,394 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsLoggingRule +import util.JenkinsReadYamlRule +import util.JenkinsStepRule +import util.Rules + +import static org.hamcrest.Matchers.* +import static org.junit.Assert.assertThat + +class PiperInitRunStageConfigurationTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + private JenkinsReadYamlRule jryr = new JenkinsReadYamlRule(this) + private ExpectedException thrown = new ExpectedException() + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(jryr) + .around(thrown) + .around(jlr) + .around(jsr) + + @Before + void init() { + + binding.variables.env.STAGE_NAME = 'Test' + + helper.registerAllowedMethod("findFiles", [Map.class], { map -> + switch (map.glob) { + case '**/conf.js': + return [new File('conf.js')].toArray() + case 'myCollection.json': + return [new File('myCollection.json')].toArray() + default: + return [].toArray() + } + }) + } + + @Test + void testStageConfig() { + helper.registerAllowedMethod('libraryResource', [String.class], {s -> + if(s == 'testDefault.yml') { + return ''' +stages: + testStage1: {} + testStage2: {} + testStage3: {} +''' + } else { + return ''' +general: {} +steps: {} +''' + } + }) + + nullScript.commonPipelineEnvironment.configuration = [ + stages: [ + testStage2: [testStage: 'myVal2'], + testStage3: [testStage: 'myVal3'] + ] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'testDefault.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(), + allOf( + containsInAnyOrder( + 'testStage2', + 'testStage3' + ), + hasSize(2) + ) + ) + } + + + @Test + void testConditionConfig() { + helper.registerAllowedMethod('libraryResource', [String.class], {s -> + if(s == 'testDefault.yml') { + return ''' +stages: + testStage1: + stepConditions: + firstStep: + config: testGeneral + testStage2: + stepConditions: + secondStep: + config: testStage + testStage3: + stepConditions: + thirdStep: + config: testStep + +''' + } else { + return ''' +general: {} +steps: {} +''' + } + }) + + nullScript.commonPipelineEnvironment.configuration = [ + general: [testGeneral: 'myVal1'], + stages: [testStage2: [testStage: 'myVal2']], + steps: [thirdStep: [testStep: 'myVal3']] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'testDefault.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(), + allOf( + containsInAnyOrder( + 'testStage1', + 'testStage2', + 'testStage3' + ), + hasSize(3) + ) + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage2.secondStep, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage3.thirdStep, is(true)) + + } + + @Test + void testConditionConfigValue() { + helper.registerAllowedMethod('libraryResource', [String.class], {s -> + if(s == 'testDefault.yml') { + return ''' +stages: + testStage1: + stepConditions: + firstStep: + config: + testGeneral: + - myValx + - myVal1 + testStage2: + stepConditions: + secondStep: + config: + testStage: + - maValXyz + testStage3: + stepConditions: + thirdStep: + config: + testStep: + - myVal3 + +''' + } else { + return ''' +general: {} +steps: {} +''' + } + }) + + nullScript.commonPipelineEnvironment.configuration = [ + general: [testGeneral: 'myVal1'], + stages: [:], + steps: [thirdStep: [testStep: 'myVal3']] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'testDefault.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(), + allOf( + containsInAnyOrder( + 'testStage1', + 'testStage3' + ), + hasSize(2) + ) + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage2?.secondStep, is(false)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage3.thirdStep, is(true)) + + } + + @Test + void testConditionFilePattern() { + helper.registerAllowedMethod('libraryResource', [String.class], {s -> + if(s == 'testDefault.yml') { + return ''' +stages: + testStage1: + stepConditions: + firstStep: + filePattern: \'**/conf.js\' + secondStep: + filePattern: \'**/conf.jsx\' + +''' + } else { + return ''' +general: {} +steps: {} +''' + } + }) + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'testDefault.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(), + allOf( + contains('testStage1'), + hasSize(1) + ) + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.secondStep, is(false)) + + } + + @Test + void testConditionFilePatternFromConfig() { + helper.registerAllowedMethod('libraryResource', [String.class], {s -> + if(s == 'testDefault.yml') { + return ''' +stages: + testStage1: + stepConditions: + firstStep: + filePatternFromConfig: myVal1 + secondStep: + filePatternFromConfig: myVal2 + +''' + } else { + return ''' +general: {} +steps: {} +''' + } + }) + + nullScript.commonPipelineEnvironment.configuration = [ + general: [:], + stages: [testStage1: [myVal1: '**/conf.js']] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'testDefault.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(), + allOf( + contains('testStage1'), + hasSize(1) + ) + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.secondStep, is(false)) + } + + @Test + void testVerboseOption() { + nullScript.commonPipelineEnvironment.configuration = [ + general: [verbose: true], + steps: [:], + stages: [ + Test: [:], + Integration: [test: 'test'], + Acceptance: [test: 'test'] + ] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml' + ) + + assertThat(jlr.log, allOf( + containsString('[piperInitRunStageConfiguration] Debug - Run Stage Configuration:'), + containsString('[piperInitRunStageConfiguration] Debug - Run Step Configuration:') + )) + } + + @Test + void testPiperInitDefault() { + + helper.registerAllowedMethod("findFiles", [Map.class], { map -> [].toArray() }) + + nullScript.commonPipelineEnvironment.configuration = [ + general: [:], + steps: [:], + stages: [ + Test: [:], + Integration: [test: 'test'], + Acceptance: [test: 'test'] + ] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.keySet(), + allOf( + containsInAnyOrder( + 'Acceptance', + 'Integration' + ), + hasSize(2) + ) + ) + + } + + @Test + void testPiperStepActivation() { + + nullScript.commonPipelineEnvironment.configuration = [ + general: [:], + steps: [ + cloudFoundryDeploy: [cfSpace: 'myTestSpace'], + newmanExecute: [newmanCollection: 'myCollection.json'] + ], + stages: [:] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml' + ) + + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.cloudFoundryDeploy, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.newmanExecute, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.newmanExecute, is(true)) + } + + @Test + void testPiperStepActivationWithStage() { + + nullScript.commonPipelineEnvironment.configuration = [ + general: [:], + steps: [:], + stages: [Acceptance: [cfSpace: 'test']] + ] + + jsr.step.piperInitRunStageConfiguration( + script: nullScript, + juStabUtils: utils, + stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml' + ) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.Acceptance.cloudFoundryDeploy, is(true)) + assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.Acceptance, is(true)) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageAcceptanceTest.groovy b/test/groovy/templates/PiperPipelineStageAcceptanceTest.groovy new file mode 100644 index 000000000..d27ed7d27 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageAcceptanceTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStageAcceptanceTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Acceptance' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageAdditionalUnitTestsTest.groovy b/test/groovy/templates/PiperPipelineStageAdditionalUnitTestsTest.groovy new file mode 100644 index 000000000..9b76e3a5d --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageAdditionalUnitTestsTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStageAdditionalUnitTestsTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Additional Unit Tests' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageBuildTest.groovy b/test/groovy/templates/PiperPipelineStageBuildTest.groovy new file mode 100644 index 000000000..8bfcf1c6a --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageBuildTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStageBuildTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Build' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageComplianceTest.groovy b/test/groovy/templates/PiperPipelineStageComplianceTest.groovy new file mode 100644 index 000000000..5fed00021 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageComplianceTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStageComplianceTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Compliance' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageInitTest.groovy b/test/groovy/templates/PiperPipelineStageInitTest.groovy new file mode 100644 index 000000000..12e7e63c3 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageInitTest.groovy @@ -0,0 +1,151 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.hasItems +import static org.hamcrest.Matchers.is +import static org.hamcrest.Matchers.isEmptyOrNullString +import static org.hamcrest.Matchers.not +import static org.junit.Assert.assertThat + +class PiperPipelineStageInitTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + private ExpectedException thrown = new ExpectedException() + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(thrown) + .around(jlr) + .around(jsr) + + private List stepsCalled = [] + + @Before + void init() { + + binding.variables.env.STAGE_NAME = 'Init' + + nullScript.commonPipelineEnvironment.configuration = [:] + + helper.registerAllowedMethod("findFiles", [Map.class], { map -> + switch (map.glob) { + case 'pom.xml': + return [new File('pom.xml')].toArray() + default: + return [].toArray() + } + }) + + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], { m, body -> + assertThat(m.stageName, is('Init')) + return body() + }) + + helper.registerAllowedMethod('checkout', [Closure.class], { c -> + stepsCalled.add('checkout') + return [GIT_BRANCH: 'master', GIT_COMMIT: 'testGitCommitId', GIT_URL: 'https://github.com/testOrg/testRepo'] + }) + binding.setVariable('scm', {}) + + helper.registerAllowedMethod('setupCommonPipelineEnvironment', [Map.class], { m -> + stepsCalled.add('setupCommonPipelineEnvironment') + }) + + helper.registerAllowedMethod('piperInitRunStageConfiguration', [Map.class], { m -> + assertThat(m.stageConfigResource, not(isEmptyOrNullString())) + stepsCalled.add('piperInitRunStageConfiguration') + }) + + helper.registerAllowedMethod('artifactSetVersion', [Map.class], { m -> + stepsCalled.add('artifactSetVersion') + }) + + helper.registerAllowedMethod('pipelineStashFilesBeforeBuild', [Map.class], { m -> + stepsCalled.add('pipelineStashFilesBeforeBuild') + }) + + } + + @Test + void testInitNoBuildTool() { + + thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTool') + jsr.step.piperPipelineStageInit( + script: nullScript, + juStabUtils: utils, + stashSettings: 'com.sap.piper/pipeline/stashSettings.yml' + ) + + } + + @Test + void testInitBuildToolDoesNotMatchProject() { + + thrown.expectMessage('[piperPipelineStageInit] buildTool configuration \'npm\' does not fit to your project, please set buildTool as genereal setting in your .pipeline/config.yml correctly, see also https://github.wdf.sap.corp/pages/ContinuousDelivery/piper-doc/configuration/') + jsr.step.piperPipelineStageInit( + script: nullScript, + juStabUtils: utils, + buildTool: 'npm', + stashSettings: 'com.sap.piper/pipeline/stashSettings.yml' + ) + + } + + @Test + void testInitDefault() { + + jsr.step.piperPipelineStageInit( + script: nullScript, + juStabUtils: utils, + buildTool: 'maven', + stashSettings: 'com.sap.piper/pipeline/stashSettings.yml' + ) + + assertThat(stepsCalled, hasItems('checkout', 'setupCommonPipelineEnvironment', 'piperInitRunStageConfiguration', 'artifactSetVersion', 'pipelineStashFilesBeforeBuild')) + + } + + @Test + void testInitOverwriteDefault() { + + binding.variables.env.BRANCH_NAME = 'testBranch' + + jsr.step.piperPipelineStageInit( + script: nullScript, + juStabUtils: utils, + buildTool: 'maven', + stashSettings: 'com.sap.piper/pipeline/stashSettings.yml' + ) + + assertThat(stepsCalled, hasItems('checkout', 'setupCommonPipelineEnvironment', 'piperInitRunStageConfiguration', 'pipelineStashFilesBeforeBuild')) + assertThat(stepsCalled, not(hasItems('artifactSetVersion'))) + + } + + @Test + void testSetScmInfoOnCommonPipelineEnvironment() { + //currently supported formats + def scmInfoTestList = [ + [GIT_URL: 'https://github.com/testOrg/testRepo.git', expectedSsh: 'git@github.com:testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'], + [GIT_URL: 'https://github.com:7777/testOrg/testRepo.git', expectedSsh: 'git@github.com:testOrg/testRepo.git', expectedHttp: 'https://github.com:7777/testOrg/testRepo.git'], + [GIT_URL: 'git@github.com:testOrg/testRepo.git', expectedSsh: 'git@github.com:testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'], + [GIT_URL: 'ssh://git@github.com/testOrg/testRepo.git', expectedSsh: 'ssh://git@github.com/testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'], + [GIT_URL: 'ssh://git@github.com:7777/testOrg/testRepo.git', expectedSsh: 'ssh://git@github.com:7777/testOrg/testRepo.git', expectedHttp: 'https://github.com/testOrg/testRepo.git'], + ] + + scmInfoTestList.each {scmInfoTest -> + jsr.step.piperPipelineStageInit.setScmInfoOnCommonPipelineEnvironment(nullScript, scmInfoTest) + assertThat(nullScript.commonPipelineEnvironment.getGitSshUrl(), is(scmInfoTest.expectedSsh)) + assertThat(nullScript.commonPipelineEnvironment.getGitHttpsUrl(), is(scmInfoTest.expectedHttp)) + } + } +} diff --git a/test/groovy/templates/PiperPipelineStageIntegrationTest.groovy b/test/groovy/templates/PiperPipelineStageIntegrationTest.groovy new file mode 100644 index 000000000..7b9591447 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageIntegrationTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.* +import static org.junit.Assert.assertThat + +class PiperPipelineStageIntegrationTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Integration' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStagePRVotingTest.groovy b/test/groovy/templates/PiperPipelineStagePRVotingTest.groovy new file mode 100644 index 000000000..82e7c5b75 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStagePRVotingTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStagePRVotingTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Pull-Request Voting' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStagePerformanceTest.groovy b/test/groovy/templates/PiperPipelineStagePerformanceTest.groovy new file mode 100644 index 000000000..64b73c860 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStagePerformanceTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStagePerformanceTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Performance' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStagePromoteTest.groovy b/test/groovy/templates/PiperPipelineStagePromoteTest.groovy new file mode 100644 index 000000000..9a84cf712 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStagePromoteTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStagePromoteTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Promote' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageReleaseTest.groovy b/test/groovy/templates/PiperPipelineStageReleaseTest.groovy new file mode 100644 index 000000000..bf1f02d3e --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageReleaseTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStageReleaseTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Release' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineStageSecurityTest.groovy b/test/groovy/templates/PiperPipelineStageSecurityTest.groovy new file mode 100644 index 000000000..b172b2ff6 --- /dev/null +++ b/test/groovy/templates/PiperPipelineStageSecurityTest.groovy @@ -0,0 +1,42 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.* + +import static org.hamcrest.Matchers.containsString +import static org.junit.Assert.assertThat + +class PiperPipelineStageSecurityTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jlr) + .around(jsr) + + @Before + void init() { + binding.variables.env.STAGE_NAME = 'Security' + helper.registerAllowedMethod('piperStageWrapper', [Map.class, Closure.class], {m, body -> + return body() + }) + } + + @Test + void testStageDefault() { + + jsr.step.piperPipelineStageIntegration( + script: nullScript, + juStabUtils: utils, + ) + assertThat(jlr.log, containsString('Stage implementation is not provided yet.')) + + } +} diff --git a/test/groovy/templates/PiperPipelineTest.groovy b/test/groovy/templates/PiperPipelineTest.groovy new file mode 100644 index 000000000..a91504ad8 --- /dev/null +++ b/test/groovy/templates/PiperPipelineTest.groovy @@ -0,0 +1,233 @@ +#!groovy +package templates + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsReadYamlRule +import util.JenkinsStepRule +import util.PipelineWhenException +import util.Rules + +import static org.hamcrest.Matchers.* +import static org.junit.Assert.assertThat + +class PiperPipelineTest extends BasePiperTest { + private JenkinsStepRule jsr = new JenkinsStepRule(this) + + @Rule + public RuleChain rules = Rules + .getCommonRules(this) + .around(new JenkinsReadYamlRule(this)) + .around(jsr) + + private skipDefaultCheckout = false + private timestamps = false + private stagesExecuted = [] + private stepsCalled = [] + + @Before + void init() { + + helper.registerAllowedMethod('library', [String.class], null) + + helper.registerAllowedMethod('pipeline', [Closure.class], null) + + helper.registerAllowedMethod('agent', [Closure.class], null) + binding.setVariable('any', {}) + binding.setVariable('none', {}) + + helper.registerAllowedMethod('options', [Closure.class], null) + + helper.registerAllowedMethod('skipDefaultCheckout', [], {skipDefaultCheckout = true}) + helper.registerAllowedMethod('timestamps', [], {timestamps = true}) + + helper.registerAllowedMethod('stages', [Closure.class], null) + + helper.registerAllowedMethod('stage', [String.class, Closure.class], {stageName, body -> + + def stageResult + + binding.variables.env.STAGE_NAME = stageName + + helper.registerAllowedMethod('when', [Closure.class], {cWhen -> + + helper.registerAllowedMethod('allOf', [Closure.class], null) + + helper.registerAllowedMethod('anyOf', [Closure.class], {cAnyOf -> + def result = false + helper.registerAllowedMethod('branch', [String.class], {branchName -> + if (!result) + result = (branchName == env.BRANCH_NAME) + if( !result) { + throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${result}'") + } + }) + return cAnyOf() + }) + + helper.registerAllowedMethod('branch', [String.class], {branchName -> + def result = (branchName == env.BRANCH_NAME) + if(result == false) { + throw new PipelineWhenException("Stage '${stageName}' skipped - expected branch: '${branchName}' while current branch: '${env.BRANCH_NAME}'") + } + return result + }) + + helper.registerAllowedMethod('expression', [Closure.class], { Closure cExp -> + def result = cExp() + if(!result) { + throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${result}'") + } + return result + }) + return cWhen() + }) + + // Stage is not executed if build fails or aborts + def status = currentBuild.result + switch (status) { + case 'FAILURE': + case 'ABORTED': + break + default: + try { + stageResult = body() + stagesExecuted.add(stageName) + } + catch (PipelineWhenException pwe) { + //skip stage due to not met when expression + } + catch (Exception e) { + throw e + } + } + return stageResult + }) + + helper.registerAllowedMethod('steps', [Closure], null) + helper.registerAllowedMethod('post', [Closure], null) + helper.registerAllowedMethod('always', [Closure], null) + + helper.registerAllowedMethod('input', [Map], {m -> return null}) + + helper.registerAllowedMethod('influxWriteData', [Map], {m -> + assertThat(m.wrapInNode, is(true)) + }) + helper.registerAllowedMethod('mailSendNotification', [Map], {m -> + assertThat(m.wrapInNode, is(true)) + }) + + helper.registerAllowedMethod('piperPipelineStageInit', [Map.class], {m -> + stepsCalled.add('piperPipelineStageInit') + }) + helper.registerAllowedMethod('piperPipelineStagePRVoting', [Map.class], {m -> + stepsCalled.add('piperPipelineStagePRVoting') + }) + helper.registerAllowedMethod('piperPipelineStageBuild', [Map.class], {m -> + stepsCalled.add('piperPipelineStageBuild') + }) + helper.registerAllowedMethod('piperPipelineStageAdditionalUnitTests', [Map.class], {m -> + stepsCalled.add('piperPipelineStageAdditionalUnitTests') + }) + helper.registerAllowedMethod('piperPipelineStageIntegration', [Map.class], {m -> + stepsCalled.add('piperPipelineStageIntegration') + }) + helper.registerAllowedMethod('piperPipelineStageAcceptance', [Map.class], {m -> + stepsCalled.add('piperPipelineStageAcceptance') + }) + helper.registerAllowedMethod('piperPipelineStageSecurity', [Map.class], {m -> + stepsCalled.add('piperPipelineStageSecurity') + }) + helper.registerAllowedMethod('piperPipelineStagePerformance', [Map.class], {m -> + stepsCalled.add('piperPipelineStagePerformance') + }) + helper.registerAllowedMethod('piperPipelineStageCompliance', [Map.class], {m -> + stepsCalled.add('piperPipelineStageCompliance') + }) + helper.registerAllowedMethod('input', [Map.class], {m -> + stepsCalled.add('input') + }) + helper.registerAllowedMethod('piperPipelineStagePromote', [Map.class], {m -> + stepsCalled.add('piperPipelineStagePromote') + }) + helper.registerAllowedMethod('piperPipelineStageRelease', [Map.class], {m -> + stepsCalled.add('piperPipelineStageRelease') + }) + + nullScript.prepareDefaultValues(script: nullScript) + + } + + @Test + void testPRVoting() { + + helper.registerAllowedMethod('piperPipelineStageInit', [Map], null) + + binding.variables.env.BRANCH_NAME = 'PR-*' + + nullScript.commonPipelineEnvironment.configuration = [runStage:[Integration:[test: 'test']]] + jsr.step.piperPipeline(script: nullScript) + + assertThat(skipDefaultCheckout, is(true)) + assertThat(timestamps, is(true)) + + assertThat(stagesExecuted.size(), is(2)) + assertThat(stagesExecuted, allOf(hasItem('Init'), hasItem('Pull-Request Voting'))) + + assertThat(stepsCalled, hasItem('piperPipelineStagePRVoting')) + } + + @Test + void testConfirm() { + jsr.step.piperPipeline(script: nullScript) + + assertThat(stepsCalled, hasItem('input')) + + } + + @Test + void testNoConfirm() { + nullScript.commonPipelineEnvironment.configuration = [ + general: [ + manualConfirmation: false + ] + ] + jsr.step.piperPipeline(script: nullScript) + + assertThat(stepsCalled, not(hasItem('input'))) + } + + @Test + void testMasterPipelineAllOn() { + + nullScript.commonPipelineEnvironment.configuration.runStage = [ + Build: true, + 'Additional Unit Tests': true, + Integration: true, + Acceptance: true, + Security: true, + Performance: true, + Compliance: true, + Promote: true, + Release: true + ] + jsr.step.piperPipeline(script: nullScript) + + assertThat(stepsCalled, hasItems( + 'piperPipelineStageInit', + 'piperPipelineStageBuild', + 'piperPipelineStageAdditionalUnitTests', + 'piperPipelineStageIntegration', + 'piperPipelineStageAcceptance', + 'piperPipelineStageSecurity', + 'piperPipelineStagePerformance', + 'piperPipelineStageCompliance', + 'input', + 'piperPipelineStagePromote', + 'piperPipelineStageRelease' + )) + } +} diff --git a/test/groovy/util/JenkinsSetupRule.groovy b/test/groovy/util/JenkinsSetupRule.groovy index 5f2f5132c..a4f55105a 100644 --- a/test/groovy/util/JenkinsSetupRule.groovy +++ b/test/groovy/util/JenkinsSetupRule.groovy @@ -41,6 +41,7 @@ class JenkinsSetupRule implements TestRule { JOB_NAME : 'p', BUILD_NUMBER: '1', BUILD_URL : 'http://build.url', + BRANCH_NAME: 'master' ]) base.evaluate() diff --git a/test/groovy/util/PipelineWhenException.groovy b/test/groovy/util/PipelineWhenException.groovy new file mode 100644 index 000000000..7a22607f9 --- /dev/null +++ b/test/groovy/util/PipelineWhenException.groovy @@ -0,0 +1,10 @@ +package util + +import hudson.AbortException + +class PipelineWhenException extends AbortException{ + public PipelineWhenException(String message) + { + super(message); + } +} diff --git a/vars/commonPipelineEnvironment.groovy b/vars/commonPipelineEnvironment.groovy index 16b863b03..a636a168a 100644 --- a/vars/commonPipelineEnvironment.groovy +++ b/vars/commonPipelineEnvironment.groovy @@ -1,3 +1,6 @@ +import com.sap.piper.ConfigurationLoader +import com.sap.piper.ConfigurationMerger + class commonPipelineEnvironment implements Serializable { Map configProperties = [:] @@ -134,4 +137,18 @@ class commonPipelineEnvironment implements Serializable { def getPipelineMeasurement(key) { return influxCustomDataMap.pipeline_data[key] } + + Map getStepConfiguration(stepName, stageName = env.STAGE_NAME, includeDefaults = true) { + Map defaults = [:] + if (includeDefaults) { + defaults = ConfigurationLoader.defaultGeneralConfiguration() + defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStepConfiguration(null, stepName), null, defaults) + defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStageConfiguration(null, stageName), null, defaults) + } + Map config = ConfigurationMerger.merge(configuration.get('general') ?: [:], null, defaults) + config = ConfigurationMerger.merge(configuration.get('steps')?.get(stepName) ?: [:], null, config) + config = ConfigurationMerger.merge(configuration.get('stages')?.get(stageName) ?: [:], null, config) + return config + } + } diff --git a/vars/piperInitRunStageConfiguration.groovy b/vars/piperInitRunStageConfiguration.groovy new file mode 100644 index 000000000..d23b5c274 --- /dev/null +++ b/vars/piperInitRunStageConfiguration.groovy @@ -0,0 +1,100 @@ +import com.sap.piper.ConfigurationLoader + +import static com.sap.piper.Prerequisites.checkScript + +import com.sap.piper.ConfigurationHelper +import groovy.transform.Field + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [ + /** + * Print more detailed information into the log. + * @possibleValues `true`, `false` + */ + 'verbose' +] + +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([ + /** + * Defines the library resource that contains the stage configuration settings + */ + 'stageConfigResource' + +]) + +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def stageName = parameters.stageName?:env.STAGE_NAME + + script.commonPipelineEnvironment.configuration.runStage = [:] + script.commonPipelineEnvironment.configuration.runStep = [:] + + // load default & individual configuration + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .withMandatoryProperty('stageConfigResource') + .use() + + + config.stages = (readYaml(text: libraryResource(config.stageConfigResource))).stages + + //handling of stage and step activation + config.stages.each {stage -> + + //activate stage if stage configuration is available + if (ConfigurationLoader.stageConfiguration(script, stage.getKey())) { + script.commonPipelineEnvironment.configuration.runStage[stage.getKey()] = true + } + //------------------------------------------------------------------------------- + //detailed handling of step and stage activation based on conditions + script.commonPipelineEnvironment.configuration.runStep[stage.getKey()] = [:] + def currentStage = stage.getKey() + stage.getValue().stepConditions.each {step -> + def stepActive = false + step.getValue().each {condition -> + switch(condition.getKey()) { + case 'config': + if (condition.getValue() instanceof Map) { + condition.getValue().each {configCondition -> + if (script.commonPipelineEnvironment.getStepConfiguration(step.getKey(), currentStage)?.get(configCondition.getKey()) in configCondition.getValue()) { + stepActive = true + } + } + } else if (script.commonPipelineEnvironment.getStepConfiguration(step.getKey(), currentStage)?.get(condition.getValue())) { + stepActive = true + } + break + case 'filePatternFromConfig': + def conditionValue=script.commonPipelineEnvironment.getStepConfiguration(step.getKey(), currentStage)?.get(condition.getValue()) + if (conditionValue && findFiles(glob: conditionValue)) { + stepActive = true + } + break + case 'filePattern': + if (findFiles(glob: condition.getValue())) { + stepActive = true + } + break + } + } + script.commonPipelineEnvironment.configuration.runStep."${stage.getKey()}"."${step.getKey()}" = stepActive + + //make sure that also related stage is activated if steps are active + if (stepActive) script.commonPipelineEnvironment.configuration.runStage[stage.getKey()] = true + + } + } + + if (config.verbose) { + echo "[${STEP_NAME}] Debug - Run Stage Configuration: ${script.commonPipelineEnvironment.configuration.runStage}" + echo "[${STEP_NAME}] Debug - Run Step Configuration: ${script.commonPipelineEnvironment.configuration.runStep}" + } +} diff --git a/vars/piperPipeline.groovy b/vars/piperPipeline.groovy new file mode 100644 index 000000000..557760d61 --- /dev/null +++ b/vars/piperPipeline.groovy @@ -0,0 +1,90 @@ +void call(parameters) { + pipeline { + agent none + options { + skipDefaultCheckout() + timestamps() + } + stages { + stage('Init') { + steps { + library 'piper-lib-os' + piperPipelineStageInit script: parameters.script, customDefaults: parameters.customDefaults + } + } + stage('Pull-Request Voting') { + when { anyOf { branch 'PR-*'; branch parameters.script.commonPipelineEnvironment.getStepConfiguration('piperPipelineStagePRVoting', 'Pull-Request Voting').customVotingBranch } } + steps { + piperPipelineStagePRVoting script: parameters.script + } + } + stage('Build') { + when {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch} + steps { + piperPipelineStageBuild script: parameters.script + } + } + stage('Additional Unit Tests') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStageAdditionalUnitTests script: parameters.script + } + } + stage('Integration') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStageIntegration script: parameters.script + } + } + stage('Acceptance') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStageAcceptance script: parameters.script + } + } + stage('Security') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStageSecurity script: parameters.script + } + } + stage('Performance') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStagePerformance script: parameters.script + } + } + stage('Compliance') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStageCompliance script: parameters.script + } + } + stage('Confirm') { + agent none + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.getStepConfiguration('piperInitRunStageConfiguration', env.STAGE_NAME).manualConfirmation}}} + steps { + input message: 'Shall we proceed to promotion & release?' + } + } + stage('Promote') { + when { branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch} + steps { + piperPipelineStagePromote script: parameters.script + } + } + stage('Release') { + when {allOf {branch parameters.script.commonPipelineEnvironment.getStepConfiguration('', '').productiveBranch; expression {return parameters.script.commonPipelineEnvironment.configuration.runStage?.get(env.STAGE_NAME)}}} + steps { + piperPipelineStageRelease script: parameters.script + } + } + } + post { + always { + influxWriteData script: parameters.script, wrapInNode: true + mailSendNotification script: parameters.script, wrapInNode: true + } + } + } +} diff --git a/vars/piperPipelineStageAcceptance.groovy b/vars/piperPipelineStageAcceptance.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageAcceptance.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStageAdditionalUnitTests.groovy b/vars/piperPipelineStageAdditionalUnitTests.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageAdditionalUnitTests.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStageBuild.groovy b/vars/piperPipelineStageBuild.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageBuild.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStageCompliance.groovy b/vars/piperPipelineStageCompliance.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageCompliance.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStageInit.groovy b/vars/piperPipelineStageInit.groovy new file mode 100644 index 000000000..8016e4ff3 --- /dev/null +++ b/vars/piperPipelineStageInit.groovy @@ -0,0 +1,112 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [ + 'buildTool', + 'productiveBranch', + 'stashSettings', + 'verbose' +] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + piperStageWrapper (script: script, stageName: stageName, stashContent: [], ordinal: 1) { + def scmInfo = checkout scm + + setupCommonPipelineEnvironment script: script, customDefaults: parameters.customDefaults + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .addIfEmpty('stageConfigResource', 'com.sap.piper/pipeline/stageDefaults.yml') + .addIfEmpty('stashSettings', 'com.sap.piper/pipeline/stashSettings.yml') + .withMandatoryProperty('buildTool') + .use() + + //perform stashing based on libray resource piper-stash-settings.yml if not configured otherwise + initStashConfiguration(script, config) + + setScmInfoOnCommonPipelineEnvironment(script, scmInfo) + script.commonPipelineEnvironment.setGitCommitId(scmInfo.GIT_COMMIT) + + if (config.verbose) { + echo "piper-lib-os configuration: ${script.commonPipelineEnvironment.configuration}" + } + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + checkBuildTool(config) + + piperInitRunStageConfiguration script: script, stageConfigResource: config.stageConfigResource + + if (env.BRANCH_NAME == config.productiveBranch) { + artifactSetVersion script: script + } + + pipelineStashFilesBeforeBuild script: script + + } +} + +private void checkBuildTool(config) { + def buildDescriptorPattern = '' + switch (config.buildTool) { + case 'maven': + buildDescriptorPattern = 'pom.xml' + break + case 'npm': + buildDescriptorPattern = 'package.json' + break + case 'mta': + buildDescriptorPattern = 'mta.yaml' + break + } + if (buildDescriptorPattern && !findFiles(glob: buildDescriptorPattern)) { + error "[${STEP_NAME}] buildTool configuration '${config.buildTool}' does not fit to your project, please set buildTool as genereal setting in your .pipeline/config.yml correctly, see also https://github.wdf.sap.corp/pages/ContinuousDelivery/piper-doc/configuration/" + } +} + +private void initStashConfiguration (script, config) { + Map stashConfiguration = readYaml(text: libraryResource(config.stashSettings)) + echo "Stash config: stashConfiguration" + script.commonPipelineEnvironment.configuration.stageStashes = stashConfiguration +} + +private void setScmInfoOnCommonPipelineEnvironment(script, scmInfo) { + + def gitUrl = scmInfo.GIT_URL + + if (gitUrl.startsWith('http')) { + def httpPattern = /(https?):\/\/([^:\/]+)(?:[:\d\/]*)(.*)/ + def gitMatcher = gitUrl =~ httpPattern + if (!gitMatcher.hasGroup() && gitMatcher.groupCount() != 3) return + script.commonPipelineEnvironment.setGitSshUrl("git@${gitMatcher[0][2]}:${gitMatcher[0][3]}") + script.commonPipelineEnvironment.setGitHttpsUrl(gitUrl) + } else if (gitUrl.startsWith('ssh')) { + //(.*)@([^:\/]*)(?:[:\d\/]*)(.*) + def httpPattern = /(.*)@([^:\/]*)(?:[:\d\/]*)(.*)/ + def gitMatcher = gitUrl =~ httpPattern + if (!gitMatcher.hasGroup() && gitMatcher.groupCount() != 3) return + script.commonPipelineEnvironment.setGitSshUrl(gitUrl) + script.commonPipelineEnvironment.setGitHttpsUrl("https://${gitMatcher[0][2]}/${gitMatcher[0][3]}") + } + else if (gitUrl.indexOf('@') > 0) { + script.commonPipelineEnvironment.setGitSshUrl(gitUrl) + script.commonPipelineEnvironment.setGitHttpsUrl("https://${(gitUrl.split('@')[1]).replace(':', '/')}") + } +} diff --git a/vars/piperPipelineStageIntegration.groovy b/vars/piperPipelineStageIntegration.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageIntegration.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStagePRVoting.groovy b/vars/piperPipelineStagePRVoting.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStagePRVoting.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStagePerformance.groovy b/vars/piperPipelineStagePerformance.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStagePerformance.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStagePromote.groovy b/vars/piperPipelineStagePromote.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStagePromote.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStageRelease.groovy b/vars/piperPipelineStageRelease.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageRelease.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +} diff --git a/vars/piperPipelineStageSecurity.groovy b/vars/piperPipelineStageSecurity.groovy new file mode 100644 index 000000000..1fb641a4f --- /dev/null +++ b/vars/piperPipelineStageSecurity.groovy @@ -0,0 +1,36 @@ +import com.sap.piper.ConfigurationHelper +import com.sap.piper.Utils +import groovy.transform.Field + +import static com.sap.piper.Prerequisites.checkScript + +@Field String STEP_NAME = getClass().getName() + +@Field Set GENERAL_CONFIG_KEYS = [] +@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([]) +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + + def script = checkScript(this, parameters) ?: this + def utils = parameters.juStabUtils ?: new Utils() + + def stageName = parameters.stageName?:env.STAGE_NAME + + Map config = ConfigurationHelper.newInstance(this) + .loadStepDefaults() + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) + .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS) + .mixin(parameters, PARAMETER_KEYS) + .use() + + piperStageWrapper (script: script, stageName: stageName) { + + // telemetry reporting + utils.pushToSWA([step: STEP_NAME], config) + + //ToDO: provide stage implementation + echo "${STEP_NAME}: Stage implementation is not provided yet. You can extend the stage using the provided stage extension mechanism." + + } +}