Skip to content

Commit

Permalink
Merge pull request #80 from zittix/zittix/rebuilddispatcher
Browse files Browse the repository at this point in the history
Add RebuildDispatcher extension point to allow other plugins to propagate action
  • Loading branch information
GLundh authored Nov 10, 2021
2 parents 5073626 + 105a664 commit e36c878
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/main/java/com/sonyericsson/rebuild/RebuildAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
package com.sonyericsson.rebuild;

import hudson.Extension;
import hudson.ExtensionList;
import hudson.model.Action;

import javax.servlet.ServletException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import hudson.matrix.MatrixRun;
import hudson.model.BooleanParameterValue;
Expand Down Expand Up @@ -336,6 +339,26 @@ private List<Cause> constructRebuildCauses(Run<?, ?> fromBuild) {
return newBuildCauses;
}

/**
* Loops over all the RebuildActionDispatchers and adds any actions to the rebuild that they want included.
* Always copies the {@link hudson.model.ParametersAction} if it is present.
*
* @param fromBuild the build to copy the actions from
* @param actions the list to append additional copied actions
*/
private void copyRebuildDispatcherActions(Run<?, ?> fromBuild, List<Action> actions) {
Set<Action> propagatingActions = new HashSet<>();

// Get all RebuildActionsDispatchers that implement our extension point
ExtensionList<RebuildActionDispatcher> rebuildActionDispatchers = RebuildActionDispatcher.all();

for (RebuildActionDispatcher dispatcher : rebuildActionDispatchers) {
propagatingActions.addAll(dispatcher.getPropagatingActions(fromBuild));
}

actions.addAll(propagatingActions);
}

/**
* Method for checking whether current build is sub job(MatrixRun) of Matrix
* build.
Expand All @@ -354,7 +377,7 @@ public boolean isMatrixRun() {
}

/**
* Method for checking,whether the rebuild functionality would be available
* Method for checking whether the rebuild functionality would be available
* for build.
*
* @return boolean
Expand Down Expand Up @@ -449,14 +472,15 @@ private ParameterValue cloneParameter(ParameterValue oldValue, String newValue)
/**
* Method for constructing Rebuild actions.
*
* @param up AbsstractBuild
* @param up AbstractBuild
* @param paramAction ParametersAction.
* @return actions List<Action>
*/
private List<Action> constructRebuildActions(Run up, ParametersAction paramAction) {
List<Cause> causes = constructRebuildCauses(up);
List<Action> actions = new ArrayList<>();
actions.add(new CauseAction(causes));
copyRebuildDispatcherActions(up, actions);
if (paramAction != null) {
actions.add(paramAction);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.sonyericsson.rebuild;

import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.model.Action;
import hudson.model.Run;
import jenkins.model.Jenkins;

import java.util.Collection;

/**
* Extension point to propagate additional actions to the rebuild.
*/
public abstract class RebuildActionDispatcher implements ExtensionPoint {

/**
* @return the actions to include in the rebuild.
*/
public abstract Collection<Action> getPropagatingActions(Run r);

/**
* All registered {@link RebuildActionDispatcher}s.
* TODO: use ExtensionList.lookup() once the Jenkins dependency is upgraded >= 1.572
*/
public static ExtensionList<RebuildActionDispatcher> all() {
Jenkins j = Jenkins.getInstance();
return j == null ? ExtensionList.create((Jenkins) null, RebuildActionDispatcher.class) : j.getExtensionList(RebuildActionDispatcher.class);
}
}
106 changes: 106 additions & 0 deletions src/test/java/com/sonyericsson/rebuild/RebuildValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import hudson.model.ParametersAction;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Project;
import hudson.model.Run;
import hudson.model.StringParameterDefinition;
import hudson.model.StringParameterValue;

Expand All @@ -54,6 +55,9 @@
import org.kohsuke.stapler.DataBoundConstructor;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;

/**
Expand Down Expand Up @@ -477,6 +481,67 @@ public void testRebuildSupportedUnknownParameterValue() throws Exception {
page.asText().contains("This is a mark for test"));
}

public void testRebuildDispatcherExtensionActionIsCopied() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
project.addProperty(new ParametersDefinitionProperty(
new StringParameterDefinition("name", "defaultValue")));

// Build (#1)
project.scheduleBuild2(0, new Cause.RemoteCause("host", "note"),
new ParametersAction(new StringParameterValue("name", "test")),
new RebuildDispatcherTestAction(true))
.get();
HtmlPage rebuildConfigPage = j.createWebClient().getPage(project,
"1/rebuild");
// Rebuild (#2)
j.submit(rebuildConfigPage.getFormByName("config"));

j.createWebClient().getPage(project).getAnchorByText("Rebuild Last")
.click();

while (project.isBuilding()) {
Thread.sleep(DELAY);
}
boolean hasRebuildDispatcherTestAction = false;
for (Action action : project.getLastCompletedBuild().getAllActions()) {
if (action instanceof RebuildDispatcherTestAction) {
hasRebuildDispatcherTestAction = true;
}
}
assertTrue("Build should have rebuildDispatcherTestAction", hasRebuildDispatcherTestAction);
}

public void testRebuildDispatcherExtensionActionIsNotCopied() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
project.addProperty(new ParametersDefinitionProperty(
new StringParameterDefinition("name", "defaultValue")));

// Build (#1)
project.scheduleBuild2(0, new Cause.RemoteCause("host", "note"),
new ParametersAction(new StringParameterValue("name", "test")),
new RebuildDispatcherTestAction(false))
.get();
HtmlPage rebuildConfigPage = j.createWebClient().getPage(project,
"1/rebuild");
// Rebuild (#2)
j.submit(rebuildConfigPage.getFormByName("config"));

j.createWebClient().getPage(project).getAnchorByText("Rebuild Last")
.click();

while (project.isBuilding()) {
Thread.sleep(DELAY);
}

boolean hasRebuildDispatcherTestAction = false;
for (Action action : project.getLastCompletedBuild().getAllActions()) {
if (action instanceof RebuildDispatcherTestAction) {
hasRebuildDispatcherTestAction = true;
}
}
assertFalse("Build should not have rebuildDispatcherTestAction", hasRebuildDispatcherTestAction);
}

/**
* A parameter value rebuild plugin does not know.
*/
Expand Down Expand Up @@ -581,4 +646,45 @@ public RebuildParameterPage getRebuildPage(ParameterValue value) {
return new RebuildParameterPage(SupportedUnknownParameterValue.class, "rebuild.groovy");
}
}

public static class RebuildDispatcherTestAction implements Action {
public final boolean shouldBeCopied;

public RebuildDispatcherTestAction(boolean shouldBeCopied) {
this.shouldBeCopied = shouldBeCopied;
}

@Override
public String getIconFileName() {
return null;
}
@Override
public String getDisplayName() {
return null;
}
@Override
public String getUrlName() {
return null;
}
}

@Extension
public static class RebuildActionDispatcherTestImpl extends RebuildActionDispatcher {
@Override
public Set<Action> getPropagatingActions(Run r) {
Set<Action> dispatcherActions = new HashSet<>();

for (Action action : r.getAllActions()) {
if (RebuildDispatcherTestAction.class.isInstance(action)) {
RebuildDispatcherTestAction testAction = (RebuildDispatcherTestAction) action;

if (testAction.shouldBeCopied) {
dispatcherActions.add(action);
}
}
}

return dispatcherActions;
}
}
}

0 comments on commit e36c878

Please sign in to comment.