[JENKINS-52332] Node Api enhancement restartable flag and restart command (#1766)

* [JENKINS-52332] Implement Node API to provide information on restartable stages in BlueOcean nodes API

Signed-off-by: olivier lamy <olamy@apache.org>
This commit is contained in:
Olivier Lamy 2018-07-05 23:06:20 +02:00 committed by GitHub
parent 9f7f689502
commit 1c8705b18e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 416 additions and 25 deletions

View File

@ -67,6 +67,8 @@ public class JsonConverter{
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.configure( SerializationFeature.FAIL_ON_SELF_REFERENCES, false );
return mapper;
}
}

View File

@ -97,6 +97,11 @@
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>github-branch-source</artifactId>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-stage-tags-metadata</artifactId>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-definition</artifactId>

View File

@ -1,6 +1,5 @@
package io.jenkins.blueocean.htmlpublisher;
import com.google.common.collect.Lists;
import htmlpublisher.HtmlPublisherTarget;
import hudson.Extension;
import hudson.model.Run;
@ -11,6 +10,7 @@ import io.jenkins.blueocean.rest.model.BlueArtifact;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class HTMLArtifact extends BlueArtifact {
@ -54,11 +54,9 @@ public class HTMLArtifact extends BlueArtifact {
if (actions.isEmpty()) {
return null;
}
List<BlueArtifact> foundArtifacts = Lists.newArrayList();
for (HtmlPublisherTarget.HTMLBuildAction action : actions) {
foundArtifacts.add(new HTMLArtifact(action, parent.getLink()));
}
return foundArtifacts;
return actions.stream()
.map( action -> new HTMLArtifact(action, parent.getLink()))
.collect(Collectors.toList());
}
}
}

View File

@ -90,13 +90,7 @@ public class MultiBranchPipelineQueueContainer extends BlueQueueContainer {
retry++;
}
Collections.sort(c, new Comparator<BlueQueueItem>() {
@Override
public int compare(BlueQueueItem o1, BlueQueueItem o2) {
return o2.getQueuedTime().compareTo(o1.getQueuedTime());
}
});
Collections.sort(c, ( o1, o2 ) -> o2.getQueuedTime().compareTo(o1.getQueuedTime()));
return c.iterator();
}

View File

