问题
I am trying to set Jenkins environment variables at runtime via the EnvironmentContributor.buildEnvironmentFor() method. Suppose I set an environment variable named "existingKey" with value "oldValue" in the Jenkins configure page. If I set existingKey to any other value by using EnvVars.overrideAll it doesn't take. New key/value pairs persist. Here's my code:
@Extension
public class MyEnvironmentContributor extends EnvironmentContributor {
Logger log...
@Override
public void buildEnvironmentFor(@Nonnull Job j, @Nonnull EnvVars envs, @Nonnull TaskListener listener) throws IOException, InterruptedException {
log.fine("pre: existingKey="+envs.get("existingKey"));
HashMap<String, String> newEnvVars = new HashMap<String, String>();
newEnvVars.put("newKey", "newValue");
newEnvVars.put("existingKey","newValue");
envs.overrideAll(newEnvVars);
log.fine("post: existingKey="+envs.get("existingKey"));
}
}
I have tested the above with both buildEnvironmentFor(Job,...) and buildEnvironmentFor(Run,...) with the same result. I have also tried EnvVar.override() and envVar.overrideExpandingAll(), none seem to work.
I have also extended RunListener, which allows me to monitor if my env variables get set.
@Extension
public class MyRunListener extends RunListener<Run> {
Logger log.....
public MyRunListener(){
//lazy loaded class
}
@Override
public void onStarted(final Run run, final TaskListener listener) {
log.fine("Build Started: " + run.getUrl() + ", " + run.getDisplayName());
try{
EnvVars env = run.getEnvironment(listener);
for (Entry<String, String> entry : env.entrySet()) {
log.fine(entry.getKey() + "=" + entry.getValue());
}
}catch(){//trivial}
}
}
The resulting logs look like this:
Build Started: job/Test/job/EnvTest/20/, #20
pre: existingKey=oldValue
post: existingKey=newValue
newKey=newValue
existingKey=oldValue
I am also printing out the env in my build container and it shows the same pattern. Any ideas how to actually override existing variables and not just set new ones?
回答1:
Since, EnvVars extends TreeMap
, before inserting existingKey
you can remove it i.e.
log.fine("pre: existingKey="+envs.get("existingKey"));
envs.remove("existingKey");
newEnvVars.put("newKey", "newValue");
newEnvVars.put("existingKey","newValue");
envs.overrideAll(newEnvVars);
log.fine("post: existingKey="+envs.get("existingKey"));
回答2:
It looks like this is not possible.
And yes
env
caches variables after first use, to avoid performance problems. There is not currently any provision to rerunEnvironmentContributor
s, nor any API in Jenkins for such contributors to indicate that their result might have changed since the last call. https://groups.google.com/forum/#!msg/jenkinsci-dev/FM_Nx_K_v9g/4BzWXd3cAgAJ
来源:https://stackoverflow.com/questions/48510209/jenkins-api-envvars-overrideall-not-overriding-existing-environment-variables-i