Skip to content

Commit 66655e0

Browse files
committed
feature/324 | skip non PR notifications
1 parent 1f980b7 commit 66655e0

File tree

9 files changed

+113
-4
lines changed

9 files changed

+113
-4
lines changed

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotifications.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.cloudbees.jenkins.plugins.bitbucket.BranchDiscoveryTrait.ExcludeOriginPRBranchesSCMHeadFilter;
2727
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi;
2828
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus;
29+
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatuses;
2930
import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient;
3031
import edu.umd.cs.findbugs.annotations.NonNull;
3132
import hudson.Extension;
@@ -41,13 +42,15 @@
4142
import java.io.IOException;
4243
import java.net.MalformedURLException;
4344
import java.net.URL;
45+
import java.util.regex.Pattern;
4446
import javax.annotation.CheckForNull;
4547
import jenkins.model.JenkinsLocationConfiguration;
4648
import jenkins.plugins.git.AbstractGitSCMSource;
4749
import jenkins.scm.api.SCMHeadObserver;
4850
import jenkins.scm.api.SCMRevision;
4951
import jenkins.scm.api.SCMRevisionAction;
5052
import jenkins.scm.api.SCMSource;
53+
import org.apache.commons.codec.digest.DigestUtils;
5154
import org.apache.commons.lang.StringUtils;
5255
import org.jenkinsci.plugins.displayurlapi.DisplayURLProvider;
5356

