Skip to content

Commit

Permalink
[JENKINS-12437] Allow propagating claims to following failed builds
Browse files Browse the repository at this point in the history
  • Loading branch information
Greybird committed Jan 6, 2018
1 parent ffd19c5 commit 88160fc
Show file tree
Hide file tree
Showing 13 changed files with 280 additions and 38 deletions.
45 changes: 37 additions & 8 deletions src/main/java/hudson/plugins/claim/AbstractClaimBuildAction.java
Expand Up @@ -11,6 +11,7 @@
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -119,10 +120,11 @@ public final void doClaim(StaplerRequest req, StaplerResponse resp)
}

boolean sticky = req.getSubmittedForm().getBoolean("sticky");
boolean propagated = req.getSubmittedForm().getBoolean("propagateToFollowingBuilds");
if (StringUtils.isEmpty(reasonProvided)) {
reasonProvided = null;
}
claim(claimedUser, reasonProvided, currentUser, sticky, true);
claim(claimedUser, reasonProvided, currentUser, sticky, propagated, true);
this.getOwner().save();
evalGroovyScript();
resp.forwardToPreviousPage(req);
Expand All @@ -134,11 +136,12 @@ public final void doClaim(StaplerRequest req, StaplerResponse resp)
* @param providedReason reason for the claim
* @param assignedByUser name of the assigned user
* @param isSticky true if the claim has to be kept until resolution
* @deprecated use {@link #claim(String, String, String, boolean, boolean)}
* @deprecated use {@link #claim(String, String, String, boolean, boolean, boolean)}
*/
@Deprecated
public final void claim(String claimedByUser, String providedReason, String assignedByUser, boolean isSticky) {
claim(claimedByUser, providedReason, assignedByUser, isSticky, false);
claim(claimedByUser, providedReason, assignedByUser, isSticky,
ClaimConfig.get().isPropagateToFollowingBuildsByDefault(), false);
}

/**
Expand All @@ -147,11 +150,12 @@ public final void claim(String claimedByUser, String providedReason, String assi
* @param providedReason reason for the claim
* @param assignedByUser name of the assigner user
* @param isSticky true if the claim has to be kept until resolution
* @param isPropagated true if the claim has to be propagated to following builds
* @param notify true if notifications have to be sent
*/
public final void claim(String claimedByUser, String providedReason, String assignedByUser, boolean isSticky,
boolean notify) {
applyClaim(claimedByUser, providedReason, assignedByUser, isSticky);
boolean isPropagated, boolean notify) {
applyClaim(claimedByUser, providedReason, assignedByUser, isSticky, isPropagated);
if (notify) {
try {
ClaimEmailer.sendEmailIfConfigured(
Expand All @@ -174,16 +178,32 @@ public final void claim(String claimedByUser, String providedReason, String assi
* @param providedReason reason for the claim
* @param assignedByUser name of the assigner user
* @param isSticky true if the claim has to be kept until resolution
* @param isPropagated true if the claim has to be propagated to following builds
*/
protected void applyClaim(String claimedByUser, String providedReason, String assignedByUser, boolean isSticky) {
protected void applyClaim(String claimedByUser, String providedReason, String assignedByUser, boolean isSticky,
boolean isPropagated) {
this.claimed = true;
this.claimedBy = claimedByUser;
this.reason = providedReason;
this.transientClaim = !isSticky;
this.claimDate = new Date();
this.assignedBy = assignedByUser;
if (isPropagated) {
getNextAction().ifPresent(action -> {
if (!action.isClaimed()) {
action.applyClaim(claimedByUser, providedReason, assignedByUser, isSticky, true);
try {
action.getOwner().save();
} catch (IOException e) {
// ignore
}
}
});
}
}

protected abstract Optional<AbstractClaimBuildAction> getNextAction();

// jelly
public final void doUnclaim(StaplerRequest req, StaplerResponse resp)
throws ServletException, IOException {
Expand All @@ -208,9 +228,11 @@ public final void unclaim() {

/**
* Unclaims a {@link Saveable}, and optionally notifies of the unclaim.
* @param notify true if notifications have to be sent
* @deprecated use {@link #unclaim(boolean)}
*/
public final void unclaim(boolean notify) {
//TODO actually notify
applyUnclaim();
}

Expand Down Expand Up @@ -275,8 +297,8 @@ public final boolean isClaimed() {
* Claim a new {@link Saveable} with the same settings as this one.
* @param other the source data
*/
public void copyTo(AbstractClaimBuildAction<T> other) {
other.applyClaim(getClaimedBy(), getReason(), getAssignedBy(), isSticky());
protected void copyTo(AbstractClaimBuildAction<T> other) {
other.applyClaim(getClaimedBy(), getReason(), getAssignedBy(), isSticky(), false);
}

public final boolean isClaimedByMe() {
Expand Down Expand Up @@ -356,6 +378,13 @@ public final void setSticky(boolean sticky) {
this.transientClaim = !sticky;
}

@Restricted(DoNotUse.class)
@SuppressWarnings("unused")
// groovy
public final boolean isPropagateToFollowingBuildsByDefault() {
return ClaimConfig.get().isPropagateToFollowingBuildsByDefault();
}

// used by groovy scripts ?
public final String getError() {
if (bfaClaimer == null) {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/hudson/plugins/claim/ClaimBuildAction.java
Expand Up @@ -3,6 +3,8 @@
import hudson.model.Run;
import jenkins.model.RunAction2;

import java.util.Optional;

public final class ClaimBuildAction extends AbstractClaimBuildAction<Run> implements RunAction2 {

private static final long serialVersionUID = 1L;
Expand Down Expand Up @@ -37,4 +39,14 @@ public void onAttached(Run<?, ?> run) {
public void onLoad(Run<?, ?> run) {
owner = run;
}

@Override
protected Optional<AbstractClaimBuildAction> getNextAction() {
Run nextRun = owner.getNextBuild();
if (nextRun != null) {
ClaimBuildAction action = nextRun.getAction(ClaimBuildAction.class);
return Optional.ofNullable(action);
}
return Optional.empty();
}
}
24 changes: 24 additions & 0 deletions src/main/java/hudson/plugins/claim/ClaimConfig.java
Expand Up @@ -37,6 +37,11 @@ public ClaimConfig() {
*/
private boolean stickyByDefault = true;

/**
* Default global value for the propagation to following builds of the claims.
*/
private boolean propagateToFollowingBuildsByDefault = false;

/**
* Sort users by full name.
*/
Expand Down Expand Up @@ -71,6 +76,7 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc
// set that to properties and call save().
sendEmails = formData.getBoolean("sendEmails");
stickyByDefault = formData.getBoolean("stickyByDefault");
propagateToFollowingBuildsByDefault = formData.getBoolean("propagateToFollowingBuildsByDefault");
sortUsersByFullName = formData.getBoolean("sortUsersByFullName");
blockAutoRefreshWhileClaiming = formData.getBoolean("blockAutoRefreshWhileClaiming");
setGroovyTrigger(req.bindJSON(SecureGroovyScript.class, formData.getJSONObject("groovyTrigger")));
Expand Down Expand Up @@ -113,6 +119,24 @@ public void setStickyByDefault(boolean stickyByDefault) {
this.stickyByDefault = stickyByDefault;
}

/**
* Returns true if the claims should be propagated to following builds by default, false otherwise.
*
* @return true to make claims propagated to following builds by default, else false.
*/
public boolean isPropagateToFollowingBuildsByDefault() {
return propagateToFollowingBuildsByDefault;
}

/**
* Sets the default following builds propagation behaviour for claims.
*
* @param propagateToFollowingBuildsByDefault the default following build propagation value.
*/
public void setPropagateToFollowingBuildsByDefault(boolean propagateToFollowingBuildsByDefault) {
this.propagateToFollowingBuildsByDefault = propagateToFollowingBuildsByDefault;
}


/**
* Returns true if the users should be sorted by full name instead of ids.
Expand Down
25 changes: 23 additions & 2 deletions src/main/java/hudson/plugins/claim/ClaimTestAction.java
Expand Up @@ -2,6 +2,10 @@

import hudson.model.Run;
import hudson.plugins.claim.ClaimTestDataPublisher.Data;
import hudson.tasks.junit.TestResultAction;
import hudson.tasks.test.TestResult;

import java.util.Optional;

public final class ClaimTestAction extends AbstractClaimBuildAction<Run> {

Expand All @@ -18,9 +22,26 @@ public String getDisplayName() {
}

@Override
protected void applyClaim(String claimedByUser, String providedReason, String assignedByUser, boolean isSticky) {
super.applyClaim(claimedByUser, providedReason, assignedByUser, isSticky);
protected void applyClaim(String claimedByUser, String providedReason, String assignedByUser, boolean isSticky,
boolean isPropagated) {
data.addClaim(testObjectId, this);
super.applyClaim(claimedByUser, providedReason, assignedByUser, isSticky, isPropagated);
}

@Override
protected Optional<AbstractClaimBuildAction> getNextAction() {
Run nextRun = getOwner().getNextBuild();
if (nextRun != null) {
TestResultAction action = nextRun.getAction(TestResultAction.class);
if (action != null) {
TestResult testResult = action.getResult().findCorrespondingResult(testObjectId);
if (testResult != null) {
ClaimTestAction claimAction = testResult.getTestAction(ClaimTestAction.class);
return Optional.ofNullable(claimAction);
}
}
}
return Optional.empty();
}

@Override
Expand Down
Expand Up @@ -104,6 +104,9 @@
<f:entry title="${%Sticky}" help="/plugin/claim/help-sticky.html">
<f:checkbox name="sticky" checked="${it.sticky}"/>
</f:entry>
<f:entry title="${%PropagateToFollowingBuilds}" help="/plugin/claim/help-propagateToFollowingBuilds.html">
<f:checkbox name="propagateToFollowingBuilds" checked="${it.propagateToFollowingBuildsByDefault}"/>
</f:entry>
<f:block>
<div align="right">
<f:submit value="${%Claim}"/>
Expand Down
@@ -1,3 +1,4 @@
Action.Claim=Claim it
Action.Release=Drop the claim
Action.Reassign=Reassign the claim
PropagateToFollowingBuilds=Propagate to following builds
Expand Up @@ -8,6 +8,11 @@
<f:entry title="${%StickyByDefault}" field="stickyByDefault" help="/plugin/claim/help-stickyByDefault.html">
<f:checkbox/>
</f:entry>
<f:entry title="${%PropagateToFollowingBuildsByDefault}" field="propagateToFollowingBuildsByDefault"
help="/plugin/claim/help-propagateToFollowingBuildsByDefault.html">
<f:checkbox/>
</f:entry>

<f:entry title="${%SortUsersByFullName}" field="sortUsersByFullName"
help="/plugin/claim/help-sortUsersByFullName.html">
<f:checkbox/>
Expand Down
@@ -1,5 +1,6 @@
SendEmails=Send emails when assigning/claiming builds
StickyByDefault=Make claim sticky by default when claiming
PropagateToFollowingBuildsByDefault=Make claim propagate to following failed builds by default
SortUsersByFullName=Sort the users by their name rather than they ids when listing them
GroovyScript=The Groovy script to run when claims are changed
BlockAutoRefreshWhileClaiming=Block web page refresh while claiming
Expand Down
3 changes: 3 additions & 0 deletions src/main/webapp/help-propagateToFollowingBuilds.html
@@ -0,0 +1,3 @@
<div>
If checked, the claim will also be applied to following runs until another claim is found or issue is solved.
</div>
4 changes: 4 additions & 0 deletions src/main/webapp/help-propagateToFollowingBuildsByDefault.html
@@ -0,0 +1,4 @@
<div>
Checking this option will make claims be applied on the build or test on following builds until a claimed one or a
successful one is found.
</div>
1 change: 1 addition & 0 deletions src/test/java/hudson/plugins/claim/ClaimGroovyTest.java
Expand Up @@ -136,6 +136,7 @@ private void doConfigureScriptWithUser(String userName)
jsonObject.accumulate("reason", "none");
jsonObject.accumulate("errors", "");
jsonObject.accumulate("sticky", true);
jsonObject.accumulate("propagateToFollowingBuilds", false);
when(req.getSubmittedForm()).thenReturn(jsonObject);

StaplerResponse res = mock(StaplerResponse.class);
Expand Down

0 comments on commit 88160fc

Please sign in to comment.