[英]How can I update a global Environment Variable using Groovy PostBuild in Jenkins permanently and use it in other subsequent builds?
[英]Creating a Jenkins environment variable using Groovy
我的项目采用版本号(以“.”或“_”分隔)。 我尝试编写一个 Groovy 脚本,该脚本仅使用这些数字中的前两个来创建 Jenkins 环境变量:
//Get the version parameter
def env = System.getenv()
def version = env['currentversion']
def m = version =~/\d{1,2}/
env = ['miniVersion':m[0].m[1]]
我这样做正确吗? 我什至可以创建一个新的环境变量吗? 有没有更好的解决方案?
以下 groovy 代码段应该传递版本(正如您已经提供的那样),并将其作为“miniVersion”存储在作业的变量中。
import hudson.model.*
def env = System.getenv()
def version = env['currentversion']
def m = version =~/\d{1,2}/
def minVerVal = m[0]+"."+m[1]
def pa = new ParametersAction([
new StringParameterValue("miniVersion", minVerVal)
])
// add variable to current job
Thread.currentThread().executable.addAction(pa)
然后可以从其他构建步骤访问该变量。 例如
echo miniVersion=%miniVersion%
输出:
miniVersion=12.34
我相信您需要使用“系统 Groovy 脚本”(仅在主节点上)而不是“Groovy 插件” - https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin# Groovyplugin-GroovyScriptvsSystemGroovyScript
我相信之前( Jenkins 1.x )的行为因为这个安全公告而停止工作......
可以通过将系统属性hudson.model.ParametersAction.keepUndefinedParameters
设置为true
来恢复以前的行为。 这可能非常不安全,仅用作短期解决方法。
java -Dhudson.model.ParametersAction.keepUndefinedParameters=true -jar jenkins.war
要允许将特定的已知安全参数名称传递给构建,请将系统属性hudson.model.ParametersAction.safeParameters
设置为以逗号分隔的安全参数名称列表。
例如
java -Dhudson.model.ParametersAction.safeParameters=miniVersion,FOO,BAR -jar jenkins.war
您还可以在 Groovy 系统脚本中定义一个没有 EnvInject 插件的变量:
import hudson.model.*
def build = Thread.currentThread().executable
def pa = new ParametersAction([
new StringParameterValue("FOO", "BAR")
])
build.addAction(pa)
然后你可以在下一个构建步骤中访问这个变量(例如)是一个 Windows 批处理命令:
@echo off
Setlocal EnableDelayedExpansion
echo FOO=!FOO!
此回声将显示“FOO=BAR”。
问候
对我来说,以下内容也适用于 Jenkins 2 (2.73.3)
代替
def pa = new ParametersAction([new StringParameterValue("FOO", foo)])
build.addAction(pa)
和
def pa = new ParametersAction([new StringParameterValue("FOO", foo)], ["FOO"])
build.addAction(pa)
ParametersAction 似乎有第二个构造函数,它允许传入“additionalSafeParameters” https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/model/ParametersAction.java
正如其他答案所述,设置新的ParametersAction
是注入一个或多个环境变量的方法,但是当作业已经参数化时,添加新操作将不会生效。 相反,您将看到指向同一组参数的构建参数的两个链接,您想要添加的链接将为null
。
这是在两种情况下更新参数列表的片段(参数化和非参数化作业):
import hudson.model.*
def build = Thread.currentThread().executable
def env = System.getenv()
def version = env['currentversion']
def m = version =~/\d{1,2}/
def minVerVal = m[0]+"."+m[1]
def newParams = null
def pl = new ArrayList<StringParameterValue>()
pl.add(new StringParameterValue('miniVersion', miniVerVal))
def oldParams = build.getAction(ParametersAction.class)
if(oldParams != null) {
newParams = oldParams.createUpdated(pl)
build.actions.remove(oldParams)
} else {
newParams = new ParametersAction(pl)
}
build.addAction(newParams)
Jenkins EnvInject 插件或许可以帮到你。 它允许将环境变量注入构建环境。
我知道它有一些编写脚本的能力,所以它可能能够做你想做的事。 我只用它来设置简单的属性(例如“LOG_PATH=${WORKSPACE}\\logs”)。
经过一番搜索,我认为最好的解决方案是使用 hudson.model.EnvironmentContributingAction。
import hudson.model.EnvironmentContributingAction
import hudson.model.AbstractBuild
import hudson.EnvVars
class BuildVariableInjector {
def build
def out
def BuildVariableInjector(build, out) {
this.build = build
this.out = out
}
def addBuildEnvironmentVariable(key, value) {
def action = new VariableInjectionAction(key, value)
build.addAction(action)
//Must call this for action to be added
build.getEnvironment()
}
class VariableInjectionAction implements EnvironmentContributingAction {
private String key
private String value
public VariableInjectionAction(String key, String value) {
this.key = key
this.value = value
}
public void buildEnvVars(AbstractBuild build, EnvVars envVars) {
if (envVars != null && key != null && value != null) {
envVars.put(key, value);
}
}
public String getDisplayName() {
return "VariableInjectionAction";
}
public String getIconFileName() {
return null;
}
public String getUrlName() {
return null;
}
}
}
我在作业中的系统 groovy 脚本(使用 groovy 插件)中使用此类。
import hudson.model.*
import java.io.File;
import jenkins.model.Jenkins;
def jenkinsRootDir = build.getEnvVars()["JENKINS_HOME"];
def parent = getClass().getClassLoader()
def loader = new GroovyClassLoader(parent)
def buildVariableInjector = loader.parseClass(new File(jenkinsRootDir + "/userContent/GroovyScripts/BuildVariableInjector.groovy")).newInstance(build, getBinding().out)
def projectBranchDependencies = []
//Some logic to set projectBranchDependencies variable
buildVariableInjector.addBuildEnvironmentVariable("projectBranchDependencies", projectBranchDependencies.join(","));
然后,您可以在构建中的任何其他点访问 projectBranchDependencies 变量,就我而言,是从 ANT 脚本访问。
注意:我从一篇博客文章中借用/修改了此实现部分的想法,但在发布这篇文章时,我无法找到原始来源以给予应有的信任。
刚刚有同样的问题。 想要根据一些 groovy 脚本的结果动态触发参数化的下游作业。
不幸的是,在我们的 Jenkins 上无法运行 System Groovy 脚本。 因此我不得不做一个小的解决方法:
运行 groovy 脚本,该脚本创建一个属性文件,其中指定了要设置的环境变量
def props = new File("properties.text") if (props.text == 'foo=bar') { props.text = 'foo=baz' } else { props.text = 'foo=bar' }
使用 env inject 插件注入写入这个脚本的变量
Inject environment variable Property file path: properties.text
之后,我可以使用变量“foo”作为参数化触发器插件的参数。 某种解决方法。 但是有效!
我的环境是以前的工具,例如 Jenkins,并且正在运行批处理文件(我知道,我老了)。 所以那些批处理文件(及其子批处理文件)正在使用环境变量。 这是我的一段 groovy 脚本,它注入了环境变量。 使用的名称和参数是虚拟的。
// The process/batch which uses environment variables
def buildLabel = "SomeVersionNr"
def script = "startBuild.bat"
def processBuilder = new ProcessBuilder(script, buildLabel)
//Inject our environment variables
Map<String, String> env = processBuilder.environment()
env.put("ProjectRoot", "someLocation")
env.put("SomeVar", "Some")
Process p = processBuilder.start()
p.waitFor()
当然,如果您从头开始设置 Jenkins,您可能会采用不同的方式并以另一种方式共享变量,或者传递参数,但这可能会派上用场。
就我而言,它只能通过替换现有参数来以这种方式工作。
def artifactNameParam = new StringParameterValue('CopyProjectArtifactName', 'bla bla bla')
build.replaceAction(new ParametersAction(artifactNameParam))
此外,此脚本必须与系统 groovy一起运行。
必须在该系统上手动安装 groovy,并且必须将 groovy 的bin目录添加到path 。 另外在lib文件夹中,我必须添加jenkins-core.jar 。
然后可以在 groovy 脚本中修改参数并在继续工作后在批处理脚本中获取修改后的值。
对我来说,以下适用于 Jenkins 2.190.1 并且比其他一些解决方法简单得多:
matcher = manager.getLogMatcher('^.*Text we want comes next: (.*)$');
if (matcher.matches()) {
def myVar = matcher.group(1);
def envVar = new EnvVars([MY_ENV_VAR: myVar]);
def newEnv = Environment.create(envVar);
manager.build.environments.add(0, newEnv);
// now the matched text from the LogMatcher is passed to an
// env var we can access at $MY_ENV_VAR in post build steps
}
这是使用 Groovy Script 插件,对 Jenkins 没有额外更改。
如果要使用更广泛,您还可以为 jenkins 创建一个全局环境变量。 写在这里比较长。
import hudson.EnvVars;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import hudson.slaves.NodeProperty;
import hudson.slaves.NodePropertyDescriptor;
import hudson.util.DescribableList;
import jenkins.model.Jenkins;
public createGlobalEnvironmentVariables(String key, String value){
Jenkins instance = Jenkins.getInstance();
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties = instance.getGlobalNodeProperties();
List<EnvironmentVariablesNodeProperty> envVarsNodePropertyList = globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class);
EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = null;
EnvVars envVars = null;
if ( envVarsNodePropertyList == null || envVarsNodePropertyList.size() == 0 ) {
newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
globalNodeProperties.add(newEnvVarsNodeProperty);
envVars = newEnvVarsNodeProperty.getEnvVars();
} else {
envVars = envVarsNodePropertyList.get(0).getEnvVars();
}
envVars.put(key, value)
instance.save()
}
createGlobalEnvironmentVariables('Var1','Dummy')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.