diff --git a/src/com/sap/piper/LegacyConfigurationCheckUtils.groovy b/src/com/sap/piper/LegacyConfigurationCheckUtils.groovy deleted file mode 100644 index 12e7fefd6..000000000 --- a/src/com/sap/piper/LegacyConfigurationCheckUtils.groovy +++ /dev/null @@ -1,267 +0,0 @@ -package com.sap.piper - -class LegacyConfigurationCheckUtils{ - static void checkConfiguration(Script script, Map configChanges) { - List errors = [] - - if (configChanges?.removedOrReplacedConfigKeys) { - errors.addAll(checkForRemovedOrReplacedConfigKeys(script, configChanges.removedOrReplacedConfigKeys)) - } - - if (configChanges?.removedOrReplacedSteps) { - errors.addAll(checkForRemovedOrReplacedSteps(script, configChanges.removedOrReplacedSteps)) - } - - if (configChanges?.removedOrReplacedStages) { - errors.addAll(checkForRemovedOrReplacedStages(script, configChanges.removedOrReplacedStages)) - } - - if (configChanges?.parameterTypeChanged) { - errors.addAll(checkForParameterTypeChanged(script, configChanges.parameterTypeChanged)) - } - - if (configChanges?.renamedNpmScript) { - errors.addAll(checkForRenamedNpmScripts(script, configChanges.renamedNpmScript)) - } - - if (errors) { - if (errors.size() > 1) { - script.echo("Your pipeline configuration file contains the following errors:") - } - errors.each {error -> - script.echo(error) - } - script.error("Failing pipeline due to configuration errors. Please see log output above.") - } - } - - static List checkForRemovedOrReplacedConfigKeys(Script script, Map configChanges) { - List errors = [] - configChanges.each {oldConfigKey, changes -> - List steps = changes?.steps ?: [] - List stages = changes?.stages ?: [] - Boolean general = changes?.general ?: false - Boolean postAction = changes?.postAction ?: false - - Boolean warnInsteadOfError = changes?.warnInsteadOfError ?: false - String customMessage = changes?.customMessage ?: "" - String newConfigKey = changes?.newConfigKey ?: "" - - if (newConfigKey) { - customMessage = "Please use the parameter ${newConfigKey} instead. " + customMessage - } - - for (int i = 0; i < steps.size(); i++) { - Map config = loadEffectiveStepConfig(script, steps[i]) - if (config.containsKey(oldConfigKey)) { - String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} for the step ${steps[i]}. " + - "This configuration option was removed. " + customMessage - if (warnInsteadOfError) { - addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) - } else { - errors.add(errorMessage) - } - } - } - - for (int i = 0; i < stages.size(); i++) { - Map config = loadEffectiveStageConfig(script, stages[i]) - if (config.containsKey(oldConfigKey)) { - String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} for the stage ${stages[i]}. " + - "This configuration option was removed. " + customMessage - if (warnInsteadOfError) { - addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) - } else { - errors.add(errorMessage) - } - } - } - - if (general) { - Map config = loadEffectiveGeneralConfig(script) - if (config.containsKey(oldConfigKey)) { - String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} in the general section. " + - "This configuration option was removed. " + customMessage - if (warnInsteadOfError) { - addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) - } else { - errors.add(errorMessage) - } - } - } - - if (postAction) { - Map config = loadEffectivePostActionConfig(script) - if (config.containsKey(oldConfigKey)) { - String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} in the postActions section. " + - "This configuration option was removed. " + customMessage - if (warnInsteadOfError) { - addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) - } else { - errors.add(errorMessage) - } - } - } - } - return errors - } - - static List checkForRemovedOrReplacedSteps(Script script, Map configChanges) { - List errors = [] - configChanges.each {oldConfigKey, changes -> - Boolean onlyCheckProjectConfig = changes?.onlyCheckProjectConfig ?: false - String customMessage = changes?.customMessage ?: "" - String newStepName = changes?.newStepName ?: "" - - if (newStepName) { - customMessage = "Please configure the step ${newStepName} instead. " + customMessage - } - - Map config - if (onlyCheckProjectConfig) { - config = ConfigurationLoader.stepConfiguration(script, oldConfigKey) - } else { - config = loadEffectiveStepConfig(script, oldConfigKey) - } - - if (config) { - errors.add("Your pipeline configuration contains configuration for the step ${oldConfigKey}. " + - "This step has been removed. " + customMessage) - } - } - return errors - } - - static List checkForRemovedOrReplacedStages(Script script, Map configChanges) { - List errors = [] - configChanges.each {oldConfigKey, changes -> - String customMessage = changes?.customMessage ?: "" - String newStageName = changes?.newStageName ?: "" - - if (newStageName) { - customMessage = "Please configure the stage ${newStageName} instead. " + customMessage - } - - if (loadEffectiveStageConfig(script, oldConfigKey)) { - errors.add("Your pipeline configuration contains configuration for the stage ${oldConfigKey}. " + - "This stage has been removed. " + customMessage) - } - } - return errors - } - - static List checkForParameterTypeChanged(Script script, Map configChanges) { - List errors = [] - configChanges.each { oldConfigKey, changes -> - String oldType = changes?.oldType ?: "" - String newType = changes?.newType ?: "" - List steps = changes?.steps ?: [] - List stages = changes?.stages ?: [] - Boolean general = changes?.general ?: false - String customMessage = changes?.customMessage ?: "" - - if (oldType != "String") { - script.echo ("Your legacy config settings contain an entry for parameterTypeChanged with the key ${oldConfigKey} with the unsupported type ${oldType}. " + - "Currently only the type 'String' is supported.") - return errors - } - - for (int i = 0; i < steps.size(); i++) { - Map config = loadEffectiveStepConfig(script, steps[i]) - if (config.containsKey(oldConfigKey)) { - if (oldType == "String" && config.get(oldConfigKey) instanceof String) { - errors.add("Your pipeline configuration contains the configuration key ${oldConfigKey} for the step ${steps[i]}. " + - "The type of this configuration parameter was changed from ${oldType} to ${newType}. " + customMessage) - } - } - } - - for (int i = 0; i < stages.size(); i++) { - Map config = loadEffectiveStageConfig(script, stages[i]) - if (config.containsKey(oldConfigKey)) { - if (oldType == "String" && config.get(oldConfigKey) instanceof String) { - errors.add("Your pipeline configuration contains the configuration key ${oldConfigKey} for the stage ${stages[i]}. " + - "The type of this configuration parameter was changed from ${oldType} to ${newType}. " + customMessage) - } - } - } - - if (general) { - Map config = loadEffectiveGeneralConfig(script) - if (config.containsKey(oldConfigKey)) { - if (oldType == "String" && config.get(oldConfigKey) instanceof String) { - errors.add("Your pipeline configuration contains the configuration key ${oldConfigKey} in the general section. " + - "The type of this configuration parameter was changed from ${oldType} to ${newType}. " + customMessage) - } - } - } - } - return errors - } - - static List checkForRenamedNpmScripts(Script script, Map configChanges) { - List errors = [] - configChanges.each { oldScriptName, changes -> - String newScriptName = changes?.newScriptName ?: "" - Boolean warnInsteadOfError = changes?.warnInsteadOfError ?: false - String customMessage = changes?.customMessage ?: "" - - String packageJsonWithScript = findPackageWithScript(script, oldScriptName) - if (packageJsonWithScript) { - String errorMessage = "Your package.json file ${packageJsonWithScript} contains an npm script using the deprecated name ${oldScriptName}. " + - "Please rename the script to ${newScriptName}, since the script ${oldScriptName} will not be executed by the pipeline anymore. " + customMessage - if (warnInsteadOfError) { - addPipelineWarning(script, "Deprecated npm script ${oldScriptName}", errorMessage) - } else { - errors.add(errorMessage) - } - } - } - return errors - } - - private static String findPackageWithScript(Script script, String scriptName) { - List packages = script.findFiles(glob: '**/package.json', excludes: '**/node_modules/**') - - for (int i = 0; i < packages.size(); i++) { - String packageJsonPath = packages[i].path - Map packageJson = script.readJSON file: packageJsonPath - Map npmScripts = packageJson?.scripts ?: [:] - if (npmScripts.get(scriptName)) { - return packageJsonPath - } - } - return "" - } - - private static Map loadEffectiveStepConfig(Script script, String stepName) { - return MapUtils.merge(ConfigurationLoader.defaultStepConfiguration(script, stepName), ConfigurationLoader.stepConfiguration(script, stepName)) - } - - private static Map loadEffectiveStageConfig(Script script, String stageName) { - return MapUtils.merge(ConfigurationLoader.defaultStageConfiguration(script, stageName), ConfigurationLoader.stageConfiguration(script, stageName)) - } - - private static Map loadEffectiveGeneralConfig(Script script) { - return MapUtils.merge(ConfigurationLoader.defaultGeneralConfiguration(script), ConfigurationLoader.generalConfiguration(script)) - } - - private static Map loadEffectivePostActionConfig(Script script) { - Map defaultPostActionConfig = DefaultValueCache.getInstance()?.getDefaultValues()?.get("postActions") ?: [:] - Map projectPostActionConfig = script?.commonPipelineEnvironment?.configuration?.postActions ?: [:] - return MapUtils.merge(defaultPostActionConfig, projectPostActionConfig) - } - - static void addPipelineWarning(Script script, String heading, String message) { - script.echo '[WARNING] ' + message - script.addBadge(icon: "warning.gif", text: message) - - String html = - """ -
$message
- """ - - script.createSummary(icon: "warning.gif", text: html) - } -} diff --git a/test/groovy/com/sap/piper/LegacyConfigurationCheckUtilsTest.groovy b/test/groovy/CheckForLegacyConfigurationTest.groovy similarity index 71% rename from test/groovy/com/sap/piper/LegacyConfigurationCheckUtilsTest.groovy rename to test/groovy/CheckForLegacyConfigurationTest.groovy index c6411229b..9694b22ca 100644 --- a/test/groovy/com/sap/piper/LegacyConfigurationCheckUtilsTest.groovy +++ b/test/groovy/CheckForLegacyConfigurationTest.groovy @@ -1,23 +1,27 @@ -package com.sap.piper - +import com.sap.piper.DefaultValueCache 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.JenkinsStepRule import util.Rules import static org.junit.Assert.assertEquals -class LegacyConfigurationCheckUtilsTest extends BasePiperTest { +class CheckForLegacyConfigurationTest extends BasePiperTest { + private ExpectedException thrown = ExpectedException.none() + private JenkinsStepRule stepRule = new JenkinsStepRule(this) + String echoOutput = "" @Rule public RuleChain ruleChain = Rules .getCommonRules(this) - .around(ExpectedException.none()) + .around(thrown) + .around(stepRule) @Before @@ -59,10 +63,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [someStep: [oldConfigKey: false]]] Map configChanges = [oldConfigKey: [steps: ['someStep'], customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key oldConfigKey for the step someStep. " + - "This configuration option was removed. test"]) + "This configuration option was removed. test"]) } @Test @@ -70,10 +74,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [someStep: [oldConfigKey: false]]] Map configChanges = [oldConfigKey: [steps: ['someStep'], newConfigKey: "newConfigKey", customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key oldConfigKey for the step someStep. " + - "This configuration option was removed. Please use the parameter newConfigKey instead. test"]) + "This configuration option was removed. Please use the parameter newConfigKey instead. test"]) } @Test @@ -84,8 +88,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [someStep: [oldConfigKey: false]]] Map configChanges = [oldConfigKey: [steps: ['someStep'], warnInsteadOfError: true, customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) - + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) assertEquals(expectedWarning, echoOutput) assertEquals(errors, []) } @@ -95,10 +98,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [stages: [someStage: [oldConfigKey: false]]] Map configChanges = [oldConfigKey: [stages: ['someStage']]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key oldConfigKey for the stage someStage. " + - "This configuration option was removed. "]) + "This configuration option was removed. "]) } @Test @@ -106,10 +109,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [general: [oldConfigKey: false]] Map configChanges = [oldConfigKey: [general: true]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key oldConfigKey in the general section. " + - "This configuration option was removed. "]) + "This configuration option was removed. "]) } @Test @@ -117,22 +120,22 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [postActions: [oldConfigKey: false]] Map configChanges = [oldConfigKey: [postAction: true]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedConfigKeys(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key oldConfigKey in the postActions section. " + - "This configuration option was removed. "]) + "This configuration option was removed. "]) } @Test void testCheckForReplacedStep() { String oldStep = "oldStep" nullScript.commonPipelineEnvironment.configuration = [steps: [oldStep: [configKey: false]]] - Map configChanges = [oldStep: [newStepName: "newStep", customMessage: "test"]] + Map configChanges = [oldStep: [newStepName: 'newStep', customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedSteps(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedSteps(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains configuration for the step $oldStep. " + - "This step has been removed. Please configure the step newStep instead. test"]) + "This step has been removed. Please configure the step newStep instead. test"]) } @Test @@ -141,10 +144,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [oldStep: [configKey: false]]] Map configChanges = [oldStep: [customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedSteps(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedSteps(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains configuration for the step $oldStep. " + - "This step has been removed. test"]) + "This step has been removed. test"]) } @Test @@ -159,7 +162,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [newStep: [configKey: false]]] Map configChanges = [oldStep: [onlyCheckProjectConfig: true]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedSteps(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedSteps(nullScript, configChanges) assertEquals(errors, []) } @@ -170,10 +173,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [stages: [oldStage: [configKey: false]]] Map configChanges = [oldStage: [newStageName: 'newStage', customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedStages(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedStages(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains configuration for the stage $oldStage. " + - "This stage has been removed. Please configure the stage newStage instead. test"]) + "This stage has been removed. Please configure the stage newStage instead. test"]) } @Test @@ -182,10 +185,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [stages: [oldStage: [configKey: false]]] Map configChanges = [oldStage: []] - List errors = LegacyConfigurationCheckUtils.checkForRemovedOrReplacedStages(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRemovedOrReplacedStages(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains configuration for the stage $oldStage. " + - "This stage has been removed. "]) + "This stage has been removed. "]) } @Test @@ -194,10 +197,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [stages: [productionDeployment: [configKeyOldType: "string"]]] Map configChanges = [configKeyOldType: [oldType: "String", newType: "List", stages: ["productionDeployment", "endToEndTests"], customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForParameterTypeChanged(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForParameterTypeChanged(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key configKeyOldType for the stage $stageName. " + - "The type of this configuration parameter was changed from String to List. test"]) + "The type of this configuration parameter was changed from String to List. test"]) } @Test @@ -206,10 +209,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [testStep: [configKeyOldType: "string"]]] Map configChanges = [configKeyOldType: [oldType: "String", newType: "List", steps: ["testStep"], customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForParameterTypeChanged(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForParameterTypeChanged(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key configKeyOldType for the step $stepName. " + - "The type of this configuration parameter was changed from String to List. test"]) + "The type of this configuration parameter was changed from String to List. test"]) } @Test @@ -218,10 +221,10 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [general: [configKeyOldType: "string"]] Map configChanges = [configKeyOldType: [oldType: "String", newType: "List", general: true, customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForParameterTypeChanged(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForParameterTypeChanged(nullScript, configChanges) assertEquals(errors, ["Your pipeline configuration contains the configuration key $key in the general section. " + - "The type of this configuration parameter was changed from String to List. test"]) + "The type of this configuration parameter was changed from String to List. test"]) } @Test @@ -231,18 +234,18 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [steps: [testStep: [configKeyOldType: [test: true]]]] Map configChanges = [configKeyOldType: [oldType: "Map", newType: "List", steps: ["testStep"], customMessage: "test"]] - LegacyConfigurationCheckUtils.checkForParameterTypeChanged(nullScript, configChanges) - - assertEquals(expectedWarning, echoOutput) + List errors = stepRule.step.checkForLegacyConfiguration.checkForParameterTypeChanged(nullScript, configChanges) + assertEquals(expectedWarning, errors[0].toString()) } @Test void testCheckForRenamedNpmScripts() { Map configChanges = [oldNpmScriptName: [newScriptName: "newNpmScriptName", customMessage: "test"]] - List errors = LegacyConfigurationCheckUtils.checkForRenamedNpmScripts(nullScript, configChanges) + List errors = stepRule.step.checkForLegacyConfiguration.checkForRenamedNpmScripts(nullScript, configChanges) + assertEquals(errors, ["Your package.json file package.json contains an npm script using the deprecated name oldNpmScriptName. " + - "Please rename the script to newNpmScriptName, since the script oldNpmScriptName will not be executed by the pipeline anymore. test"]) + "Please rename the script to newNpmScriptName, since the script oldNpmScriptName will not be executed by the pipeline anymore. test"]) } @Test @@ -251,7 +254,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { String expectedWarning = "[WARNING] Your package.json file package.json contains an npm script using the deprecated name oldNpmScriptName. " + "Please rename the script to newNpmScriptName, since the script oldNpmScriptName will not be executed by the pipeline anymore. test" - LegacyConfigurationCheckUtils.checkForRenamedNpmScripts(nullScript, configChanges) + stepRule.step.checkForLegacyConfiguration.checkForRenamedNpmScripts(nullScript, configChanges) assertEquals(expectedWarning, echoOutput) } @@ -273,7 +276,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { "This configuration option was removed. test" assertExceptionAndOutput(exception, output) { - LegacyConfigurationCheckUtils.checkConfiguration(nullScript, configChanges) + stepRule.step.checkForLegacyConfiguration(script: nullScript, legacyConfigSettings: configChanges) } } @@ -294,7 +297,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { "This step has been removed. Please configure the step newStep instead. test" assertExceptionAndOutput(exception, output) { - LegacyConfigurationCheckUtils.checkConfiguration(nullScript, configChanges) + stepRule.step.checkForLegacyConfiguration(script: nullScript, legacyConfigSettings: configChanges) } } @@ -312,7 +315,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { "This stage has been removed. " assertExceptionAndOutput(exception, output) { - LegacyConfigurationCheckUtils.checkConfiguration(nullScript, configChanges) + stepRule.step.checkForLegacyConfiguration(script: nullScript, legacyConfigSettings: configChanges) } } @@ -334,7 +337,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { "The type of this configuration parameter was changed from String to List. test" assertExceptionAndOutput(exception, output) { - LegacyConfigurationCheckUtils.checkConfiguration(nullScript, configChanges) + stepRule.step.checkForLegacyConfiguration(script: nullScript, legacyConfigSettings: configChanges) } } @@ -353,37 +356,7 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { "Please rename the script to newNpmScriptName, since the script oldNpmScriptName will not be executed by the pipeline anymore. test" assertExceptionAndOutput(exception, output) { - LegacyConfigurationCheckUtils.checkConfiguration(nullScript, configChanges) - } - } - - @Test - void testCheckConfigurationMultipleErrors() { - nullScript.commonPipelineEnvironment.configuration = [steps: [testStep: [configKeyOldType: "string"]]] - Map configChanges = [ - renamedNpmScript: [ - oldNpmScriptName: [ - newScriptName: "newNpmScriptName", - customMessage: "test"] - ], - parameterTypeChanged: [ - configKeyOldType: [ - oldType: "String", - newType: "List", - steps: ["testStep"], - customMessage: "test"] - ] - ] - - String exception = "Failing pipeline due to configuration errors. Please see log output above." - String output = "Your pipeline configuration file contains the following errors:\n" + - "Your pipeline configuration contains the configuration key configKeyOldType for the step testStep. " + - "The type of this configuration parameter was changed from String to List. test\n" + - "Your package.json file package.json contains an npm script using the deprecated name oldNpmScriptName. " + - "Please rename the script to newNpmScriptName, since the script oldNpmScriptName will not be executed by the pipeline anymore. test" - - assertExceptionAndOutput(exception, output) { - LegacyConfigurationCheckUtils.checkConfiguration(nullScript, configChanges) + stepRule.step.checkForLegacyConfiguration(script: nullScript, legacyConfigSettings: configChanges) } } @@ -397,4 +370,5 @@ class LegacyConfigurationCheckUtilsTest extends BasePiperTest { assertEquals(exception, actualException) assertEquals(output, echoOutput) } + } diff --git a/test/groovy/templates/PiperPipelineStageInitTest.groovy b/test/groovy/templates/PiperPipelineStageInitTest.groovy index 15c5636de..3dce8d1f6 100644 --- a/test/groovy/templates/PiperPipelineStageInitTest.groovy +++ b/test/groovy/templates/PiperPipelineStageInitTest.groovy @@ -14,6 +14,7 @@ import static org.hamcrest.Matchers.is import static org.hamcrest.Matchers.isEmptyOrNullString import static org.hamcrest.Matchers.not import static org.junit.Assert.assertThat +import static org.junit.Assert.assertTrue class PiperPipelineStageInitTest extends BasePiperTest { private JenkinsStepRule jsr = new JenkinsStepRule(this) @@ -233,4 +234,19 @@ class PiperPipelineStageInitTest extends BasePiperTest { assertThat(nullScript.commonPipelineEnvironment.configuration.stageStashes, hasKey('init')) } + + @Test + void testLegacyConfigSettings() { + boolean checkForLegacyConfigurationCalled = false + helper.registerAllowedMethod('checkForLegacyConfiguration', [Map.class], { + checkForLegacyConfigurationCalled = true + }) + nullScript.commonPipelineEnvironment.configuration = [ + general: [legacyConfigSettings: 'com.sap.piper/pipeline/cloudSdkLegacyConfigSettings.yml'] + ] + + jsr.step.piperPipelineStageInit(script: nullScript, juStabUtils: utils, buildTool: 'maven') + + assertTrue(checkForLegacyConfigurationCalled) + } } diff --git a/vars/checkForLegacyConfiguration.groovy b/vars/checkForLegacyConfiguration.groovy new file mode 100644 index 000000000..40c682e06 --- /dev/null +++ b/vars/checkForLegacyConfiguration.groovy @@ -0,0 +1,277 @@ +import com.sap.piper.ConfigurationLoader +import com.sap.piper.DefaultValueCache +import com.sap.piper.MapUtils +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 = [] +@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + +void call(Map parameters = [:]) { + List errors = [] + def script = checkScript(this, parameters) ?: this + def configChanges = parameters.legacyConfigSettings + + if (configChanges?.removedOrReplacedConfigKeys) { + errors.addAll(checkForRemovedOrReplacedConfigKeys(script, configChanges.removedOrReplacedConfigKeys)) + } + + if (configChanges?.removedOrReplacedSteps) { + errors.addAll(checkForRemovedOrReplacedSteps(script, configChanges.removedOrReplacedSteps)) + } + + if (configChanges?.removedOrReplacedStages) { + errors.addAll(checkForRemovedOrReplacedStages(script, configChanges.removedOrReplacedStages)) + } + + if (configChanges?.parameterTypeChanged) { + errors.addAll(checkForParameterTypeChanged(script, configChanges.parameterTypeChanged)) + } + + if (configChanges?.renamedNpmScript) { + errors.addAll(checkForRenamedNpmScripts(script, configChanges.renamedNpmScript)) + } + + if (errors) { + if (errors.size() > 1) { + script.echo("Your pipeline configuration file contains the following errors:") + } + for (error in errors) { + script.echo(error) + } + script.error("Failing pipeline due to configuration errors. Please see log output above.") + } +} + +static List checkForRemovedOrReplacedConfigKeys(Script script, Map configChanges) { + List errors = [] + configChanges.each { oldConfigKey, changes -> + List steps = changes?.steps ?: [] + List stages = changes?.stages ?: [] + Boolean general = changes?.general ?: false + Boolean postAction = changes?.postAction ?: false + + Boolean warnInsteadOfError = changes?.warnInsteadOfError ?: false + String customMessage = changes?.customMessage ?: "" + String newConfigKey = changes?.newConfigKey ?: "" + + if (newConfigKey) { + customMessage = "Please use the parameter ${newConfigKey} instead. " + customMessage + } + + for (int i = 0; i < steps.size(); i++) { + Map config = loadEffectiveStepConfig(script, steps[i]) + if (config.containsKey(oldConfigKey)) { + String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} for the step ${steps[i]}. " + + "This configuration option was removed. " + customMessage + if (warnInsteadOfError) { + addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) + } else { + errors.add(errorMessage) + } + } + } + + for (int i = 0; i < stages.size(); i++) { + Map config = loadEffectiveStageConfig(script, stages[i]) + if (config.containsKey(oldConfigKey)) { + String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} for the stage ${stages[i]}. " + + "This configuration option was removed. " + customMessage + if (warnInsteadOfError) { + addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) + } else { + errors.add(errorMessage) + } + } + } + + if (general) { + Map config = loadEffectiveGeneralConfig(script) + if (config.containsKey(oldConfigKey)) { + String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} in the general section. " + + "This configuration option was removed. " + customMessage + if (warnInsteadOfError) { + addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) + } else { + errors.add(errorMessage) + } + } + } + + if (postAction) { + Map config = loadEffectivePostActionConfig(script) + if (config.containsKey(oldConfigKey)) { + String errorMessage = "Your pipeline configuration contains the configuration key ${oldConfigKey} in the postActions section. " + + "This configuration option was removed. " + customMessage + if (warnInsteadOfError) { + addPipelineWarning(script, "Deprecated configuration key ${oldConfigKey}", errorMessage) + } else { + errors.add(errorMessage) + } + } + } + } + return errors +} + +static List checkForRemovedOrReplacedSteps(Script script, Map configChanges) { + List errors = [] + configChanges.each { oldConfigKey, changes -> + Boolean onlyCheckProjectConfig = changes?.onlyCheckProjectConfig ?: false + String customMessage = changes?.customMessage ?: "" + String newStepName = changes?.newStepName ?: "" + + if (newStepName) { + customMessage = "Please configure the step ${newStepName} instead. " + customMessage + } + + Map config + if (onlyCheckProjectConfig) { + config = ConfigurationLoader.stepConfiguration(script, oldConfigKey) + } else { + config = loadEffectiveStepConfig(script, oldConfigKey) + } + + if (config) { + errors.add("Your pipeline configuration contains configuration for the step ${oldConfigKey}. " + + "This step has been removed. " + customMessage) + } + } + return errors +} + +static List checkForRemovedOrReplacedStages(Script script, Map configChanges) { + List errors = [] + configChanges.each { oldConfigKey, changes -> + String customMessage = changes?.customMessage ?: "" + String newStageName = changes?.newStageName ?: "" + + if (newStageName) { + customMessage = "Please configure the stage ${newStageName} instead. " + customMessage + } + + if (loadEffectiveStageConfig(script, oldConfigKey)) { + errors.add("Your pipeline configuration contains configuration for the stage ${oldConfigKey}. " + + "This stage has been removed. " + customMessage) + } + } + return errors +} + +static List checkForParameterTypeChanged(Script script, Map configChanges) { + List errors = [] + configChanges.each { oldConfigKey, changes -> + String oldType = changes?.oldType ?: "" + String newType = changes?.newType ?: "" + List steps = changes?.steps ?: [] + List stages = changes?.stages ?: [] + Boolean general = changes?.general ?: false + String customMessage = changes?.customMessage ?: "" + + if (oldType != "String") { + errors.add("Your legacy config settings contain an entry for parameterTypeChanged with the key ${oldConfigKey} with the unsupported type ${oldType}. " + + "Currently only the type 'String' is supported.") + return + } + + for (int i = 0; i < steps.size(); i++) { + Map config = loadEffectiveStepConfig(script, steps[i]) + if (config.containsKey(oldConfigKey)) { + if (oldType == "String" && config.get(oldConfigKey) instanceof String) { + errors.add("Your pipeline configuration contains the configuration key ${oldConfigKey} for the step ${steps[i]}. " + + "The type of this configuration parameter was changed from ${oldType} to ${newType}. " + customMessage) + } + } + } + + for (int i = 0; i < stages.size(); i++) { + Map config = loadEffectiveStageConfig(script, stages[i]) + if (config.containsKey(oldConfigKey)) { + if (oldType == "String" && config.get(oldConfigKey) instanceof String) { + errors.add("Your pipeline configuration contains the configuration key ${oldConfigKey} for the stage ${stages[i]}. " + + "The type of this configuration parameter was changed from ${oldType} to ${newType}. " + customMessage) + } + } + } + + if (general) { + Map config = loadEffectiveGeneralConfig(script) + if (config.containsKey(oldConfigKey)) { + if (oldType == "String" && config.get(oldConfigKey) instanceof String) { + errors.add("Your pipeline configuration contains the configuration key ${oldConfigKey} in the general section. " + + "The type of this configuration parameter was changed from ${oldType} to ${newType}. " + customMessage) + } + } + } + } + return errors +} + +static List checkForRenamedNpmScripts(Script script, Map configChanges) { + List errors = [] + configChanges.each { oldScriptName, changes -> + String newScriptName = changes?.newScriptName ?: "" + Boolean warnInsteadOfError = changes?.warnInsteadOfError ?: false + String customMessage = changes?.customMessage ?: "" + + String packageJsonWithScript = findPackageWithScript(script, oldScriptName) + if (packageJsonWithScript) { + String errorMessage = "Your package.json file ${packageJsonWithScript} contains an npm script using the deprecated name ${oldScriptName}. " + + "Please rename the script to ${newScriptName}, since the script ${oldScriptName} will not be executed by the pipeline anymore. " + customMessage + if (warnInsteadOfError) { + addPipelineWarning(script, "Deprecated npm script ${oldScriptName}", errorMessage) + } else { + errors.add(errorMessage) + } + } + } + return errors +} + +private static String findPackageWithScript(Script script, String scriptName) { + List packages = script.findFiles(glob: '**/package.json', excludes: '**/node_modules/**') + + for (int i = 0; i < packages.size(); i++) { + String packageJsonPath = packages[i].path + Map packageJson = script.readJSON file: packageJsonPath + Map npmScripts = packageJson?.scripts ?: [:] + if (npmScripts.get(scriptName)) { + return packageJsonPath + } + } + return "" +} + +private static Map loadEffectiveStepConfig(Script script, String stepName) { + return MapUtils.merge(ConfigurationLoader.defaultStepConfiguration(script, stepName), ConfigurationLoader.stepConfiguration(script, stepName)) +} + +private static Map loadEffectiveStageConfig(Script script, String stageName) { + return MapUtils.merge(ConfigurationLoader.defaultStageConfiguration(script, stageName), ConfigurationLoader.stageConfiguration(script, stageName)) +} + +private static Map loadEffectiveGeneralConfig(Script script) { + return MapUtils.merge(ConfigurationLoader.defaultGeneralConfiguration(script), ConfigurationLoader.generalConfiguration(script)) +} + +private static Map loadEffectivePostActionConfig(Script script) { + Map defaultPostActionConfig = DefaultValueCache.getInstance()?.getDefaultValues()?.get("postActions") ?: [:] + Map projectPostActionConfig = script?.commonPipelineEnvironment?.configuration?.postActions ?: [:] + return MapUtils.merge(defaultPostActionConfig, projectPostActionConfig) +} + +static void addPipelineWarning(Script script, String heading, String message) { + script.echo '[WARNING] ' + message + script.addBadge(icon: "warning.gif", text: message) + + String html = + """ +$message
+ """ + + script.createSummary(icon: "warning.gif", text: html) +} diff --git a/vars/piperPipelineStageInit.groovy b/vars/piperPipelineStageInit.groovy index 5472b3d53..184ca5cdc 100644 --- a/vars/piperPipelineStageInit.groovy +++ b/vars/piperPipelineStageInit.groovy @@ -1,8 +1,6 @@ -import com.cloudbees.groovy.cps.NonCPS import com.sap.piper.ConfigurationHelper import com.sap.piper.GenerateStageDocumentation import com.sap.piper.JenkinsUtils -import com.sap.piper.LegacyConfigurationCheckUtils import com.sap.piper.StageNameProvider import com.sap.piper.Utils import com.sap.piper.k8s.ContainerMap @@ -125,7 +123,7 @@ void call(Map parameters = [:]) { if (config.legacyConfigSettings) { Map legacyConfigSettings = readYaml(text: libraryResource(config.legacyConfigSettings)) - LegacyConfigurationCheckUtils.checkConfiguration(script, legacyConfigSettings) + checkForLegacyConfiguration(script: script, legacyConfigSettings: legacyConfigSettings) } String buildTool = checkBuildTool(config)