@ -1,24 +1,41 @@
package io.jenkins.blueocean.rest.impl.pipeline;
import hudson.model.Action;
import hudson.model.Queue;
import io.jenkins.blueocean.commons.JsonConverter;
import io.jenkins.blueocean.commons.ServiceException;
import io.jenkins.blueocean.commons.stapler.Export;
import io.jenkins.blueocean.listeners.NodeDownstreamBuildAction;
import io.jenkins.blueocean.rest.Reachable;
import io.jenkins.blueocean.rest.factory.BluePipelineFactory;
import io.jenkins.blueocean.rest.hal.Link;
import io.jenkins.blueocean.rest.model.BlueActionProxy;
import io.jenkins.blueocean.rest.model.BlueInputStep;
import io.jenkins.blueocean.rest.model.BluePipeline;
import io.jenkins.blueocean.rest.model.BluePipelineNode;
import io.jenkins.blueocean.rest.model.BluePipelineStep;
import io.jenkins.blueocean.rest.model.BluePipelineStepContainer;
import io.jenkins.blueocean.rest.model.BlueQueueItem;
import io.jenkins.blueocean.rest.model.BlueRun;
import io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl;
import io.jenkins.blueocean.service.embedded.rest.ActionProxiesImpl;
import io.jenkins.blueocean.listeners.NodeDownstreamBuildAction;
import io.jenkins.blueocean.service.embedded.rest.QueueItemImpl;
import io.jenkins.blueocean.service.embedded.rest.QueueUtil;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.jenkinsci.plugins.pipeline.modeldefinition.actions.RestartDeclarativePipelineAction;
import org.jenkinsci.plugins.workflow.actions.LogAction;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.export.Exported;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
@ -32,6 +49,7 @@ import java.util.List;
* @see FlowNode
*/
public class PipelineNodeImpl extends BluePipelineNode {
private static final Logger LOGGER = LoggerFactory.getLogger( PipelineNodeImpl.class );
private final FlowNodeWrapper node;
private final List<Edge> edges;
private final Long durationInMillis;
@ -152,6 +170,20 @@ public class PipelineNodeImpl extends BluePipelineNode {
this);
}
@Override
public boolean isRestartable() {
RestartDeclarativePipelineAction restartDeclarativePipelineAction =
this.run.getAction( RestartDeclarativePipelineAction.class );
if ( restartDeclarativePipelineAction != null ) {
List<String> restartableStages = restartDeclarativePipelineAction.getRestartableStages();
if ( restartableStages != null ) {
return restartableStages.contains(this.getDisplayName())
&& this.getStateObj() == BlueRun.BlueRunState.FINISHED;
}
}
return false;
}
@Override
public BlueInputStep getInputStep() {
return null;
@ -162,6 +194,45 @@ public class PipelineNodeImpl extends BluePipelineNode {
return null;
}
public HttpResponse restart(StaplerRequest request) {
try
{
JSONObject body = JSONObject.fromObject( IOUtils.toString( request.getReader() ) );
boolean restart = body.getBoolean( "restart" );
if ( restart && isRestartable() ) {
LOGGER.debug( "submitInputStep, restart: {}, step: {}", restart, this.getDisplayName() );
RestartDeclarativePipelineAction restartDeclarativePipelineAction =
this.run.getAction( RestartDeclarativePipelineAction.class );
Queue.Item item = restartDeclarativePipelineAction.run( this.getDisplayName() );
BluePipeline bluePipeline = BluePipelineFactory.getPipelineInstance( this.run.getParent(), this.parent );
BlueQueueItem queueItem = QueueUtil.getQueuedItem( bluePipeline.getOrganization(), item, run.getParent());
if (queueItem != null) { // If the item is still queued
return ( req, rsp, node1 ) -> {
rsp.setStatus( HttpServletResponse.SC_OK );
rsp.getOutputStream().print( Export.toJson( queueItem.toRun() ) );
};
}
WorkflowRun restartRun = QueueUtil.getRun(run.getParent(), item.getId());
if (restartRun != null) {
return ( req, rsp, node1 ) -> {
rsp.setStatus( HttpServletResponse.SC_OK );
rsp.getOutputStream().print( Export.toJson( new PipelineRunImpl(restartRun, parent,
bluePipeline.getOrganization()) ) );
};
} else { // For some reason could not be added to the queue
throw new ServiceException.UnexpectedErrorException("Run was not added to queue.");
}
}
// ISE cant happen if stage not restartable or anything else :)
} catch ( Exception e) {
LOGGER.warn( "error restarting stage: " + e.getMessage(), e);
throw new ServiceException.UnexpectedErrorException( e.getMessage());
}
return null;
}
public static class EdgeImpl extends Edge {
private final String id;
private final String type;

View File

@ -57,7 +57,7 @@ import static org.junit.Assert.fail;
* @author Vivek Pandey
*/
public abstract class PipelineBaseTest{
private static final Logger LOGGER = LoggerFactory.getLogger(PipelineBaseTest.class);
protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
@BeforeClass
public static void enableJWT() {

View File

@ -0,0 +1,88 @@
package io.jenkins.blueocean.rest.impl.pipeline;
import hudson.FilePath;
import hudson.model.Label;
import io.jenkins.blueocean.service.embedded.rest.QueueItemImpl;
import io.jenkins.blueocean.service.embedded.rest.QueuedBlueRun;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.junit.Assert.*;
public class RestartStageTest extends PipelineBaseTest
{
@Test
public void restart_stage() throws Exception {
WorkflowJob p = createWorkflowJobWithJenkinsfile( getClass(), "restartStage.jenkinsfile");
// Ensure null before first run
Map pipeline = request().get( String.format( "/organizations/jenkins/pipelines/%s/", p.getName())).build( Map.class);
Assert.assertNull( pipeline.get( "latestRun"));
j.createOnlineSlave( Label.get( "first"));
FilePath ws = j.jenkins.getWorkspaceFor(p);
FilePath noErrorMessageFile = ws.child( "TEST-io.blueocean.NoErrorMessage.xml");
noErrorMessageFile.copyFrom(RestartStageTest.class.getResource("TEST-io.blueocean.NoErrorMessage.xml"));
FilePath stdoutStderrFile = ws.child( "TEST-io.blueocean.StdoutStderr.xml");
stdoutStderrFile.copyFrom(RestartStageTest.class.getResource("TEST-io.blueocean.StdoutStderr.xml"));
// Run until completed
WorkflowRun r = p.scheduleBuild2( 0).waitForStart();
j.waitForCompletion( r );
Map runResult = get( "/organizations/jenkins/pipelines/" + p.getName() + "/runs/1");
while (runResult.get( "state" ).equals( "RUNNING" )) {
runResult = get( "/organizations/jenkins/pipelines/" + p.getName() + "/runs/1");
}
Assert.assertEquals( "SUCCESS", runResult.get( "result" ) );
// Ensure we find stage with restartable flag
List<Map> resp = get( "/organizations/jenkins/pipelines/" + p.getName() + "/runs/1/nodes/", List.class);
assertEquals(10, resp.size());
Optional<Map> optionalMap = resp.stream()
.filter( map -> map.get( "displayName" ).equals( "Static Analysis" ) )
.findFirst();
assertTrue(optionalMap.isPresent());
Map res = optionalMap.get();
assertEquals( true, res.get( "restartable" ) );
LOGGER.info( "buildNumber: {}", r.getNumber() );
noErrorMessageFile.delete();
stdoutStderrFile.delete();
// restart the stage
Map restartMap = new HashMap( 1 );
restartMap.put( "restart", true );
Map restartResult = post( "/organizations/jenkins/pipelines/" + p.getName()
+ "/runs/1/nodes/" + res.get( "id" ) + "/restart",
restartMap);
assertEquals( QueuedBlueRun.class.getName(), restartResult.get( "_class" ) );
int id = Integer.parseInt((String)restartResult.get( "id" ));
// depending on build still in queue or not when guessing the build number
assertTrue( id >= r.getNumber());
runResult = get( "/organizations/jenkins/pipelines/" + p.getName() + "/runs/2");
while (runResult.get( "state" ).equals( "RUNNING" )) {
runResult = get( "/organizations/jenkins/pipelines/" + p.getName() + "/runs/2");
}
LOGGER.info( "runResult: {}", runResult );
Assert.assertNotEquals( "FAILURE", runResult.get( "result" ) );
}
}

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite tests="1" failures="0" name="io.blueocean.TestResults" time="0.004" errors="1" skipped="0">
<properties>
<property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
<property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib"/>
<property name="java.vm.version" value="25.101-b13"/>
<property name="user.country.format" value="NZ"/>
<property name="gopherProxySet" value="false"/>
<property name="java.vm.vendor" value="Oracle Corporation"/>
<property name="maven.multiModuleProjectDirectory" value="/Users/ivan/w/b/blue-ath/src/test/resources/multibranch/test_results"/>
<property name="java.vendor.url" value="http://java.oracle.com/"/>
<property name="path.separator" value=":"/>
<property name="guice.disable.misplaced.annotation.check" value="true"/>
<property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
<property name="file.encoding.pkg" value="sun.io"/>
<property name="user.country" value="US"/>
<property name="sun.java.launcher" value="SUN_STANDARD"/>
<property name="sun.os.patch.level" value="unknown"/>
<property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
<property name="user.dir" value="/Users/ivan/w/b/blue-ath/src/test/resources/multibranch/test_results"/>
<property name="java.runtime.version" value="1.8.0_101-b13"/>
<property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
<property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/endorsed"/>
<property name="os.arch" value="x86_64"/>
<property name="java.io.tmpdir" value="/var/folders/74/xxmdr51s12d0c3l4yp9gh_fr0000gn/T/"/>
<property name="line.separator" value="
"/>
<property name="java.vm.specification.vendor" value="Oracle Corporation"/>
<property name="os.name" value="Mac OS X"/>
<property name="classworlds.conf" value="/usr/local/Cellar/maven/3.3.9/libexec/bin/m2.conf"/>
<property name="sun.jnu.encoding" value="UTF-8"/>
<property name="java.library.path" value="/Users/ivan/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
<property name="java.specification.name" value="Java Platform API Specification"/>
<property name="java.class.version" value="52.0"/>
<property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
<property name="os.version" value="10.12"/>
<property name="http.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="user.home" value="/Users/ivan"/>
<property name="user.timezone" value="Pacific/Auckland"/>
<property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
<property name="java.specification.version" value="1.8"/>
<property name="file.encoding" value="UTF-8"/>
<property name="user.name" value="ivan"/>
<property name="java.class.path" value="/usr/local/Cellar/maven/3.3.9/libexec/boot/plexus-classworlds-2.5.2.jar"/>
<property name="java.vm.specification.version" value="1.8"/>
<property name="sun.arch.data.model" value="64"/>
<property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre"/>
<property name="sun.java.command" value="org.codehaus.plexus.classworlds.launcher.Launcher test"/>
<property name="java.specification.vendor" value="Oracle Corporation"/>
<property name="user.language" value="en"/>
<property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
<property name="java.vm.info" value="mixed mode"/>
<property name="java.version" value="1.8.0_101"/>
<property name="java.ext.dirs" value="/Users/ivan/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
<property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/classes"/>
<property name="java.vendor" value="Oracle Corporation"/>
<property name="java.awt.headless" value="true"/>
<property name="maven.home" value="/usr/local/Cellar/maven/3.3.9/libexec"/>
<property name="file.separator" value="/"/>
<property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
<property name="sun.cpu.endian" value="little"/>
<property name="sun.io.unicode.encoding" value="UnicodeBig"/>
<property name="socksNonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="ftp.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="sun.cpu.isalist" value=""/>
</properties>
<testcase classname="io.blueocean.TestResults" name="testCase" time="0.004">
</testcase>
</testsuite>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite tests="1" failures="0" name="io.blueocean.TestResults.StdOut" time="0.004" errors="1" skipped="0">
<properties>
<property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
<property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib"/>
<property name="java.vm.version" value="25.101-b13"/>
<property name="user.country.format" value="NZ"/>
<property name="gopherProxySet" value="false"/>
<property name="java.vm.vendor" value="Oracle Corporation"/>
<property name="maven.multiModuleProjectDirectory" value="/Users/ivan/w/b/blue-ath/src/test/resources/multibranch/test_results"/>
<property name="java.vendor.url" value="http://java.oracle.com/"/>
<property name="path.separator" value=":"/>
<property name="guice.disable.misplaced.annotation.check" value="true"/>
<property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
<property name="file.encoding.pkg" value="sun.io"/>
<property name="user.country" value="US"/>
<property name="sun.java.launcher" value="SUN_STANDARD"/>
<property name="sun.os.patch.level" value="unknown"/>
<property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
<property name="user.dir" value="/Users/ivan/w/b/blue-ath/src/test/resources/multibranch/test_results"/>
<property name="java.runtime.version" value="1.8.0_101-b13"/>
<property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
<property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/endorsed"/>
<property name="os.arch" value="x86_64"/>
<property name="java.io.tmpdir" value="/var/folders/74/xxmdr51s12d0c3l4yp9gh_fr0000gn/T/"/>
<property name="line.separator" value="
"/>
<property name="java.vm.specification.vendor" value="Oracle Corporation"/>
<property name="os.name" value="Mac OS X"/>
<property name="classworlds.conf" value="/usr/local/Cellar/maven/3.3.9/libexec/bin/m2.conf"/>
<property name="sun.jnu.encoding" value="UTF-8"/>
<property name="java.library.path" value="/Users/ivan/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
<property name="java.specification.name" value="Java Platform API Specification"/>
<property name="java.class.version" value="52.0"/>
<property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
<property name="os.version" value="10.12"/>
<property name="http.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="user.home" value="/Users/ivan"/>
<property name="user.timezone" value="Pacific/Auckland"/>
<property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
<property name="java.specification.version" value="1.8"/>
<property name="file.encoding" value="UTF-8"/>
<property name="user.name" value="ivan"/>
<property name="java.class.path" value="/usr/local/Cellar/maven/3.3.9/libexec/boot/plexus-classworlds-2.5.2.jar"/>
<property name="java.vm.specification.version" value="1.8"/>
<property name="sun.arch.data.model" value="64"/>
<property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre"/>
<property name="sun.java.command" value="org.codehaus.plexus.classworlds.launcher.Launcher test"/>
<property name="java.specification.vendor" value="Oracle Corporation"/>
<property name="user.language" value="en"/>
<property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
<property name="java.vm.info" value="mixed mode"/>
<property name="java.version" value="1.8.0_101"/>
<property name="java.ext.dirs" value="/Users/ivan/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
<property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/classes"/>
<property name="java.vendor" value="Oracle Corporation"/>
<property name="java.awt.headless" value="true"/>
<property name="maven.home" value="/usr/local/Cellar/maven/3.3.9/libexec"/>
<property name="file.separator" value="/"/>
<property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
<property name="sun.cpu.endian" value="little"/>
<property name="sun.io.unicode.encoding" value="UnicodeBig"/>
<property name="socksNonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="ftp.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="sun.cpu.isalist" value=""/>
</properties>
<testcase classname="io.blueocean.TestResults.StdOut" name="testCase" time="0.004">
</testcase>
</testsuite>

View File

@ -0,0 +1,63 @@
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'mvn clean source:jar package'
}
}
stage('Browser Tests') {
parallel {
stage('Firefox') {
steps {
sh 'echo \'setting up selenium environment\''
//sh 'ping -c 5 localhost'
}
}
stage('Safari') {
steps {
sh 'echo \'setting up selenium environment\''
//sh 'ping -c 8 localhost'
}
}
stage('Chrome') {
steps {
sh 'echo \'setting up selenium environment\''
//sh 'ping -c 3 localhost'
}
}
stage('Internet Explorer') {
steps {
sh 'echo \'setting up selenium environment\''
//sh 'ping -c 4 localhost'
}
}
}
}
stage('Static Analysis') {
steps {
echo 'mvn findbugs:findbugs'
}
}
stage('Deploy') {
parallel {
stage('Deploy') {
steps {
echo 'mvn source:jar package -Dmaven.test.skip'
}
}
stage('final') {
steps {
echo 'fdsf223'
}
}
}
}
}
post {
always {
junit testResults:'**/TEST-*.xml', allowEmptyResults: true
}
}
}

