Skip to content
Permalink
Browse files

JENKINS-25298 Rebuild

  • Loading branch information...
patbos committed Feb 17, 2015
1 parent 2301a15 commit bba6b4ac2e74048042b2648a58bc45b29c78c87b
Showing with 387 additions and 43 deletions.
  1. +2 −2 pom.xml
  2. +56 −4 src/main/java/se/diabol/jenkins/pipeline/DeliveryPipelineView.java
  3. +15 −0 src/main/java/se/diabol/jenkins/pipeline/PipelineApi.java
  4. +19 −2 src/main/java/se/diabol/jenkins/pipeline/domain/Pipeline.java
  5. +10 −2 src/main/java/se/diabol/jenkins/pipeline/domain/Stage.java
  6. +22 −3 src/main/java/se/diabol/jenkins/pipeline/domain/Task.java
  7. +13 −2 src/main/java/se/diabol/jenkins/pipeline/domain/Trigger.java
  8. +4 −0 src/main/java/se/diabol/jenkins/pipeline/domain/status/SimpleStatus.java
  9. +11 −2 src/main/java/se/diabol/jenkins/pipeline/util/ProjectUtil.java
  10. +4 −0 src/main/resources/se/diabol/jenkins/pipeline/DeliveryPipelineView/configure-entries.jelly
  11. +3 −0 src/main/resources/se/diabol/jenkins/pipeline/DeliveryPipelineView/help-allowRebuild.html
  12. +34 −0 src/main/webapp/pipe.js
  13. +16 −1 src/main/webapp/pipeline-common.css
  14. BIN src/main/webapp/play.png
  15. BIN src/main/webapp/refresh.png
  16. BIN src/main/webapp/report.png
  17. +72 −1 src/test/java/se/diabol/jenkins/pipeline/DeliveryPipelineViewTest.java
  18. +20 −0 src/test/java/se/diabol/jenkins/pipeline/PipelineApiTest.java
  19. +17 −1 src/test/java/se/diabol/jenkins/pipeline/domain/PipelineTest.java
  20. +1 −1 src/test/java/se/diabol/jenkins/pipeline/domain/StageTest.java
  21. +28 −8 src/test/java/se/diabol/jenkins/pipeline/domain/TaskTest.java
  22. +38 −12 src/test/java/se/diabol/jenkins/pipeline/domain/TriggerTest.java
  23. +2 −2 src/test/java/se/diabol/jenkins/pipeline/sort/LatestActivityComparatorTest.java
@@ -4,7 +4,7 @@

<groupId>se.diabol.jenkins.pipeline</groupId>
<artifactId>delivery-pipeline-plugin</artifactId>
<version>0.8.12-SNAPSHOT</version>
<version>0.9.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<name>Delivery Pipeline Plugin</name>
<url>https://wiki.jenkins-ci.org/display/JENKINS/Delivery+Pipeline+Plugin</url>
@@ -24,7 +24,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.509.4</version>
<version>1.565</version>
</parent>

<properties>
@@ -19,29 +19,53 @@

import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.model.*;
import hudson.model.AbstractBuild;
import hudson.model.AbstractDescribableImpl;
import hudson.model.AbstractProject;
import hudson.model.Api;
import hudson.model.Cause;
import hudson.model.CauseAction;
import hudson.model.Descriptor;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.ParametersAction;
import hudson.model.TopLevelItem;
import hudson.model.View;
import hudson.model.ViewDescriptor;
import hudson.model.ViewGroup;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException;
import org.kohsuke.stapler.*;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.bind.JavaScriptMethod;
import org.kohsuke.stapler.export.Exported;
import se.diabol.jenkins.pipeline.domain.Component;
import se.diabol.jenkins.pipeline.domain.Pipeline;
import se.diabol.jenkins.pipeline.trigger.ManualTrigger;
import se.diabol.jenkins.pipeline.domain.PipelineException;
import se.diabol.jenkins.pipeline.sort.ComponentComparator;
import se.diabol.jenkins.pipeline.sort.ComponentComparatorDescriptor;
import se.diabol.jenkins.pipeline.trigger.ManualTrigger;
import se.diabol.jenkins.pipeline.trigger.ManualTriggerFactory;
import se.diabol.jenkins.pipeline.trigger.TriggerException;
import se.diabol.jenkins.pipeline.util.PipelineUtils;
import se.diabol.jenkins.pipeline.util.ProjectUtil;

import javax.servlet.ServletException;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
@@ -71,6 +95,7 @@
private int updateInterval = DEFAULT_INTERVAL;
private boolean showChanges = false;
private boolean allowManualTriggers = false;
private boolean allowRebuild = false;

private List<RegExpSpec> regexpFirstJobs;

@@ -245,6 +270,15 @@ public String getError() {
return error;
}

