39

我的项目有一个版本号(用“.”或“_”分隔)。我尝试编写一个 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]]

我这样做正确吗?我什至可以创建一个新的环境变量吗?有没有更好的解决方案?

4

11 回答 11

53

詹金斯 1.x

下面的 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

詹金斯 2.x

我相信以前的(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 中这两行应该这样写:

System.setProperty("hudson.model.ParametersAction.keepUndefinedParameters","true");
System.setProperty("hudson.model.ParametersAction.safeParameters","miniVersion,FOO,BAR");  
于 2012-10-04T06:31:29.543 回答
23

您还可以在 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”。

问候

于 2014-02-21T13:59:42.287 回答
14

对我来说,以下内容也适用于 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

于 2018-01-22T09:01:45.900 回答
10

正如其他答案状态设置新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)
于 2014-09-11T20:37:35.657 回答
9

Jenkins EnvInject 插件也许可以帮助你。它允许将环境变量注入构建环境。

我知道它有一些编写脚本的能力,所以它可能能够做你想做的事。我只用它来设置简单的属性(例如“LOG_PATH=${WORKSPACE}\logs”)。

于 2012-05-02T14:00:35.007 回答
8

经过一番搜索,我认为最好的解决方案是使用 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 脚本。

注意:我从博客文章中借用/修改了此实现部分的想法,但在发布本文时,我无法找到原始来源以便给予应有的信任。

于 2016-04-07T13:18:38.953 回答
4

只是有同样的问题。希望根据一些 groovy 脚本的结果动态触发参数化的下游作业。

不幸的是,在我们的 Jenkins 上,无法运行 System Groovy 脚本。因此我不得不做一个小解决方法:

  1. 运行 groovy 脚本,该脚本创建一个属性文件,其中指定了要设置的环境变量

    def props = new File("properties.text")
    if (props.text == 'foo=bar') {
        props.text = 'foo=baz'
    } else {
        props.text = 'foo=bar'
    }
    
  2. 使用 env injection 插件将写入此脚本的变量注入

    Inject environment variable
    Property file path: properties.text
    

之后,我可以使用变量 'foo' 作为参数化触发器插件的参数。某种解决方法。但是有效!

于 2015-09-09T16:48:14.533 回答
1

我的环境是之前的工具,例如 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,您可能会采用不同的方式并以另一种方式共享变量,或者传递参数,但这可能会派上用场。

于 2017-08-04T17:31:03.000 回答
0

在我这边,它只能通过替换现有参数以这种方式工作。

def artifactNameParam = new StringParameterValue('CopyProjectArtifactName', 'bla bla bla')
build.replaceAction(new ParametersAction(artifactNameParam))

此外,此脚本必须与系统 groovy一起运行。

必须在该系统上手动安装 groovy,并且必须将 groovy 的bin目录添加到path。此外,在lib文件夹中,我必须添加jenkins-core.jar

然后可以在 groovy 脚本中修改参数并在批处理脚本中获取修改后的值以继续工作。

于 2019-06-26T13:21:05.050 回答
0

对我来说,以下工作适用于 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 进行额外更改。

于 2019-11-15T20:48:17.683 回答
0

如果想更广泛地使用,您还可以为 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')
于 2022-01-04T11:15:12.777 回答