@@ -62,6 +65,7 @@ public class BitbucketBuildStatusNotifications {
6265
private static final String FAILED_STATE = "FAILED";
6366
private static final String STOPPED_STATE = "STOPPED";
6467
private static final String INPROGRESS_STATE = "INPROGRESS";
68+
private static final Pattern PR_BUILD_PATTERN = Pattern.compile("^.*/job/PR-(\\d+)/(\\d+)/.*$");
6569

6670
private static String getRootURL(@NonNull Run<?, ?> build) {
6771
JenkinsLocationConfiguration cfg = JenkinsLocationConfiguration.get();
@@ -157,7 +161,7 @@ private static void createStatus(@NonNull Run<?, ?> build, @NonNull TaskListener
157161
statusDescription = StringUtils.defaultIfBlank(buildDescription, "The build is in progress...");
158162
state = INPROGRESS_STATE;
159163
}
160-
status = new BitbucketBuildStatus(hash, statusDescription, state, url, key, name);
164+
status = new BitbucketBuildStatus(hash, statusDescription, state, url, DigestUtils.md5Hex(key), name);
161165
new BitbucketChangesetCommentNotifier(bitbucket).buildStatus(status);
162166
if (result != null) {
163167
listener.getLogger().println("[Bitbucket] Build result notified");
@@ -184,6 +188,7 @@ private static void sendNotifications(BitbucketSCMSource source, Run<?, ?> build
184188
if (hash == null) {
185189
return;
186190
}
191+
187192
boolean shareBuildKeyBetweenBranchAndPR = sourceContext
188193
.filters().stream()
189194
.anyMatch(filter -> filter instanceof ExcludeOriginPRBranchesSCMHeadFilter);
@@ -199,6 +204,15 @@ private static void sendNotifications(BitbucketSCMSource source, Run<?, ?> build
199204
listener.getLogger().println("[Bitbucket] Notifying commit build result");
200205
key = getBuildKey(build, r.getHead().getName(), shareBuildKeyBetweenBranchAndPR);
201206
bitbucket = source.buildBitbucketClient();
207+
if (sourceContext.doNotOverridePrBuildStatuses()) {
208+
BitbucketBuildStatuses buildStatuses = bitbucket.getBuildStatus(hash);
209+
for (BitbucketBuildStatus bs : buildStatuses.getValues()) {
210+
if (DigestUtils.md5Hex(key).equals(bs.getKey()) && PR_BUILD_PATTERN.matcher(bs.getUrl()).matches()) {
211+
listener.getLogger().println("[Bitbucket] Skip notification which overwrites commit status");
212+
return;
213+
}
214+
}
215+
}
202216
}
203217
createStatus(build, listener, bitbucket, key, hash);
204218
}

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotificationsTrait.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public class BitbucketBuildStatusNotificationsTrait extends SCMSourceTrait {
4545
*/
4646
private boolean sendSuccessNotificationForUnstableBuild;
4747

48+
49+
private boolean doNotOverridePrBuildStatuses;
50+
4851
/**
4952
* Constructor.
5053
*
@@ -61,19 +64,29 @@ public void setSendSuccessNotificationForUnstableBuild(boolean isSendSuccess) {
6164
sendSuccessNotificationForUnstableBuild = isSendSuccess;
6265
}
6366

67+
@DataBoundSetter
68+
public void setDoNotOverridePrBuildStatuses(boolean doNotOverridePrBuildStatuses) {
69+
doNotOverridePrBuildStatuses = doNotOverridePrBuildStatuses;
70+
}
71+
6472
/**
6573
* @return if unstable builds will be communicated as successful
6674
*/
6775
public boolean getSendSuccessNotificationForUnstableBuild() {
6876
return this.sendSuccessNotificationForUnstableBuild;
6977
}
7078

79+
public boolean getDoNotOverridePrBuildStatuses() {
80+
return this.doNotOverridePrBuildStatuses;
81+
}
82+
7183
/**
7284
* {@inheritDoc}
7385
*/
7486
@Override
7587
protected void decorateContext(SCMSourceContext<?, ?> context) {
7688
((BitbucketSCMSourceContext) context).withSendSuccessNotificationForUnstableBuild(getSendSuccessNotificationForUnstableBuild());
89+
((BitbucketSCMSourceContext) context).withDoNotOverridePrBuildStatuses(getDoNotOverridePrBuildStatuses());
7790
}
7891

7992
/**

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceContext.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ public class BitbucketSCMSourceContext extends SCMSourceContext<BitbucketSCMSour
9191
*/
9292
private boolean sendSuccessNotificationForUnstableBuild;
9393

94+
private boolean doNotOverridePrBuildStatuses;
95+
9496
/**
9597
* Constructor.
9698
*
@@ -215,6 +217,10 @@ public final boolean sendSuccessNotificationForUnstableBuild() {
215217
return sendSuccessNotificationForUnstableBuild;
216218
}
217219

220+
public final boolean doNotOverridePrBuildStatuses() {
221+
return doNotOverridePrBuildStatuses;
222+
}
223+
218224
/**
219225
* Adds a requirement for branch details to any {@link BitbucketSCMSourceRequest} for this context.
220226
*
@@ -352,6 +358,12 @@ public final BitbucketSCMSourceContext withSendSuccessNotificationForUnstableBui
352358
return this;
353359
}
354360

361+
@NonNull
362+
public final BitbucketSCMSourceContext withDoNotOverridePrBuildStatuses(boolean doNotOverwritePrBuildStatus) {
363+
this.doNotOverridePrBuildStatuses = doNotOverwritePrBuildStatus;
364+
return this;
365+
}
366+
355367
/**
356368
* {@inheritDoc}
357369
*/

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketApi.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,15 @@ List<? extends BitbucketRepository> getRepositories(@CheckForNull UserRoleInRepo
280280
*/
281281
void postBuildStatus(@NonNull BitbucketBuildStatus status) throws IOException, InterruptedException;
282282

283+
/**
284+
* Set the build status for the given commit hash.
285+
*
286+
* @param hash get the status object for specified key
287+
* @throws IOException if there was a network communications error.
288+
* @throws InterruptedException if interrupted while waiting on remote communications.
289+
*/
290+
BitbucketBuildStatuses getBuildStatus(@NonNull String hash) throws IOException, InterruptedException;
291+
283292
/**
284293
* Returns {@code true} if and only if the repository is private.
285294
*

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketBuildStatus.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
package com.cloudbees.jenkins.plugins.bitbucket.api;
2525

2626
import com.fasterxml.jackson.annotation.JsonIgnore;
27-
import org.apache.commons.codec.digest.DigestUtils;
2827
import org.kohsuke.accmod.Restricted;
2928
import org.kohsuke.accmod.restrictions.DoNotUse;
3029

@@ -71,7 +70,7 @@ public BitbucketBuildStatus(String hash, String description, String state, Strin
7170
this.description = description;
7271
this.state = state;
7372
this.url = url;
74-
this.key = DigestUtils.md5Hex(key);
73+
this.key = key;
7574
this.name = name;
7675
}
7776

@@ -112,7 +111,7 @@ public String getKey() {
112111
}
113112

114113
public void setKey(String key) {
115-
this.key = DigestUtils.md5Hex(key);
114+
this.key = key;
116115
}
117116

118117
public String getName() {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2016, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package com.cloudbees.jenkins.plugins.bitbucket.api;
25+
26+
import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestCommit;
27+
28+
import java.util.List;
29+
30+
public class BitbucketBuildStatuses {
31+
private List<BitbucketBuildStatus> values;
32+
33+
public List<BitbucketBuildStatus> getValues() {
34+
return values;
35+
}
36+
}

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi;
2929
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
3030
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus;
31+
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatuses;
3132
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCloudWorkspace;
3233
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit;
3334
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketException;
@@ -648,6 +649,11 @@ public void postBuildStatus(@NonNull BitbucketBuildStatus status) throws IOExcep
648649
postRequest(url, JsonParser.toJson(status));
649650
}
650651

652+
@Override
653+
public BitbucketBuildStatuses getBuildStatus(@NonNull String hash) throws IOException, InterruptedException {
654+
return null;
655+
}
656+
651657
/**
652658
* {@inheritDoc}
653659
*/

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi;
2828
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
2929
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus;
30+
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatuses;
3031
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit;
3132
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest;
3233
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository;
@@ -510,6 +511,22 @@ public void postBuildStatus(@NonNull BitbucketBuildStatus status) throws IOExcep
510511
);
511512
}
512513

514+
/**
515+
* {@inheritDoc}
516+
*/
517+
public BitbucketBuildStatuses getBuildStatus(@NonNull String hash) throws IOException {
518+
String url = UriTemplate
519+
.fromTemplate(API_COMMIT_STATUS_PATH)
520+
.set("hash", hash)
521+
.expand();
522+
String response = getRequest(url);
523+
try {
524+
return JsonParser.toJava(response, BitbucketBuildStatuses.class);
525+
} catch (IOException e) {
526+
throw new IOException("I/O error when accessing URL: " + url, e);
527+
}
528+
}
529+
513530
/**
514531
* {@inheritDoc}
515532
*/

src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotificationsTrait/config.jelly

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
<f:entry title="${%Communicate Unstable builds to Bitbucket as Successful}" field="sendSuccessNotificationForUnstableBuild">
44
<f:checkbox/>
55
</f:entry>
6+
<f:entry title="${%Do not override PR build statuses}" field="doNotOverridePrBuildStatuses">
7+
<f:checkbox/>
8+
</f:entry>
69
</j:jelly>

0 commit comments

Comments
 (0)