Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-54133] Encode console notes on master for JEP-210 compatibility #32

Merged
merged 6 commits into from
Oct 29, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .mvn/extensions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<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">
<extension>
<groupId>io.jenkins.tools.incrementals</groupId>
<artifactId>git-changelist-maven-extension</artifactId>
<version>1.0-beta-7</version>
</extension>
</extensions>
2 changes: 2 additions & 0 deletions .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-Pconsume-incrementals
-Pmight-produce-incrementals
25 changes: 17 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.31</version>
<version>3.25</version>
<relativePath />
</parent>

<artifactId>ant</artifactId>
<version>1.9-SNAPSHOT</version>
<version>${revision}${changelist}</version>
<packaging>hpi</packaging>
<name>Ant Plugin</name>
<description>Adds Apache Ant support to Jenkins</description>
Expand All @@ -24,18 +24,21 @@
<scm>
<connection>scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<tag>HEAD</tag>
<tag>${scmTag}</tag>
</scm>

<properties>
<jenkins.version>1.651.3</jenkins.version>
<revision>1.9</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.121.2</jenkins.version>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big jump, but required for JEP-210 compatibility. Based on these usage stats, around 73% of users of ant 1.8 are on Jenkins 2.121.2 or newer anyway, so this seems fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway even if there is some unrelated fix we realize we need to deliver urgently to the remaining 27%, it is easy enough to publish a backport.

<java.level>8</java.level>
</properties>