View File

@ -39,6 +39,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Basic {@link BlueRun} implementation.
@ -390,7 +391,7 @@ public abstract class AbstractRunImpl<T extends Run> extends BlueRun {
}
static Collection<BlueCause> getCauses(Collection<hudson.model.Cause> causes) {
return Collections2.transform(causes, input -> new BlueCauseImpl(input));
return causes.stream().map( input -> new BlueCauseImpl(input)).collect(Collectors.toList());
}
}
}

View File

@ -17,6 +17,7 @@ import jenkins.model.Jenkins;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.NoSuchElementException;
public class QueueUtil {
@ -39,12 +40,12 @@ public class QueueUtil {
@Nullable
@SuppressWarnings("unchecked")
public static <T extends Run> T getRun(@Nonnull Job job, final long queueId) {
return Iterables.find((Iterable<T>) job.getBuilds(), new Predicate<Run>() {
@Override
public boolean apply(@Nullable Run input) {
return input != null && input.getQueueId() == queueId;
}
}, null);
try {
return Iterables.find((Iterable<T>) job.getBuilds(), input -> input != null && input.getQueueId() == queueId);
} catch ( NoSuchElementException e ) {
// ignore as maybe we do not have builds
}
return null;
}
/**
@ -63,11 +64,12 @@ public class QueueUtil {
List<BlueQueueItem> items2 = Lists.newArrayList();
for (int i = 0; i < items.size(); i++) {
Link self = pipeline.getLink().rel("queue").rel(Long.toString(items.get(i).getId()));
items2.add(0, new QueueItemImpl(
QueueItemImpl queueItem = new QueueItemImpl(
organization,
items.get(i),
pipeline,
(items.size() == 1 ? job.getNextBuildNumber() : job.getNextBuildNumber() + i), self, pipeline.getLink()));
(items.size() == 1 ? job.getNextBuildNumber() : job.getNextBuildNumber() + i), self, pipeline.getLink());
items2.add(0, queueItem);
}
return items2;

View File

@ -2,8 +2,12 @@ package io.jenkins.blueocean.rest.model;
import io.jenkins.blueocean.rest.Navigable;
import io.jenkins.blueocean.rest.annotation.Capability;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.WebMethod;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.verb.POST;
import java.util.List;
@ -69,6 +73,21 @@ public abstract class BluePipelineNode extends BluePipelineStep {
@Navigable
public abstract BluePipelineStepContainer getSteps();
/**
* @return <code>true</code> if the pipeline can be restarted from this node
*/
@Exported
public abstract boolean isRestartable();
/**
*
* @param request To restart the content must be simple json body with a field <code>restart</code> will value <code>true</code>
* @return the response content will be {@link BlueRun}
*/
@POST
@WebMethod(name = "restart")
public abstract HttpResponse restart( StaplerRequest request);
/**
* Represents edge of pipeline flow graph
*/

12
pom.xml
View File

@ -321,7 +321,7 @@
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-definition</artifactId>
<version>1.2.9</version>
<version>1.3</version>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci.plugins</groupId>
@ -329,6 +329,16 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-stage-tags-metadata</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-api</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>