Skip to content

Commit a11acf6

Browse files
authored
Merge branch 'master' into JENKINS-41854
2 parents bdc09c0 + 9336a7b commit a11acf6

File tree

11 files changed

+139
-82
lines changed

11 files changed

+139
-82
lines changed

.mvn/extensions.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
2+
<extension>
3+
<groupId>io.jenkins.tools.incrementals</groupId>
4+
<artifactId>git-changelist-maven-extension</artifactId>
5+
<version>1.0-beta-4</version>
6+
</extension>
7+
</extensions>

.mvn/maven.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-Pconsume-incrementals
2+
-Pmight-produce-incrementals

Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
buildPlugin(jenkinsVersions: [null, '2.73.1'])
1+
buildPlugin(jenkinsVersions: [null, '2.121.1'])

pom.xml

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
<parent>
2929
<groupId>org.jenkins-ci.plugins</groupId>
3030
<artifactId>plugin</artifactId>
31-
<version>3.2</version>
31+
<version>3.19</version>
3232
<relativePath />
3333
</parent>
3434
<groupId>org.jenkins-ci.plugins.workflow</groupId>
3535
<artifactId>workflow-durable-task-step</artifactId>
36-
<version>2.20-SNAPSHOT</version>
36+
<version>${revision}${changelist}</version>
3737
<packaging>hpi</packaging>
3838
<name>Pipeline: Nodes and Processes</name>
3939
<url>https://wiki.jenkins.io/display/JENKINS/Pipeline+Nodes+and+Processes+Plugin</url>
@@ -47,8 +47,8 @@
4747
<connection>scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
4848
<developerConnection>scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
4949
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
50-
<tag>HEAD</tag>
51-
</scm>
50+
<tag>${scmTag}</tag>
51+
</scm>
5252
<repositories>
5353
<repository>
5454
<id>repo.jenkins-ci.org</id>
@@ -62,9 +62,12 @@
6262
</pluginRepository>
6363
</pluginRepositories>
6464
<properties>
65-
<jenkins.version>2.60.3</jenkins.version>
65+
<revision>2.21</revision>
66+
<changelist>-SNAPSHOT</changelist>
67+
<jenkins.version>2.73.3</jenkins.version>
6668
<java.level>8</java.level>
6769
<workflow-step-api-plugin.version>2.13</workflow-step-api-plugin.version>
70+
<workflow-support-plugin.version>2.20</workflow-support-plugin.version>
6871
</properties>
6972
<dependencies>
7073
<dependency>
@@ -75,17 +78,17 @@
7578
<dependency>
7679
<groupId>org.jenkins-ci.plugins</groupId>
7780
<artifactId>durable-task</artifactId>
78-
<version>1.18</version>
81+
<version>1.24</version>
7982
</dependency>
8083
<dependency>
8184
<groupId>org.jenkins-ci.plugins.workflow</groupId>
8285
<artifactId>workflow-api</artifactId>
83-
<version>2.22</version>
86+
<version>2.25</version>
8487
</dependency>
8588
<dependency>
8689
<groupId>org.jenkins-ci.plugins.workflow</groupId>
8790
<artifactId>workflow-support</artifactId>
88-
<version>2.16</version>
91+
<version>${workflow-support-plugin.version}</version>
8992
</dependency>
9093
<dependency>
9194
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@@ -96,7 +99,7 @@
9699
<dependency>
97100
<groupId>org.jenkins-ci.plugins.workflow</groupId>
98101
<artifactId>workflow-job</artifactId>
99-
<version>2.9</version>
102+
<version>2.24</version>
100103
<scope>test</scope>
101104
</dependency>
102105
<dependency>
@@ -121,7 +124,7 @@
121124
<dependency>
122125
<groupId>org.jenkins-ci.plugins.workflow</groupId>
123126
<artifactId>workflow-support</artifactId>
124-
<version>2.13</version>
127+
<version>${workflow-support-plugin.version}</version>
125128
<classifier>tests</classifier>
126129
<scope>test</scope>
127130
</dependency>
@@ -134,12 +137,17 @@
134137
<dependency>
135138
<groupId>org.jenkins-ci.plugins</groupId>
136139
<artifactId>script-security</artifactId>
137-
<version>1.27</version>
140+
<version>1.39</version>
138141
</dependency>
139142
<dependency>
140143
<groupId>org.jenkins-ci.plugins</groupId>
141144
<artifactId>structs</artifactId>
142-
<version>1.7</version>
145+
<version>1.10</version>
146+
</dependency>
147+
<dependency>
148+
<groupId>org.jenkins-ci.plugins</groupId>
149+
<artifactId>scm-api</artifactId>
150+
<version>2.2.6</version>
143151
</dependency>
144152
</dependencies>
145153
</project>

