From 213af04b695957617c114d1df827d58f81d0faed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Fri, 1 Jun 2018 13:15:09 +0200 Subject: [PATCH] [JENKINS-51170] Enable the usage of the StepEnvironmentContributor extensionpoint Support the new StepEnvironmentContributor hook introduced in jenkinsci/workflow-step-api-plugin#36. --- pom.xml | 6 +- .../plugins/workflow/cps/EnvActionImpl.java | 15 ++++- .../DynamicEnvironmentExpanderTest.java | 63 +++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index be1cadab0..5092b0f20 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ org.jenkins-ci.plugins plugin - 3.28 + 3.32 org.jenkins-ci.plugins.workflow @@ -68,7 +68,7 @@ 8 false 3.1.0 - 2.21 + 3.2-rc711.a7efba98306d 2.2.6 1.25 1.17 @@ -77,7 +77,7 @@ org.jenkins-ci.plugins.workflow workflow-step-api - 2.18 + 2.19-rc508.410020b15345 org.jenkins-ci.plugins.workflow diff --git a/src/main/java/org/jenkinsci/plugins/workflow/cps/EnvActionImpl.java b/src/main/java/org/jenkinsci/plugins/workflow/cps/EnvActionImpl.java index 69a96a0a8..4f2309f1d 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/cps/EnvActionImpl.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/cps/EnvActionImpl.java @@ -64,6 +64,10 @@ private EnvActionImpl() { } @Override public EnvVars getEnvironment() throws IOException, InterruptedException { + return getEnvironment(getListener()); + } + + private TaskListener getListener() throws IOException { TaskListener listener; if (owner instanceof FlowExecutionOwner.Executable) { FlowExecutionOwner executionOwner = ((FlowExecutionOwner.Executable) owner).asFlowExecutionOwner(); @@ -75,6 +79,10 @@ private EnvActionImpl() { } else { listener = new LogTaskListener(LOGGER, Level.INFO); } + return listener; + } + + private EnvVars getEnvironment(TaskListener listener) throws IOException, InterruptedException { EnvVars e = owner.getEnvironment(listener); e.putAll(env); return e; @@ -88,7 +96,12 @@ private EnvActionImpl() { @Override public String getProperty(String propertyName) { try { CpsThread t = CpsThread.current(); - return EnvironmentExpander.getEffectiveEnvironment(getEnvironment(), t.getContextVariable(EnvVars.class), t.getContextVariable(EnvironmentExpander.class)).get(propertyName); + TaskListener listener = getListener(); + + return EnvironmentExpander.getEffectiveEnvironment( + getEnvironment(listener), t.getContextVariable(EnvVars.class), + t.getContextVariable(EnvironmentExpander.class), null, listener) + .get(propertyName); } catch (Exception x) { LOGGER.log(Level.WARNING, null, x); return null; diff --git a/src/test/java/org/jenkinsci/plugins/workflow/DynamicEnvironmentExpanderTest.java b/src/test/java/org/jenkinsci/plugins/workflow/DynamicEnvironmentExpanderTest.java index e59cad60a..09a916baf 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/DynamicEnvironmentExpanderTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/DynamicEnvironmentExpanderTest.java @@ -24,14 +24,20 @@ package org.jenkinsci.plugins.workflow; +import com.google.common.collect.ImmutableSet; import hudson.EnvVars; import hudson.model.EnvironmentContributor; import hudson.model.Run; import hudson.model.TaskListener; import java.io.IOException; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Set; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; +import org.jenkinsci.plugins.workflow.graph.FlowNode; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback; @@ -39,7 +45,9 @@ import org.jenkinsci.plugins.workflow.steps.Step; import org.jenkinsci.plugins.workflow.steps.StepContext; import org.jenkinsci.plugins.workflow.steps.StepDescriptor; +import org.jenkinsci.plugins.workflow.steps.StepEnvironmentContributor; import org.jenkinsci.plugins.workflow.steps.StepExecution; +import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; import org.junit.ClassRule; import org.junit.Rule; @@ -145,4 +153,59 @@ private static class ExpanderImpl extends EnvironmentExpander { } } + @Issue("JENKINS-51170") + @Test public void perStepEnvironment() { + story.then(r -> { + WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); + p.setDefinition(new CpsFlowDefinition("printEnv \"VAR\"; printEnv \"VAR\"", true)); + WorkflowRun b = story.j.buildAndAssertSuccess(p); + r.assertLogContains("VAR=1", b); + r.assertLogContains("VAR=2", b); + }); + } + + @TestExtension("perStepEnvironment") public static class StepEnvAdder extends StepEnvironmentContributor { + private Map stepNumbers = new HashMap<>(); + + @Override + public void buildEnvironmentFor(@CheckForNull StepContext stepContext, + @Nonnull EnvVars envs, + @CheckForNull TaskListener listener) throws IOException, InterruptedException { + + FlowNode node = stepContext.get(FlowNode.class); + int stepNumber = stepNumbers.computeIfAbsent(node.getId(), (k) -> stepNumbers.size() + 1); + envs.override("VAR", String.valueOf(stepNumber)); + } + } + + public static class PrintEnvStep extends Step { + private final String var; + @DataBoundConstructor + public PrintEnvStep(String var) { + this.var = var; + } + + @Override + public StepExecution start(StepContext context) throws Exception { return new Execution(context, var); } + + private static class Execution extends SynchronousStepExecution { + private final String var; + + Execution(StepContext context, String var) { super(context); this.var = var; } + + @Override + protected Void run() throws Exception { + StepContext context = getContext(); + String message = this.var + "=" + context.get(EnvVars.class).get(var); + context.get(TaskListener.class).getLogger().println(message); + return null; + } + } + + @TestExtension("perStepEnvironment") public static class DescriptorImpl extends StepDescriptor { + @Override public String getFunctionName() { return "printEnv"; } + @Override public Set> getRequiredContext() { return ImmutableSet.of(EnvVars.class, TaskListener.class); } + } + } + }