@Exported
public boolean isAllowRebuild() {
return allowRebuild;
}

public void setAllowRebuild(boolean allowRebuild) {
this.allowRebuild = allowRebuild;
}

@JavaScriptMethod
public void triggerManual(String projectName, String upstreamName, String buildId) throws TriggerException, AuthenticationException {
try {
@@ -269,6 +303,24 @@ public void triggerManual(String projectName, String upstreamName, String buildI
}
}

public void triggerRebuild(String projectName, String buildId) {
AbstractProject project = ProjectUtil.getProject(projectName, Jenkins.getInstance());
if (!project.hasPermission(Item.BUILD)) {
throw new BadCredentialsException("Not auth to build");
}
AbstractBuild build = project.getBuildByNumber(Integer.parseInt(buildId));

List<Cause> prevCauses = build.getCauses();
CauseAction causeAction = new CauseAction();
for (Cause cause : prevCauses) {
if (!(cause instanceof Cause.UserIdCause)) {
causeAction.getCauses().add(cause);
}
}
causeAction.getCauses().add(new Cause.UserIdCause());
project.scheduleBuild2(project.getQuietPeriod(),null, causeAction, build.getAction(ParametersAction.class));
}

protected static String triggerExceptionMessage(final String projectName, final String upstreamName, final String buildId) {
String message = "Could not trigger manual build " + projectName + " for upstream " + upstreamName + " id: " + buildId;
if (projectName.contains("/")) {
@@ -54,7 +54,22 @@ public void doManualStep(StaplerRequest req, StaplerResponse rsp,
} else {
rsp.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
}
}

@SuppressWarnings("UnusedDeclaration")
public void doRebuildStep(StaplerRequest req, StaplerResponse rsp,
@QueryParameter String project,
@QueryParameter String buildId) throws IOException, ServletException {
if (project != null && buildId != null) {
try {
view.triggerRebuild(project, buildId);
rsp.setStatus(HttpServletResponse.SC_OK);
} catch (AuthenticationException e) {
rsp.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
} else {
rsp.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
}
}


@@ -138,9 +138,26 @@ public Pipeline createPipelineAggregated(ItemGroup context) {
*/
public List<Pipeline> createPipelineLatest(int noOfPipelines, ItemGroup context) {
List<Pipeline> result = new ArrayList<Pipeline>();
int no = noOfPipelines;
if (firstProject.isInQueue()) {
String pipeLineTimestamp = PipelineUtils.formatTimestamp(firstProject.getQueueItem().getInQueueSince());
List<Stage> pipelineStages = new ArrayList<Stage>();
for (Stage stage : getStages()) {
pipelineStages.add(stage.createLatestStage(context, null));
}
Pipeline pipelineLatest = new Pipeline(getName(), firstProject, "#" + firstProject.getNextBuildNumber(), pipeLineTimestamp,
Trigger.getTriggeredBy(firstProject, null), null,
// Trigger.getTriggeredBy(firstBuild),
// UserInfo.getContributors(firstBuild),
pipelineStages, false);
//pipelineLatest.setChanges(pipelineChanges);
result.add(pipelineLatest);
no--;
}


Iterator it = firstProject.getBuilds().iterator();
for (int i = 0; i < noOfPipelines && it.hasNext(); i++) {
for (int i = 0; i < no && it.hasNext(); i++) {
AbstractBuild firstBuild = (AbstractBuild) it.next();
List<Change> pipelineChanges = Change.getChanges(firstBuild);
String pipeLineTimestamp = PipelineUtils.formatTimestamp(firstBuild.getTimeInMillis());
@@ -149,7 +166,7 @@ public Pipeline createPipelineAggregated(ItemGroup context) {
pipelineStages.add(stage.createLatestStage(context, firstBuild));
}
Pipeline pipelineLatest = new Pipeline(getName(), firstProject, firstBuild.getDisplayName(), pipeLineTimestamp,
Trigger.getTriggeredBy(firstBuild), UserInfo.getContributors(firstBuild), pipelineStages, false);
Trigger.getTriggeredBy(firstProject, firstBuild), UserInfo.getContributors(firstBuild), pipelineStages, false);
pipelineLatest.setChanges(pipelineChanges);
result.add(pipelineLatest);
}
@@ -33,7 +33,15 @@
import se.diabol.jenkins.pipeline.util.PipelineUtils;
import se.diabol.jenkins.pipeline.util.ProjectUtil;

import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -145,7 +153,7 @@ public static Stage getPrototypeStage(String name, List<Task> tasks) {
public static List<Stage> extractStages(AbstractProject firstProject) throws PipelineException {
Map<String, Stage> stages = newLinkedHashMap();
for (AbstractProject project : ProjectUtil.getAllDownstreamProjects(firstProject).values()) {
Task task = Task.getPrototypeTask(project);
Task task = Task.getPrototypeTask(project, project.getFullName().equals(firstProject.getFullName()));
PipelineProperty property = (PipelineProperty) project.getProperty(PipelineProperty.class);
if (property == null && project.getParent() instanceof AbstractProject) {
property = (PipelineProperty) ((AbstractProject) project.getParent()).getProperty(PipelineProperty.class);
@@ -46,8 +46,9 @@
private final ManualStep manual;
private final String buildId;
private final List<String> downstreamTasks;
private final boolean initial;

public Task(String id, String name, Status status, String link, ManualStep manual, List<String> downstreamTasks) {
public Task(String id, String name, Status status, String link, ManualStep manual, List<String> downstreamTasks, boolean initial) {
super(name);
this.id = id;
this.link = link;
@@ -56,6 +57,7 @@ public Task(String id, String name, Status status, String link, ManualStep manua
this.manual = manual;
this.buildId = null;
this.downstreamTasks = downstreamTasks;
this.initial = initial;
}


@@ -69,6 +71,7 @@ public Task(Task task, String buildId, Status status, String link, ManualStep ma
this.link = link;
this.manual = manual;
this.testResult = testResult;
this.initial = task.isInitial();
}

@Exported
@@ -112,7 +115,23 @@ public Status getStatus() {
return downstreamTasks;
}

public static Task getPrototypeTask(AbstractProject project) {
@Exported
public boolean isRebuildable() {
if (initial) {
return false;
}
if (status.isRunning() || status.isIdle() || status.isNotBuilt() || status.isQueued() || status.isDisabled()) {
return false;
} else {
return true;
}
}

public boolean isInitial() {
return initial;
}

public static Task getPrototypeTask(AbstractProject project, boolean initial) {
String taskName;
PipelineProperty property = (PipelineProperty) project.getProperty(PipelineProperty.class);
if (property == null && project.getParent() instanceof AbstractProject) {
@@ -132,7 +151,7 @@ public static Task getPrototypeTask(AbstractProject project) {
downStreamTasks.add(downstreamProject.getRelativeNameFrom(Jenkins.getInstance()));
}
return new Task(project.getRelativeNameFrom(Jenkins.getInstance()), taskName, status,
project.getUrl(), ManualStep.resolveManualStep(project), downStreamTasks);
project.getUrl(), ManualStep.resolveManualStep(project), downStreamTasks, initial);
}

public Task getLatestTask(ItemGroup context, AbstractBuild firstBuild) {
@@ -61,9 +61,20 @@ public String getDescription() {
return description;
}

public static List<Trigger> getTriggeredBy(AbstractBuild<?, ?> build) {
public static List<Trigger> getTriggeredBy(AbstractProject project, AbstractBuild<?, ?> build) {
Set<Trigger> result = new HashSet<Trigger>();
List<Cause> causes = build.getCauses();
List<Cause> causes;
if (build == null && project.isInQueue()) {
causes = project.getQueueItem().getCauses();
} else {
if (build != null) {
causes = build.getCauses();
} else {
return new ArrayList<Trigger>();
}

}

for (Cause cause : causes) {
if (cause instanceof Cause.UserIdCause) {
result.add(new Trigger(Trigger.TYPE_MANUAL, "user " + getDisplayName(((Cause.UserIdCause) cause).getUserName())));
@@ -133,7 +133,10 @@ public static Status resolveStatus(AbstractProject project, AbstractBuild build,

return StatusFactory.running(progress, build.getTimeInMillis(), currentTimeMillis() - build.getTimestamp().getTimeInMillis());
}
return getStatusFromResult(build);
}

private static Status getStatusFromResult(AbstractBuild build) {
Result result = build.getResult();
if (Result.ABORTED.equals(result)) {
return StatusFactory.cancelled(build.getTimeInMillis(), build.getDuration());
@@ -151,6 +154,7 @@ public static Status resolveStatus(AbstractProject project, AbstractBuild build,
return StatusFactory.notBuilt(build.getTimeInMillis(), build.getDuration());
}
throw new IllegalStateException("Result " + result + " not recognized.");

}


@@ -19,12 +19,21 @@

import hudson.EnvVars;
import hudson.Util;
import hudson.model.*;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Cause;
import hudson.model.ItemGroup;
import hudson.model.Items;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import se.diabol.jenkins.pipeline.RelationshipResolver;

import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -28,6 +28,10 @@
<f:checkbox/>
</f:entry>

<f:entry title="Enable rebuild" field="allowRebuild">
<f:checkbox/>
</f:entry>


<f:entry title="Show avatars" field="showAvatars">
<f:checkbox/>
@@ -0,0 +1,3 @@
<div>
Rebuild a task.
</div>
Oops, something went wrong.

0 comments on commit bba6b4a

Please sign in to comment.
You can’t perform that action at this time.