github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/src/com/sap/piper/Utils.groovy (about) 1 package com.sap.piper 2 3 import com.cloudbees.groovy.cps.NonCPS 4 import com.sap.piper.analytics.Telemetry 5 import groovy.text.GStringTemplateEngine 6 7 import java.nio.charset.StandardCharsets 8 import java.security.MessageDigest 9 10 def stash(Map params) { 11 if(params.includes == null) params.includes = '**/*.*' 12 if(params.excludes == null) params.excludes = '' 13 if(params.useDefaultExcludes == null) params.useDefaultExcludes = true 14 if(params.allowEmpty == null) params.allowEmpty = false 15 return stash(params.name, params.includes, params.excludes, params.useDefaultExcludes, params.allowEmpty) 16 } 17 18 def stash(String name, String includes = '**/*.*', String excludes = '', boolean useDefaultExcludes = true, boolean allowEmpty = false) { 19 if(!name) throw new IllegalArgumentException("name must not be '$name'") 20 echo "Stash content: ${name} (includes: ${includes}, excludes: ${excludes}, useDefaultExcludes: ${useDefaultExcludes}, allowEmpty: ${allowEmpty})" 21 22 Map stashParams = [ 23 name : name, 24 includes: includes, 25 excludes: excludes 26 ] 27 //only set the optional parameter if default excludes should not be applied 28 if (!useDefaultExcludes) { 29 stashParams.useDefaultExcludes = useDefaultExcludes 30 } 31 //only set the optional parameter if allow empty should be applied 32 if (allowEmpty) { 33 stashParams.allowEmpty = allowEmpty 34 } 35 steps.stash stashParams 36 } 37 38 def stashList(script, List stashes) { 39 for (def stash : stashes) { 40 def name = stash.name 41 def includes = stash.includes 42 def excludes = stash.excludes 43 44 if (stash?.merge == true) { 45 String lockingResourceGroup = script.commonPipelineEnvironment.projectName?:env.JOB_NAME 46 String lockName = "${lockingResourceGroup}/${stash.name}" 47 lock(lockName) { 48 unstash stash.name 49 echo "Stash content: ${name} (includes: ${includes}, excludes: ${excludes})" 50 steps.stash name: name, includes: includes, excludes: excludes, allowEmpty: true 51 } 52 } else { 53 echo "Stash content: ${name} (includes: ${includes}, excludes: ${excludes})" 54 steps.stash name: name, includes: includes, excludes: excludes, allowEmpty: true 55 } 56 } 57 } 58 59 def stashWithMessage(name, msg, include = '**/*.*', exclude = '', useDefaultExcludes = true) { 60 try { 61 stash(name, include, exclude, useDefaultExcludes) 62 } catch (e) { 63 echo msg + name + " (${e.getMessage()})" 64 } 65 } 66 67 def stashStageFiles(Script script, String stageName) { 68 List stashes = script.commonPipelineEnvironment.configuration.stageStashes?.get(stageName)?.stashes ?: [] 69 70 stashList(script, stashes) 71 72 //NOTE: We do not delete the directory in case Jenkins runs on Kubernetes. 73 // deleteDir() is not required in pods, but would be nice to have the same behaviour and leave a clean fileSystem. 74 if (!isInsidePod(script)) { 75 script.deleteDir() 76 } 77 } 78 79 def unstashStageFiles(Script script, String stageName, List stashContent = []) { 80 stashContent += script.commonPipelineEnvironment.configuration.stageStashes?.get(stageName)?.unstash ?: [] 81 82 script.deleteDir() 83 unstashAll(stashContent) 84 85 return stashContent 86 } 87 88 boolean isInsidePod(Script script) { 89 return script.env.POD_NAME 90 } 91 92 def unstash(name, msg = "Unstash failed:") { 93 94 def unstashedContent = [] 95 try { 96 echo "Unstash content: ${name}" 97 steps.unstash name 98 unstashedContent += name 99 } catch (e) { 100 echo "$msg $name (${e.getMessage()})" 101 if (e.getMessage().contains("JNLP4-connect")) { 102 sleep(3) // Wait 3 seconds in case it has been a network hiccup 103 try { 104 echo "[Retry JNLP4-connect issue] Unstashing content: ${name}" 105 steps.unstash name 106 unstashedContent += name 107 } catch (errRetry) { 108 msg = "[Retry JNLP4-connect issue] Unstashing failed:" 109 echo "$msg $name (${errRetry.getMessage()})" 110 } 111 } 112 } 113 return unstashedContent 114 } 115 116 def unstashAll(stashContent) { 117 def unstashedContent = [] 118 if (stashContent) { 119 for (int i = 0; i < stashContent.size(); i++) { 120 if (stashContent[i]) { 121 unstashedContent += unstash(stashContent[i]) 122 } 123 } 124 } 125 return unstashedContent 126 } 127 128 @NonCPS 129 def generateSha1(input) { 130 return MessageDigest 131 .getInstance("SHA-1") 132 .digest(input.getBytes(StandardCharsets.UTF_8)) 133 .encodeHex().toString() 134 } 135 136 void pushToSWA(Map parameters, Map config) { 137 try { 138 parameters.actionName = parameters.get('actionName') ?: 'Piper Library OS' 139 parameters.eventType = parameters.get('eventType') ?: 'library-os' 140 parameters.jobUrlSha1 = generateSha1(env.JOB_URL ?: '') 141 parameters.buildUrlSha1 = generateSha1(env.BUILD_URL ?: '') 142 143 Telemetry.notify(this, config, parameters) 144 } catch (ignore) { 145 // some error occured in telemetry reporting. This should not break anything though. 146 echo "[${parameters.step}] Telemetry Report failed: ${ignore.getMessage()}" 147 } 148 } 149 150 @NonCPS 151 static String fillTemplate(String templateText, Map binding) { 152 def engine = new GStringTemplateEngine() 153 String result = engine.createTemplate(templateText).make(binding) 154 return result 155 } 156 157 static String downloadSettingsFromUrl(script, String url, String targetFile = 'settings.xml') { 158 if (script.fileExists(targetFile)) { 159 throw new RuntimeException("Trying to download settings file to ${targetFile}, but a file with this name already exists. Please specify a unique file name.") 160 } 161 162 def settings = script.httpRequest(url) 163 script.writeFile(file: targetFile, text: settings.getContent()) 164 return targetFile 165 } 166 167 /* 168 * Uses the Maven Help plugin to evaluate the given expression into the resolved values 169 * that maven sees at / generates at runtime. This way, the exact Maven coordinates and 170 * variables can be used. 171 */ 172 static String evaluateFromMavenPom(Script script, String pomFileName, String pomPathExpression) { 173 174 String resolvedExpression = script.mavenExecute( 175 script: script, 176 pomPath: pomFileName, 177 goals: ['org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate'], 178 defines: ["-Dexpression=$pomPathExpression", "-DforceStdout", "-q"], 179 returnStdout: true 180 ) 181 if (resolvedExpression.startsWith('null object or invalid expression')) { 182 // There is no error indication (exit code or otherwise) from the 183 // 'evaluate' Maven plugin, only this output to stdout. The calling 184 // code assumes an empty string is returned when the property could 185 // not be resolved. 186 throw new RuntimeException("Cannot evaluate property value from '${pomFileName}', " + 187 "missing property or invalid expression '${pomPathExpression}'.") 188 } 189 return resolvedExpression 190 } 191 192 static List appendParameterToStringList(List list, Map parameters, String paramName) { 193 def value = parameters[paramName] 194 List result = [] 195 result.addAll(list) 196 if (value in CharSequence) { 197 result.add(value) 198 } else if (value in List) { 199 result.addAll(value) 200 } 201 return result 202 }