![](/img/trans.png)
[英]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.