src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@
3030
import hudson.EnvVars;
3131
import hudson.FilePath;
3232
import hudson.Launcher;
33+
import hudson.Util;
3334
import hudson.model.TaskListener;
3435
import hudson.util.DaemonThreadFactory;
3536
import hudson.util.FormValidation;
3637
import hudson.util.LogTaskListener;
3738
import hudson.util.NamingThreadFactory;
3839
import java.io.IOException;
3940
import java.nio.charset.Charset;
41+
import java.nio.charset.StandardCharsets;
4042
import java.util.Set;
4143
import java.util.concurrent.ScheduledFuture;
4244
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -56,6 +58,8 @@
5658
import org.jenkinsci.plugins.workflow.steps.StepExecution;
5759
import org.jenkinsci.plugins.workflow.support.concurrent.Timeout;
5860
import org.jenkinsci.plugins.workflow.support.concurrent.WithThreadName;
61+
import org.kohsuke.accmod.Restricted;
62+
import org.kohsuke.accmod.restrictions.DoNotUse;
5963
import org.kohsuke.stapler.DataBoundSetter;
6064
import org.kohsuke.stapler.QueryParameter;
6165

@@ -67,7 +71,7 @@ public abstract class DurableTaskStep extends Step {
6771
private static final Logger LOGGER = Logger.getLogger(DurableTaskStep.class.getName());
6872

6973
private boolean returnStdout;
70-
private String encoding = DurableTaskStepDescriptor.defaultEncoding;
74+
private String encoding;
7175
private boolean returnStatus;
7276

7377
protected abstract DurableTask task();
@@ -85,7 +89,7 @@ public String getEncoding() {
8589
}
8690

8791
@DataBoundSetter public void setEncoding(String encoding) {
88-
this.encoding = encoding;
92+
this.encoding = Util.fixEmpty(encoding);
8993
}
9094

9195
public boolean isReturnStatus() {
@@ -102,17 +106,16 @@ public boolean isReturnStatus() {
102106

103107
public abstract static class DurableTaskStepDescriptor extends StepDescriptor {
104108

105-
public static final String defaultEncoding = "UTF-8";
106-
109+
@Restricted(DoNotUse.class)
107110
public FormValidation doCheckEncoding(@QueryParameter boolean returnStdout, @QueryParameter String encoding) {
111+
if (encoding.isEmpty()) {
112+
return FormValidation.ok();
113+
}
108114
try {
109115
Charset.forName(encoding);
110116
} catch (Exception x) {
111117
return FormValidation.error(x, "Unrecognized encoding");
112118
}
113-
if (!returnStdout && !encoding.equals(DurableTaskStepDescriptor.defaultEncoding)) {
114-
return FormValidation.warning("encoding is ignored unless returnStdout is checked.");
115-
}
116119
return FormValidation.ok();
117120
}
118121

@@ -154,7 +157,6 @@ static final class Execution extends AbstractStepExecutionImpl implements Runnab
154157
private String node;
155158
private String remote;
156159
private boolean returnStdout; // serialized default is false
157-
private String encoding; // serialized default is irrelevant
158160
private boolean returnStatus; // serialized default is false
159161

160162
Execution(StepContext context, DurableTaskStep step) {
@@ -164,7 +166,6 @@ static final class Execution extends AbstractStepExecutionImpl implements Runnab
164166

165167
@Override public boolean start() throws Exception {
166168
returnStdout = step.returnStdout;
167-
encoding = step.encoding;
168169
returnStatus = step.returnStatus;
169170
StepContext context = getContext();
170171
ws = context.get(FilePath.class);
@@ -173,6 +174,11 @@ static final class Execution extends AbstractStepExecutionImpl implements Runnab
173174
if (returnStdout) {
174175
durableTask.captureOutput();
175176
}
177+
if (step.encoding != null) {
178+
durableTask.charset(Charset.forName(step.encoding));
179+
} else {
180+
durableTask.defaultCharset();
181+
}
176182
controller = durableTask.launch(context.get(EnvVars.class), ws, context.get(Launcher.class), context.get(TaskListener.class));
177183
this.remote = ws.getRemote();
178184
setupTimer();
@@ -327,7 +333,7 @@ private void check() {
327333
LOGGER.log(Level.FINE, "last-minute output in {0} on {1}", new Object[] {remote, node});
328334
}
329335
if (returnStatus || exitCode == 0) {
330-
getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(controller.getOutput(workspace, launcher()), encoding) : null);
336+
getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(controller.getOutput(workspace, launcher()), StandardCharsets.UTF_8) : null);
331337
} else {
332338
if (returnStdout) {
333339
listener.getLogger().write(controller.getOutput(workspace, launcher())); // diagnostic

src/main/java/org/jenkinsci/plugins/workflow/support/steps/ExecutorStepExecution.java

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.jenkinsci.plugins.workflow.support.steps;
22

3-
import com.google.inject.Inject;
43
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
54
import hudson.AbortException;
65
import hudson.EnvVars;
@@ -27,12 +26,14 @@
2726
import hudson.remoting.ChannelClosedException;
2827
import hudson.remoting.RequestAbortedException;
2928
import hudson.security.ACL;
29+
import hudson.security.ACLContext;
3030
import hudson.security.AccessControlled;
3131
import hudson.security.Permission;
3232
import hudson.slaves.WorkspaceList;
3333
import java.io.IOException;
3434
import java.io.PrintStream;
3535
import java.io.Serializable;
36+
import java.util.Arrays;
3637
import java.util.Collection;
3738
import java.util.Collections;
3839
import java.util.HashMap;
@@ -68,7 +69,6 @@
6869
import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl;
6970
import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback;
7071
import org.jenkinsci.plugins.workflow.steps.StepContext;
71-
import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
7272
import org.jenkinsci.plugins.workflow.steps.durable_task.Messages;
7373
import org.jenkinsci.plugins.workflow.support.actions.WorkspaceActionImpl;
7474
import org.jenkinsci.plugins.workflow.support.concurrent.Timeout;
@@ -111,7 +111,7 @@ public boolean start() throws Exception {
111111
try {
112112
logger = getContext().get(TaskListener.class).getLogger();
113113
} catch (Exception x) { // IOException, InterruptedException
114-
LOGGER.log(WARNING, null, x);
114+
LOGGER.log(FINE, "could not print message to build about " + item + "; perhaps it is already completed", x);
115115
return;
116116
}
117117
logger.println("Still waiting to schedule task");
@@ -127,11 +127,26 @@ public boolean start() throws Exception {
127127

128128
@Override
129129
public void stop(Throwable cause) throws Exception {
130-
for (Queue.Item item : Queue.getInstance().getItems()) {
130+
Queue.Item[] items;
131+
try (ACLContext as = ACL.as(ACL.SYSTEM)) {
132+
items = Queue.getInstance().getItems();
133+
}
134+
LOGGER.log(FINE, "stopping one of {0}", Arrays.asList(items));
135+
StepContext context = getContext();
136+
for (Queue.Item item : items) {
131137
// if we are still in the queue waiting to be scheduled, just retract that
132-
if (item.task instanceof PlaceholderTask && ((PlaceholderTask) item.task).context.equals(getContext())) {
133-
Queue.getInstance().cancel(item);
134-
break;
138+
if (item.task instanceof PlaceholderTask) {
139+
PlaceholderTask task = (PlaceholderTask) item.task;
140+
if (task.context.equals(context)) {
141+
task.stopping = true;
142+
Queue.getInstance().cancel(item);
143+
LOGGER.log(FINE, "canceling {0}", item);
144+
break;
145+
} else {
146+
LOGGER.log(FINE, "no match on {0} with {1} vs. {2}", new Object[] {item, task.context, context});
147+
}
148+
} else {
149+
LOGGER.log(FINE, "no match on {0}", item);
135150
}
136151
}
137152
Jenkins j = Jenkins.getInstance();
@@ -141,9 +156,17 @@ public void stop(Throwable cause) throws Exception {
141156
COMPUTERS: for (Computer c : j.getComputers()) {
142157
for (Executor e : c.getExecutors()) {
143158
Queue.Executable exec = e.getCurrentExecutable();
144-
if (exec instanceof PlaceholderTask.PlaceholderExecutable && ((PlaceholderTask.PlaceholderExecutable) exec).getParent().context.equals(getContext())) {
145-
PlaceholderTask.finish(((PlaceholderTask.PlaceholderExecutable) exec).getParent().cookie);
146-
break COMPUTERS;
159+
if (exec instanceof PlaceholderTask.PlaceholderExecutable) {
160+
StepContext actualContext = ((PlaceholderTask.PlaceholderExecutable) exec).getParent().context;
161+
if (actualContext.equals(context)) {
162+
PlaceholderTask.finish(((PlaceholderTask.PlaceholderExecutable) exec).getParent().cookie);
163+
LOGGER.log(FINE, "canceling {0}", exec);
164+
break COMPUTERS;
165+
} else {
166+
LOGGER.log(FINE, "no match on {0} with {1} vs. {2}", new Object[] {exec, actualContext, context});
167+
}
168+
} else {
169+
LOGGER.log(FINE, "no match on {0}", exec);
147170
}
148171
}
149172
}
@@ -213,7 +236,10 @@ public void stop(Throwable cause) throws Exception {
213236
@Override public void onLeft(Queue.LeftItem li) {
214237
if (li.isCancelled()) {
215238
if (li.task instanceof PlaceholderTask) {
216-
(((PlaceholderTask) li.task).context).onFailure(new AbortException(Messages.ExecutorStepExecution_queue_task_cancelled()));
239+
PlaceholderTask task = (PlaceholderTask) li.task;
240+
if (!task.stopping) {
241+
task.context.onFailure(new AbortException(Messages.ExecutorStepExecution_queue_task_cancelled()));
242+
}
217243
}
218244
}
219245
}
@@ -253,6 +279,9 @@ public static final class PlaceholderTask implements ContinuedTask, Serializable
253279
/** {@link Authentication#getName} of user of build, if known. */
254280
private final @CheckForNull String auth;
255281

282+
/** Flag to remember that {@link #stop} is being called, so {@link CancelledItemListener} can be suppressed. */
283+
private transient boolean stopping;
284+
256285
PlaceholderTask(StepContext context, String label) throws IOException, InterruptedException {
257286
this.context = context;
258287
this.label = label;

src/main/resources/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep/config.jelly

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ THE SOFTWARE.
3131
<f:checkbox/>
3232
</f:entry>
3333
<f:entry field="encoding" title="${%Encoding of standard output}">
34-
<f:textbox default="${descriptor.defaultEncoding}"/>
34+
<f:textbox/>
3535
</f:entry>
3636
<f:entry field="returnStatus" title="${%Return exit status}">
3737
<f:checkbox/>
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
11
<div>
2-
Encoding of standard output, if it is being captured.
2+
Encoding of process output.
3+
In the case of <code>returnStdout</code>, applies to the return value of this step;
4+
otherwise, or always for standard error, controls how text is copied to the build log.
5+
If unspecified, uses the system default encoding of the node on which the step is run.
6+
If there is any expectation that process output might include non-ASCII characters,
7+
it is best to specify the encoding explicitly.
8+
For example, if you have specific knowledge that a given process is going to be producing UTF-8
9+
yet will be running on a node with a different system encoding
10+
(typically Windows, since every Linux distribution has defaulted to UTF-8 for a long time),
11+
you can ensure correct output by specifying: <code>encoding: 'UTF-8'</code>
312
</div>

0 commit comments

Comments
 (0)