I created a groovy script which injects passed environment variables and even treats them as shell comands.
inject_env_vars.groovy
// Inject environment variables using Groovy import hudson.model.* import hudson.AbortException import groovy.json.StringEscapeUtils def build = Thread.currentThread().executable def injectEnvVars(envVars) { for (item in envVars) { build.addAction( new ParametersAction([ new StringParameterValue(item.key, item.value) ]) ) } } def bash(cmd, env) { cmd = cmd as String // create a process for the shell pb = new ProcessBuilder(["bash", "-c", cmd]) // make job workspace directory as the current one pb.directory(new File(env['WORKSPACE'])) pb.environment().putAll(env) // capture messages sent to stderr pb.redirectErrorStream(true) shell = pb.start() shell.getOutputStream().close() // capture the output from the command def shellIn = shell.getInputStream() def reader = new BufferedReader(new InputStreamReader(shellIn)) def builder = new StringBuilder() while ( (line = reader.readLine()) != null ) { builder.append(line) builder.append(System.getProperty("line.separator")) } result = builder.toString() // wait for the shell to finish and get the return code def exitStatus = shell.waitFor() try { shellIn.close(); } catch (IOException ignoreMe) {} if (exitStatus) { throw new AbortException(result) } return result } def readPropsFile(filePath) { // https://en.wikipedia.org/wiki/.properties def props = new Properties() new File(filePath).withInputStream { stream -> props.load(stream) } return props } def readEnvSh(filePath) { vars = [:] file = new File(filePath) file.eachLine { line -> def matcher = (line =~ '^(.*)=(.*)$') if (matcher) { def name = matcher.group(1) def value = matcher.group(2) if (value.startsWith('"')) { value = value[1..-2] } vars[name] = value } } return vars } // add some useful environment variables env = build.getEnvironment(listener) if (!env.containsKey('BUILD_USER')) { def userCause = build.getCause(hudson.model.Cause$UserIdCause) def userName = userCause?.userId ?: 'Jenkins' injectEnvVars([ 'BUILD_USER': userName, 'JOB_DIR': "${env.WORKSPACE}/../../jobs/${env.JOB_NAME}", 'BUILD_DIR': "${env.WORKSPACE}/../../jobs/${env.JOB_NAME}/builds/${env.BUILD_ID}", ]) } // inject build result string: http://javadoc.jenkins-ci.org/hudson/model/Result.html injectEnvVars(['BUILD_RESULT': "${build.result}"]) for (item in binding.variables.clone()) { def varName = item.key def varValue = item.value if (!(varValue instanceof String)) { // skip values injected by Jenkins Groovy plugin continue } if (varName == '_') { // run the given script code new GroovyShell( new Binding([ 'env': build.getEnvironment(listener), 'injectEnvVars': this.&injectEnvVars, 'readEnvSh': this.&readEnvSh, ]) ).evaluate(varValue) } else { varValue = StringEscapeUtils.escapeJava(varValue) varValue = bash("echo \"${varValue}\"", build.getEnvironment(listener)) injectEnvVars(["${varName}": varValue]) } }
hipchat_message='${BUILD_USER} <a href="$BUILD_URL">started deploying backend</a> to <b>${project} ${target}</b>' evaluate(new File("/home/jenkins/workspace/devops/inject_env_vars.groovy"))
hipchat_message='$(/home/jenkins/workspace/devops/deploy/get_deploy_info.py)' evaluate(new File("/home/jenkins/workspace/devops/inject_env_vars.groovy"))
// variable `_` is considered to contain script code inside `inject_env_vars.groovy`
_='''
_env = readEnvSh("${env.WORKSPACE}/env.sh")
if (env['BUILD_RESULT'] == 'SUCCESS') {
// single quoted values will be expanded when passed to injectEnvVars
_env['hipchat_message'] = 'Server build succeded: <a href="https://$SERVER_NAME/">$SERVER_NAME</a> (<a href="$BUILD_URL">Job</a>)'
} else {
...
}
injectEnvVars(_env)
'''
evaluate(new File("/home/jenkins/workspace/devops/inject_env_vars.groovy"))
These should be run as System Groovy script.
I hope this could be someday implemented as a plugin.
No comments:
Post a Comment