<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.6</version>
<version>1.17</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
Expand All @@ -52,13 +55,13 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.32</version>
<version>2.58</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.9</version>
<version>2.26</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -70,7 +73,13 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<version>2.5</version>
<version>2.23-rc763.103ba9929364</version> <!-- TODO https://github.com/jenkinsci/workflow-durable-task-step-plugin/pull/81 -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>durable-task</artifactId>
<version>1.27-rc372.48473ef5775d</version> <!-- TODO https://github.com/jenkinsci/durable-task-plugin/pull/84 -->
<scope>test</scope>
</dependency>
<dependency>
Expand Down
36 changes: 21 additions & 15 deletions src/main/java/hudson/tasks/Ant.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.kohsuke.stapler.QueryParameter;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.remoting.VirtualChannel;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -395,22 +396,27 @@ public void buildEnvVars(EnvVars env) {
* Gets the executable path of this Ant on the given target system.
*/
public String getExecutable(Launcher launcher) throws IOException, InterruptedException {
return launcher.getChannel().call(new MasterToSlaveCallable<String,IOException>() {
private static final long serialVersionUID = 906341330603832653L;
public String call() throws IOException {
File exe = getExeFile();
if(exe.exists())
return exe.getPath();
return null;
}
});
VirtualChannel channel = launcher.getChannel();
if (channel == null) {
throw new IOException("offline?");
}
return channel.call(new GetExecutable(getHome()));
}

private File getExeFile() {
String execName = Functions.isWindows() ? "ant.bat" : "ant";
String home = Util.replaceMacro(getHome(), EnvVars.masterEnvVars);

return new File(home,"bin/"+execName);
private static class GetExecutable extends MasterToSlaveCallable<String, IOException> {
private static final long serialVersionUID = 906341330603832653L;
private final String rawHome;
GetExecutable(String rawHome) {
this.rawHome = rawHome;
}
@Override public String call() throws IOException {
String execName = Functions.isWindows() ? "ant.bat" : "ant";
String home = Util.replaceMacro(rawHome, EnvVars.masterEnvVars);
File exe = new File(home, "bin/" + execName);
if (exe.exists()) {
return exe.getPath();
}
return null;
}
}

/**
Expand Down
35 changes: 32 additions & 3 deletions src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
import hudson.console.ConsoleLogFilter;
import hudson.console.LineTransformationOutputStream;
import hudson.model.Run;
import java.io.ByteArrayOutputStream;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import jenkins.util.JenkinsJVM;

/**
* Filter {@link OutputStream} that places an annotation that marks Ant target execution.
Expand All @@ -43,12 +45,32 @@
public class AntConsoleAnnotator extends LineTransformationOutputStream {
private final OutputStream out;
private final Charset charset;
/** Serialized, signed, and Base64-encoded forms of {@link AntTargetNote} and {@link AntOutcomeNote} respectively. */
private final byte[][] antNotes;

private boolean seenEmptyLine;

public AntConsoleAnnotator(OutputStream out, Charset charset) {
this(out, charset, createAntNotes());
}

private AntConsoleAnnotator(OutputStream out, Charset charset, byte[][] antNotes) {
this.out = out;
this.charset = charset;
this.antNotes = antNotes;
}

private static byte[][] createAntNotes() {
JenkinsJVM.checkJenkinsJVM();
try {
ByteArrayOutputStream targetNote = new ByteArrayOutputStream();
new AntTargetNote().encodeTo(targetNote);
ByteArrayOutputStream outcomeNote = new ByteArrayOutputStream();
new AntOutcomeNote().encodeTo(outcomeNote);
return new byte[][] {targetNote.toByteArray(), outcomeNote.toByteArray()};
} catch (IOException x) { // should be impossible
throw new RuntimeException(x);
}
}

@Override
Expand All @@ -60,10 +82,10 @@ protected void eol(byte[] b, int len) throws IOException {

if (seenEmptyLine && endsWith(line,':') && line.indexOf(' ')<0)
// put the annotation
new AntTargetNote().encodeTo(out);
out.write(antNotes[0]);

if (line.equals("BUILD SUCCESSFUL") || line.equals("BUILD FAILED"))
new AntOutcomeNote().encodeTo(out);
out.write(antNotes[1]);

seenEmptyLine = line.length()==0;
out.write(b,0,len);
Expand All @@ -85,8 +107,15 @@ public static ConsoleLogFilter asConsoleLogFilter() {
}
private static class ConsoleLogFilterImpl extends ConsoleLogFilter implements Serializable {
private static final long serialVersionUID = 1;
private byte[][] antNotes = createAntNotes();
private Object readResolve() {
if (antNotes == null) { // old program.dat
antNotes = createAntNotes();
}
return this;
}
@Override public OutputStream decorateLogger(Run build, OutputStream logger) throws IOException, InterruptedException {
return new AntConsoleAnnotator(logger, Charsets.UTF_8);
return new AntConsoleAnnotator(logger, Charsets.UTF_8, antNotes);
}
}

Expand Down
14 changes: 10 additions & 4 deletions src/test/java/hudson/tasks/AntWrapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@

import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.console.ConsoleNote;
import hudson.model.FreeStyleProject;
import hudson.slaves.DumbSlave;
import java.util.logging.Level;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
Expand All @@ -38,6 +41,7 @@
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.LoggerRule;
import org.jvnet.hudson.test.RestartableJenkinsRule;
import org.jvnet.hudson.test.ToolInstallations;

Expand All @@ -46,6 +50,7 @@ public class AntWrapperTest {
@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public RestartableJenkinsRule r = new RestartableJenkinsRule();
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@Rule public LoggerRule logging = new LoggerRule();

@Test public void configRoundTrip() throws Exception {
r.addStep(new Statement() {
Expand All @@ -70,12 +75,13 @@ public class AntWrapperTest {
r.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
ToolInstallations.configureDefaultAnt(tmp); // TODO could instead use DockerRule<JavaContainer> to run against a specified JDK location
DumbSlave s = r.j.createOnlineSlave();
logging.recordPackage(ConsoleNote.class, Level.FINE);
WorkflowJob p = r.j.createProject(WorkflowJob.class, "p");
r.j.jenkins.getWorkspaceFor(p).child("build.xml").copyFrom(AntWrapperTest.class.getResource("_ant/simple-build.xml"));
p.setDefinition(new CpsFlowDefinition("node {withAnt(installation: 'default') {if (isUnix()) {sh 'ant foo'} else {bat 'ant foo'}}}", true));
s.getWorkspaceFor(p).child("build.xml").copyFrom(AntWrapperTest.class.getResource("_ant/simple-build.xml"));
p.setDefinition(new CpsFlowDefinition("node('!master') {withAnt(installation: 'default') {if (isUnix()) {sh 'ant foo'} else {bat 'ant foo'}}}", true));
WorkflowRun b = r.j.buildAndAssertSuccess(p);
// TODO passes locally, fails in jenkins.ci: AntConsoleAnnotator processes AntOutcomeNote but not AntTargetNote
// (perhaps because it seems to have set ANT_HOME=/opt/ant/latest? yet the output looks right)
b.getLogText().writeRawLogTo(0, System.err);
AntTest.assertHtmlLogContains(b, "<b class=ant-target>foo</b>");
AntTest.assertHtmlLogContains(b, "<b class=ant-target>bar</b>");
JenkinsRule.WebClient wc = r.j.createWebClient();
Expand Down