1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-02-11 13:53:53 +02:00

Enable Jenkins to use checkIfStepActive go step (#3931)

* Extend checkIfStepActive

* adapt default format in abap Tests
Co-authored-by: dominiklendle <d.lendle@sap.com>
Co-authored-by: “Raman <“raman_susla@epam.com”>
This commit is contained in:
Ashly Mathew 2022-08-29 11:39:08 +02:00 committed by GitHub
parent 5e305eca40
commit b75d6cf9ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 347 additions and 739 deletions

View File

@ -1,12 +1,13 @@
stages:
Init: {}
Initial Checks: {}
Prepare System: {}
AUnit: {}
ATC: {}
Clone Repositories: {}
Build: {}
Integration Tests: {}
Confirm: {}
Publish: {}
Post: {}
spec:
stages:
- displayName: Init
- displayName: Initial Checks
- displayName: Prepare System
- displayName: AUnit
- displayName: ATC
- displayName: Clone Repositories
- displayName: Build
- displayName: Integration Tests
- displayName: Confirm
- displayName: Publish
- displayName: Post

View File

@ -1,121 +1,128 @@
stages:
Init:
stepConditions:
slackSendNotification:
configKeys:
- 'channel'
'Pull-Request Voting':
stepConditions:
sonarExecuteScan:
filePattern: '**/sonar-project.properties'
mavenExecuteIntegration:
filePattern: 'integration-tests/pom.xml'
npmExecuteScripts:
configKeys:
- 'runScripts'
Build:
stepConditions:
sonarExecuteScan:
filePattern: '**/sonar-project.properties'
'Additional Unit Tests':
stepConditions:
batsExecuteTests:
filePattern: '**/*.bats'
karmaExecuteTests:
filePattern: '**/karma.conf.js'
npmExecuteScripts:
configKeys:
- 'runScripts'
Integration:
stepConditions:
npmExecuteScripts:
configKeys:
- 'runScripts'
mavenExecuteIntegration:
filePattern: 'integration-tests/pom.xml'
Acceptance:
stepConditions:
multicloudDeploy:
configKeys:
- 'cfTargets'
- 'neoTargets'
cloudFoundryDeploy:
configKeys:
- 'cfSpace'
- 'cloudFoundry/space'
healthExecuteCheck:
configKeys:
- 'testServerUrl'
newmanExecute:
filePatternFromConfig: 'newmanCollection'
configKeys:
- 'testRepository'
uiVeri5ExecuteTests:
filePattern: '**/conf.js'
configKeys:
- 'testRepository'
npmExecuteEndToEndTests:
configKeys:
- 'appUrls'
Security:
stepConditions:
checkmarxExecuteScan:
configKeys:
- 'checkmarxCredentialsId'
fortifyExecuteScan:
configKeys:
- 'fortifyCredentialsId'
whitesourceExecuteScan:
configKeys:
- 'userTokenCredentialsId'
- 'whitesource/userTokenCredentialsId'
- 'whitesourceUserTokenCredentialsId'
Performance:
stepConditions:
multicloudDeploy:
configKeys:
- 'cfTargets'
- 'neoTargets'
gatlingExecuteTests:
filePatternFromConfig: 'pomPath'
configKeys:
- 'appUrls'
Compliance: {}
Promote:
stepConditions:
containerPushToRegistry:
configKeys:
- 'dockerRegistryUrl'
nexusUpload:
configKeys:
- 'url'
Release:
stepConditions:
multicloudDeploy:
configKeys:
- 'cfTargets'
- 'neoTargets'
cloudFoundryDeploy:
configKeys:
- 'cfSpace'
- 'cloudFoundry/space'
neoDeploy:
configKeys:
- 'neo/account'
tmsUpload:
configKeys:
- nodeName
healthExecuteCheck:
configKeys:
- 'testServerUrl'
npmExecuteEndToEndTests:
configKeys:
- 'appUrls'
githubPublishRelease:
configKeys:
- 'githubTokenCredentialsId'
'Post Actions':
stepConditions:
slackSendNotification:
configKeys:
- 'channel'
spec:
stages:
- displayName: Init
steps:
- name: slackSendNotification
conditions:
- configKey: 'channel'
- displayName: Pull-Request Voting
steps:
- name: sonarExecuteScan
conditions:
- filePattern: '**/sonar-project.properties'
- name: mavenExecuteIntegration
conditions:
- filePattern: 'integration-tests/pom.xml'
- name: npmExecuteScripts
conditions:
- configKey: 'runScripts'
- displayName: Build
steps:
- name: sonarExecuteScan
conditions:
- filePattern: '**/sonar-project.properties'
- displayName: Additional Unit Tests
steps:
- name: batsExecuteTests
conditions:
- filePattern: '**/*.bats'
- name: karmaExecuteTests
conditions:
- filePattern: '**/karma.conf.js'
- name: npmExecuteScripts
conditions:
- configKey: 'runScripts'
- displayName: Integration
steps:
- name: npmExecuteScripts
conditions:
- configKey: 'runScripts'
- name: mavenExecuteIntegration
conditions:
- filePattern: 'integration-tests/pom.xml'
- displayName: Acceptance
steps:
- name: multicloudDeploy
conditions:
- configKey: 'cfTargets'
- configKey: 'neoTargets'
- name: cloudFoundryDeploy
conditions:
- configKey: 'cfSpace'
- configKey: 'cloudFoundry/space'
- name: healthExecuteCheck
conditions:
- configKey: 'testServerUrl'
- name: newmanExecute
conditions:
- filePatternFromConfig: 'newmanCollection'
- configKey: 'testRepository'
- name: uiVeri5ExecuteTests
conditions:
- filePattern: '**/conf.js'
- configKey: 'testRepository'
- name: npmExecuteEndToEndTests
conditions:
- configKey: 'appUrls'
- displayName: Security
steps:
- name: checkmarxExecuteScan
conditions:
- configKey: 'checkmarxCredentialsId'
- name: fortifyExecuteScan
conditions:
- configKey: 'fortifyCredentialsId'
- name: whitesourceExecuteScan
conditions:
- configKey: 'userTokenCredentialsId'
- configKey: 'whitesource/userTokenCredentialsId'
- configKey: 'whitesourceUserTokenCredentialsId'
- displayName: Performance
steps:
- name: multicloudDeploy
conditions:
- configKey: 'cfTargets'
- configKey: 'neoTargets'
- name: gatlingExecuteTests
conditions:
- filePatternFromConfig: 'pomPath'
- configKey: 'appUrls'
- displayName: Compliance
- displayName: Promote
steps:
- name: containerPushToRegistry
conditions:
- configKey: 'dockerRegistryUrl'
- name: nexusUpload
conditions:
- configKey: 'url'
- displayName: Release
steps:
- name: multicloudDeploy
conditions:
- configKey: 'cfTargets'
- configKey: 'neoTargets'
- name: cloudFoundryDeploy
conditions:
- configKey: 'cfSpace'
- configKey: 'cloudFoundry/space'
- name: neoDeploy
conditions:
- configKey: 'neo/account'
- name: tmsUpload
conditions:
- configKey: nodeName
- name: healthExecuteCheck
conditions:
- configKey: 'testServerUrl'
- name: npmExecuteEndToEndTests
conditions:
- configKey: 'appUrls'
- name: githubPublishRelease
conditions:
- configKey: 'githubTokenCredentialsId'
- displayName: Post Actions
steps:
- name: slackSendNotification
conditions:
- configKey: 'channel'

View File

@ -1,6 +1,7 @@
package templates
import org.junit.Before
import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
@ -10,6 +11,9 @@ import util.JenkinsStepRule
import util.PipelineWhenException
import org.junit.rules.ExpectedException
import util.Rules
import util.JenkinsShellCallRule
import com.sap.piper.PiperGoUtils
import com.sap.piper.Utils
import static org.hamcrest.Matchers.*
import static org.junit.Assert.assertThat
@ -21,6 +25,8 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
private List stepsCalled = []
private List activeStages = []
private ExpectedException thrown = new ExpectedException()
private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this)
private PiperGoUtils piperGoUtils = new PiperGoUtils(utils) { void unstashPiperBin() { }}
@Rule
public RuleChain rules = Rules
@ -28,12 +34,21 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
.around(readYamlRule)
.around(thrown)
.around(jsr)
.around(shellCallRule)
@After
public void tearDown() {
Utils.metaClass = null
}
@Before
void init() {
Utils.metaClass.unstash = { def n -> ["dummy"] }
binding.variables.env.STAGE_NAME = 'Init'
helper.registerAllowedMethod('deleteDir', [], null)
helper.registerAllowedMethod("writeFile", [Map.class], null)
helper.registerAllowedMethod("readJSON", [Map.class],null)
helper.registerAllowedMethod('setupCommonPipelineEnvironment', [Map.class], { m ->
stepsCalled.add('setupCommonPipelineEnvironment')
@ -54,14 +69,16 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
stepsCalled('activateStage')
activeStages.add(m)
})
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 0)
nullScript.prepareDefaultValues(script: nullScript)
}
@Test
void testStageConfigurationToggleFalse() {
jsr.step.abapEnvironmentPipelineStageInit(script: nullScript, skipCheckout: false)
jsr.step.abapEnvironmentPipelineStageInit(script: nullScript, skipCheckout: false, piperGoUtils: piperGoUtils)
assertThat(stepsCalled, hasItems('setupCommonPipelineEnvironment', 'checkout'))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test
@ -70,16 +87,20 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
script: nullScript,
skipCheckout: true,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stashContent: ['mystash']
)
assertThat(stepsCalled, not(hasItems('checkout')))
assertThat(stepsCalled, hasItems('setupCommonPipelineEnvironment'))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test
void testSkipCheckoutToggleNull() {
jsr.step.abapEnvironmentPipelineStageInit(script: nullScript, skipCheckout: null)
jsr.step.abapEnvironmentPipelineStageInit(script: nullScript, skipCheckout: null, piperGoUtils: piperGoUtils)
assertThat(stepsCalled, hasItems('setupCommonPipelineEnvironment', 'checkout'))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test
@ -95,7 +116,8 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
jsr.step.abapEnvironmentPipelineStageInit(
script: nullScript,
juStabUtils: utils,
skipCheckout: "false"
skipCheckout: "false",
piperGoUtils: piperGoUtils
)
}
@ -106,7 +128,8 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
jsr.step.abapEnvironmentPipelineStageInit(
script: nullScript,
juStabUtils: utils,
skipCheckout: true
skipCheckout: true,
piperGoUtils: piperGoUtils
)
}
@ -118,7 +141,8 @@ class abapEnvironmentPipelineStageInitTest extends BasePiperTest {
script: nullScript,
juStabUtils: utils,
skipCheckout: true,
stashContent: []
stashContent: [],
piperGoUtils: piperGoUtils
)
}

View File

@ -10,6 +10,8 @@ import util.JenkinsLoggingRule
import util.JenkinsReadYamlRule
import util.JenkinsStepRule
import util.Rules
import util.JenkinsShellCallRule
import com.sap.piper.PiperGoUtils
import static org.hamcrest.Matchers.*
import static org.junit.Assert.assertThat
@ -19,15 +21,16 @@ class PiperInitRunStageConfigurationTest extends BasePiperTest {
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
private JenkinsReadYamlRule jryr = new JenkinsReadYamlRule(this)
private ExpectedException thrown = new ExpectedException()
private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this)
private PiperGoUtils piperGoUtils = new PiperGoUtils(utils) { void unstashPiperBin() { }}
@Rule
public RuleChain rules = Rules
.getCommonRules(this)
.around(jryr)
.around(thrown)
.around(shellCallRule)
.around(jlr)
.around(jsr)
@Before
void init() {
@ -43,328 +46,24 @@ class PiperInitRunStageConfigurationTest extends BasePiperTest {
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.testStage1, is(false))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage2, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage3, is(true))
}
@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.testStage1, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage2, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage3, is(true))
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.testStage1, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage2, is(false))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage3, is(true))
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 testConditionConfigKeys() {
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
stepConditions:
firstStep:
configKeys:
- myKey1_1
- myKey1_2
testStage2:
stepConditions:
secondStep:
configKeys:
- myKey2_1
testStage3:
stepConditions:
thirdStep:
configKeys:
- myKey3_1
'''
} else {
return '''
general: {}
steps: {}
'''
}
})
nullScript.commonPipelineEnvironment.configuration = [
general: [myKey1_1: 'myVal1_1'],
stages: [:],
steps: [thirdStep: [myKey3_1: 'myVal3_1']]
]
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
stageConfigResource: 'testDefault.yml'
)
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage1, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage2, is(false))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage3, is(true))
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 testConditionFilePatternWithList() {
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
stepConditions:
firstStep:
filePattern:
- \'**/conf.js\'
- \'myCollection.json\'
secondStep:
filePattern: \'**/conf.jsx\'
'''
} else {
return '''
general: {}
steps: {}
'''
}
})
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
stageConfigResource: 'testDefault.yml'
)
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))
helper.registerAllowedMethod("writeFile", [Map.class], null)
}
@Test
void testVerboseOption() {
nullScript.commonPipelineEnvironment.configuration = [
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 0)
helper.registerAllowedMethod("readJSON", [Map.class], { m ->
if (m.containsValue(".pipeline/stage_out.json")) {
return ["testStage1":false]
} else {
if (m.containsValue(".pipeline/step_out.json")) {
return [:]
}
return [:]
}
})
nullScript.commonPipelineEnvironment.configuration = [
general: [verbose: true],
steps: [:],
stages: [
@ -377,6 +76,7 @@ steps: {}
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
)
@ -384,11 +84,49 @@ steps: {}
containsString('[piperInitRunStageConfiguration] Debug - Run Stage Configuration:'),
containsString('[piperInitRunStageConfiguration] Debug - Run Step Configuration:')
))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test(expected = Exception.class)
void testPiperShFailed() {
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 1)
helper.registerAllowedMethod("readJSON", [Map.class], { m ->
if (m.containsValue(".pipeline/stage_out.json")) {
return ["Integration":true, "Acceptance":true]
} else {
if (m.containsValue(".pipeline/step_out.json")) {
return [ Integration: [test: true], Acceptance: [test: true]]
}
return [:]
}
})
helper.registerAllowedMethod("findFiles", [Map.class], { map -> [].toArray() })
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
)
}
@Test
void testPiperInitDefault() {
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 0)
helper.registerAllowedMethod("readJSON", [Map.class], { m ->
if (m.containsValue(".pipeline/stage_out.json")) {
return ["Integration":true, "Acceptance":true]
} else {
if (m.containsValue(".pipeline/step_out.json")) {
return [ Integration: [test: true], Acceptance: [test: true]]
}
return [:]
}
})
helper.registerAllowedMethod("findFiles", [Map.class], { map -> [].toArray() })
nullScript.commonPipelineEnvironment.configuration = [
@ -404,168 +142,41 @@ steps: {}
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stageConfigResource: 'com.sap.piper/pipeline/stageDefaults.yml'
)
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.Acceptance, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.Integration, is(true))
}
@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))
}
@Test
void testConditionNpmScripts() {
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
stepConditions:
firstStep:
npmScripts: \'npmScript\'
secondStep:
filePattern: \'**/conf.jsx\'
'''
} else {
return '''
general: {}
steps: {}
'''
}
})
helper.registerAllowedMethod('findFiles', [Map], {m ->
if(m.glob == '**/package.json') {
return [new File("package.json")].toArray()
} else {
return []
}
})
helper.registerAllowedMethod('readJSON', [Map], { m ->
if (m.file == 'package.json') {
return [scripts: [npmScript: "echo test",
npmScript2: "echo test"]]
} else {
return [:]
}
})
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
stageConfigResource: 'testDefault.yml'
)
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.secondStep, is(false))
}
@Test
void testConditionNpmScriptsWithList() {
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
stepConditions:
firstStep:
npmScripts:
- \'npmScript\'
- \'npmScript2\'
secondStep:
filePattern: \'**/conf.jsx\'
'''
} else {
return '''
general: {}
steps: {}
'''
}
})
helper.registerAllowedMethod('findFiles', [Map], {m ->
if(m.glob == '**/package.json') {
return [new File("package.json")].toArray()
} else {
return []
}
})
helper.registerAllowedMethod('readJSON', [Map], { m ->
if (m.file == 'package.json') {
return [scripts: [npmScript: "echo test",
npmScript2: "echo test"]]
} else {
return [:]
}
})
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
stageConfigResource: 'testDefault.yml'
)
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.firstStep, is(true))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStep.testStage1.secondStep, is(false))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test
void testConditionOnlyProductiveBranchOnNonProductiveBranch() {
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 0)
helper.registerAllowedMethod("readJSON", [Map.class], { m ->
if (m.containsValue(".pipeline/stage_out.json")) {
return ["testStage1":true]
} else {
if (m.containsValue(".pipeline/step_out.json")) {
return [:]
}
return [:]
}
})
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
stepConditions:
firstStep:
filePattern: \'**/conf.js\'
spec:
stages:
- name: testStage1
displayName: testStage1
steps:
- name: firstStep
conditions:
- filePattern: \'**/conf.js\'
'''
} else {
return '''
@ -583,23 +194,40 @@ stages:
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stageConfigResource: 'testDefault.yml',
productiveBranch: 'master'
)
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage1, is(false))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test
void testConditionOnlyProductiveBranchOnProductiveBranch() {
helper.registerAllowedMethod("readJSON", [Map.class], { m ->
if (m.containsValue(".pipeline/stage_out.json")) {
return ["testStage1":true]
} else {
if (m.containsValue(".pipeline/step_out.json")) {
return ["testStage1":["firstStep":true]]
}
return [:]
}
})
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 0)
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
stepConditions:
firstStep:
filePattern: \'**/conf.js\'
spec:
stages:
- name: testStage1
displayName: testStage1
steps:
- name: firstStep
conditions:
- filePattern: \'**/conf.js\'
'''
} else {
return '''
@ -617,29 +245,49 @@ stages:
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stageConfigResource: 'testDefault.yml',
productiveBranch: 'test'
)
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage1, is(true))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
@Test
void testStageExtensionExists() {
shellCallRule.setReturnValue('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _', 0)
helper.registerAllowedMethod("readJSON", [Map.class], { m ->
if (m.containsValue(".pipeline/stage_out.json")) {
return ["testStage1":false, "testStage2":false, "testStage3":false, "testStage4":false, "testStage5":false]
} else {
if (m.containsValue(".pipeline/step_out.json")) {
return [:]
}
return [:]
}
})
helper.registerAllowedMethod('libraryResource', [String.class], {s ->
if(s == 'testDefault.yml') {
return '''
stages:
testStage1:
extensionExists: true
testStage2:
extensionExists: true
testStage3:
extensionExists: false
testStage4:
extensionExists: 'false'
testStage5:
dummy: true
spec:
stages:
- name: testStage1
displayName: testStage1
extensionExists: true
- name: testStage2
displayName: testStage2
extensionExists: true
- name: testStage3
displayName: testStage3
extensionExists: false
- name: testStage4
displayName: testStage4
extensionExists: 'false'
- name: testStage5
displayName: testStage5
dummy: true
'''
} else {
return '''
@ -673,6 +321,7 @@ steps: {}
jsr.step.piperInitRunStageConfiguration(
script: nullScript,
juStabUtils: utils,
piperGoUtils: piperGoUtils,
stageConfigResource: 'testDefault.yml'
)
@ -681,5 +330,6 @@ steps: {}
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage3, is(false))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage4, is(false))
assertThat(nullScript.commonPipelineEnvironment.configuration.runStage.testStage5, is(false))
assertThat(shellCallRule.shell, hasItem('./piper checkIfStepActive --stageConfig .pipeline/stage_conditions.yaml --useV1 --stageOutputFile .pipeline/stage_out.json --stepOutputFile .pipeline/step_out.json --stage _ --step _'))
}
}

View File

@ -287,3 +287,26 @@ void handleErrorDetails(String stepName, Closure body) {
error "[${stepName}] Step execution failed. Error: ${ex}, please see log file for more details."
}
}
// it can be used in 2 ways:
// 1. use stage, step arguments and leave stepOutputFile "" and stageOutputFile "" empty to check if this step is active in this stage (true means step is active, false - not active or something went wrong)
// 2. use stageOutputFile and/or stepOutputFile and leave step "" and stage "" to write the whole map of steps in all stages into a file[s] (true means no errors, false - something went wrong)
// if both presented - priority is option 2
static boolean checkIfStepActive(Map parameters = [:], Script script, String piperGoPath, String stageConfig = "", String stepOutputFile = "", String stageOutputFile = "", String stage = "", String step = "") {
def utils = parameters.juStabUtils ?: new Utils()
def piperGoUtils = parameters.piperGoUtils ?: new PiperGoUtils(utils)
def flags = "--stageConfig ${stageConfig} --useV1"
if (stageOutputFile) {
flags += " --stageOutputFile ${stageOutputFile}"
}
if (stepOutputFile) {
flags += " --stepOutputFile ${stepOutputFile}"
}
if (!stage || !step) {
stage = "_"
step = "_"
}
flags += " --stage ${stage} --step ${step}"
piperGoUtils.unstashPiperBin()
def returnCode = script.sh(returnStatus: true, script: "${piperGoPath} checkIfStepActive ${flags}")
return (returnCode == 0)
}

View File

@ -34,7 +34,6 @@ import groovy.transform.Field
* Defines the library resource that contains the stage configuration settings
*/
'stageConfigResource'
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
@ -57,60 +56,38 @@ void call(Map parameters = [:]) {
.withMandatoryProperty('stageConfigResource')
.use()
// Go logic to check if the step is active
String piperGoPath = parameters?.piperGoPath ?: './piper'
def resource = libraryResource(config.stageConfigResource)
config.stages = (readYaml(text: resource)).spec.stages
writeFile(file: ".pipeline/stage_conditions.yaml", text: resource)
def success = piperExecuteBin.checkIfStepActive(parameters, script, piperGoPath, ".pipeline/stage_conditions.yaml", ".pipeline/step_out.json", ".pipeline/stage_out.json")
if (!success) {
throw new Exception("checkIfStepActive finished with error")
}
config.stages = (readYaml(text: libraryResource(config.stageConfigResource))).stages
//handling of stage and step activation
config.stages.each {stage ->
script.commonPipelineEnvironment.configuration.runStage = script.readJSON file: ".pipeline/stage_out.json"
script.commonPipelineEnvironment.configuration.runStep = script.readJSON file: ".pipeline/step_out.json"
// Retaining this groovy code as some additional checks for activating-deactivating a stage seems to be done.
script.commonPipelineEnvironment.configuration.runStage.each {stage ->
String currentStage = stage.getKey()
script.commonPipelineEnvironment.configuration.runStep[currentStage] = [:]
// Always test step conditions in order to fill runStep[currentStage] map
boolean anyStepConditionTrue = false
stage.getValue().stepConditions?.each {step ->
boolean stepActive = false
String stepName = step.getKey()
step.getValue().each {condition ->
Map stepConfig = script.commonPipelineEnvironment.getStepConfiguration(stepName, currentStage)
switch(condition.getKey()) {
case 'config':
stepActive = stepActive || checkConfig(condition, stepConfig)
break
case 'configKeys':
stepActive = stepActive || checkConfigKeys(condition, stepConfig)
break
case 'filePatternFromConfig':
stepActive = stepActive || checkForFilesWithPatternFromConfig(script, condition, stepConfig)
break
case 'filePattern':
stepActive = stepActive || checkForFilesWithPattern(script, condition)
break
case 'npmScripts':
stepActive = stepActive || checkForNpmScriptsInPackages(script, condition)
break
}
}
script.commonPipelineEnvironment.configuration.runStep[currentStage][stepName] = stepActive
anyStepConditionTrue = anyStepConditionTrue || stepActive
}
Map stageConfig = ConfigurationHelper.newInstance(this)
.loadStepDefaults([:], currentStage)
.mixinStageConfig(script.commonPipelineEnvironment, currentStage)
.use()
boolean runStage
boolean runStage = stage.getValue()
if (stageConfig.runInAllBranches == false && (config.productiveBranch != env.BRANCH_NAME)) {
runStage = false
} else if (ConfigurationLoader.stageConfiguration(script, currentStage)) {
//activate stage if stage configuration is available
runStage = true
} else if (stage.getValue().extensionExists == true) {
runStage = anyStepConditionTrue || checkExtensionExists(script, config, currentStage)
} else {
runStage = anyStepConditionTrue
def extensionExists = config.stages.find {e -> e.displayName == currentStage && e.extensionExists == true?true:false}
if (extensionExists != null) {
runStage = runStage || checkExtensionExists(script, config, currentStage)
}
}
script.commonPipelineEnvironment.configuration.runStage[currentStage] = runStage
@ -136,77 +113,3 @@ private static boolean checkExtensionExists(Script script, Map config, String st
def globalInterceptorFile = "${config.globalExtensionsDirectory}${stageName}.groovy"
return script.fileExists(projectInterceptorFile) || script.fileExists(globalInterceptorFile)
}
private static boolean checkConfig(def condition, Map stepConfig) {
Boolean configExists = false
if (condition.getValue() instanceof Map) {
condition.getValue().each {configCondition ->
if (MapUtils.getByPath(stepConfig, configCondition.getKey()) in configCondition.getValue()) {
configExists = true
}
}
} else if (MapUtils.getByPath(stepConfig, condition.getValue())) {
configExists = true
}
return configExists
}
private static boolean checkConfigKeys(def condition, Map stepConfig) {
Boolean configKeyExists = false
if (condition.getValue() instanceof List) {
condition.getValue().each { configKey ->
if (MapUtils.getByPath(stepConfig, configKey)) {
configKeyExists = true
}
}
} else if (MapUtils.getByPath(stepConfig, condition.getValue())) {
configKeyExists = true
}
return configKeyExists
}
private static boolean checkForFilesWithPatternFromConfig (Script script, def condition, Map stepConfig) {
def conditionValue = MapUtils.getByPath(stepConfig, condition.getValue())
if (conditionValue && script.findFiles(glob: conditionValue)) {
return true
}
return false
}
private static boolean checkForFilesWithPattern (Script script, def condition) {
Boolean filesExist = false
if (condition.getValue() instanceof List) {
condition.getValue().each {configKey ->
if (script.findFiles(glob: configKey)) {
filesExist = true
}
}
} else {
if (script.findFiles(glob: condition.getValue())) {
filesExist = true
}
}
return filesExist
}
private static boolean checkForNpmScriptsInPackages (Script script, def condition) {
def packages = script.findFiles(glob: '**/package.json', excludes: '**/node_modules/**')
Boolean npmScriptExists = false
for (int i = 0; i < packages.size(); i++) {
String packageJsonPath = packages[i].path
Map packageJson = script.readJSON file: packageJsonPath
Map npmScripts = packageJson.scripts ?: [:]
if (condition.getValue() instanceof List) {
condition.getValue().each { configKey ->
if (npmScripts[configKey]) {
npmScriptExists = true
}
}
} else {
if (npmScripts[condition.getValue()]) {
npmScriptExists = true
}
}
}
return npmScriptExists
}