Skip to content

Commit e7638eb

Browse files
ssc327ssc327bitwiseman
authored
Fix Automatic Webhook Creation for BitBucket 5.x [Fixes 352] (#375)
* ssc327: 352: reorganize hook events for different BitBucket versions fix 352 so that Bitbucket versions prior to 5.10 can make automatic webhooks * PR comment updates Co-authored-by: Liam Newman <[email protected]> * Update src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java * Update src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java Co-authored-by: ssc327 <[email protected]> Co-authored-by: Liam Newman <[email protected]>
1 parent 5c88587 commit e7638eb

File tree

8 files changed

+180
-12
lines changed

8 files changed

+180
-12
lines changed

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/HookEventType.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,14 @@ public enum HookEventType {
100100
SERVER_PULL_REQUEST_APPROVED("pr:reviewer:approved", NativeServerPullRequestHookProcessor.class),
101101

102102
/**
103-
* @see <a href="https://confluence.atlassian.com/bitbucketserver068/event-payload-981145451.html#Eventpayload-Modified">Eventpayload-Modified</a>
104-
* @since Bitbucket Server 5.4
103+
* @see <a href="https://confluence.atlassian.com/bitbucketserver0510/event-payload-951390742.html#Eventpayload-Modified.1">Eventpayload: Pull Request - Modified</a>
104+
* @since Bitbucket Server 5.10
105105
*/
106106
SERVER_PULL_REQUEST_MODIFIED("pr:modified", NativeServerPullRequestHookProcessor.class),
107107

108108
/**
109-
* @see <a href="https://confluence.atlassian.com/bitbucketserver054/event-payload-939508609.html#Eventpayload-ReviewersUpdated">Eventpayload-Modified</a>
110-
* @since Bitbucket Server 6.8
109+
* @see <a href="https://confluence.atlassian.com/bitbucketserver0510/event-payload-951390742.html#Eventpayload-ReviewersUpdated">Eventpayload: Pull Request - Reviewers Updated</a>
110+
* @since Bitbucket Server 5.10
111111
*/
112112
SERVER_PULL_REQUEST_REVIEWER_UPDATED("pr:reviewer:updated", NativeServerPullRequestHookProcessor.class),
113113

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookConfiguration.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint;
3131
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration;
3232
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint;
33-
import com.cloudbees.jenkins.plugins.bitbucket.server.BitbucketServerVersion;
3433
import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerWebhook;
3534
import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.NativeBitbucketServerWebhook;
3635
import com.damnhandy.uri.template.UriTemplate;
@@ -67,16 +66,22 @@ public class WebhookConfiguration {
6766
HookEventType.SERVER_PULL_REQUEST_MERGED.getKey(),
6867
HookEventType.SERVER_PULL_REQUEST_DECLINED.getKey(),
6968
HookEventType.SERVER_PULL_REQUEST_DELETED.getKey(),
69+
// only on v5.10 and above
7070
HookEventType.SERVER_PULL_REQUEST_MODIFIED.getKey(),
7171
HookEventType.SERVER_PULL_REQUEST_REVIEWER_UPDATED.getKey(),
7272
// only on v7.x and above
7373
HookEventType.SERVER_PULL_REQUEST_FROM_REF_UPDATED.getKey()
7474
));
7575

7676
/**
77-
* The list of events available in Bitbucket Server v6.x.
77+
* The list of events available in Bitbucket Server v6.x. Applies to v5.10+.
7878
*/
79-
private static final List<String> NATIVE_SERVER_EVENTS_v6 = Collections.unmodifiableList(NATIVE_SERVER_EVENTS_v7.subList(0, 6));
79+
private static final List<String> NATIVE_SERVER_EVENTS_v6 = Collections.unmodifiableList(NATIVE_SERVER_EVENTS_v7.subList(0, 7));
80+
81+
/**
82+
* The list of events available in Bitbucket Server v5.9-.
83+
*/
84+
private static final List<String> NATIVE_SERVER_EVENTS_v5 = Collections.unmodifiableList(NATIVE_SERVER_EVENTS_v7.subList(0, 5));
8085

8186
/**
8287
* The title of the webhook.
@@ -203,8 +208,23 @@ public BitbucketWebHook getHook(BitbucketSCMSource owner) {
203208
private static List<String> getNativeServerEvents(String serverUrl) {
204209
AbstractBitbucketEndpoint endpoint = BitbucketEndpointConfiguration.get().findEndpoint(serverUrl);
205210
if (endpoint instanceof BitbucketServerEndpoint) {
206-
if (((BitbucketServerEndpoint)endpoint).getServerVersion().equals(BitbucketServerVersion.VERSION_6)) {
211+
switch (((BitbucketServerEndpoint) endpoint).getServerVersion()) {
212+
case VERSION_5:
213+
return NATIVE_SERVER_EVENTS_v5;
214+
case VERSION_5_10:
215+
return NATIVE_SERVER_EVENTS_v6;
216+
case VERSION_6:
217+
// plugin version 2.9.1 introduced VERSION_6 setting for BitBucket but it
218+
// actually applies
219+
// to Version 5.10+. In order to preserve backwards compatibility, rather than
220+
// remove
221+
// VERSION_6, it will use the same list as 5.10 until such time a need arises
222+
// for it to have its
223+
// own list
207224
return NATIVE_SERVER_EVENTS_v6;
225+
case VERSION_7:
226+
default:
227+
return NATIVE_SERVER_EVENTS_v7;
208228
}
209229
}
210230

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/BitbucketServerVersion.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727

2828
public enum BitbucketServerVersion implements ModelObject {
2929
VERSION_7("Bitbucket v7.x (and later)"),
30-
VERSION_6("Bitbucket v6.x (and earlier)");
30+
VERSION_6("Bitbucket v6.x"),
31+
VERSION_5_10("Bitbucket v5.10 to v5.16"),
32+
VERSION_5("Bitbucket v5.9 (and earlier)");
3133

3234
private final String displayName;
3335

@@ -41,4 +43,3 @@ public String getDisplayName() {
4143
}
4244

4345
}
44-

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@ private String postRequest(String path, List<? extends NameValuePair> params) th
10071007
private String postRequest(String path, String content) throws IOException {
10081008
HttpPost request = new HttpPost(this.baseURL + path);
10091009
request.setEntity(new StringEntity(content, ContentType.create("application/json", "UTF-8")));
1010+
LOGGER.log(Level.FINEST, content);
10101011
return postRequest(request);
10111012
}
10121013

src/test/java/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfigurationTest.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ public void should_support_configuration_as_code() throws Exception {
649649

650650
BitbucketEndpointConfiguration instance = BitbucketEndpointConfiguration.get();
651651

652-
assertThat(instance.getEndpoints(), hasSize(9));
652+
assertThat(instance.getEndpoints(), hasSize(11));
653653

654654
BitbucketCloudEndpoint endpoint1 = (BitbucketCloudEndpoint) instance.getEndpoints().get(0);
655655
assertThat(endpoint1.getDisplayName(), is(Messages.BitbucketCloudEndpoint_displayName()));
@@ -741,5 +741,25 @@ public void should_support_configuration_as_code() throws Exception {
741741
assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN));
742742
assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_6));
743743

744+
serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(9);
745+
assertThat(serverEndpoint.getDisplayName(), is("Example Inc"));
746+
assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8089"));
747+
assertThat(serverEndpoint.isManageHooks(), is(false));
748+
assertThat(serverEndpoint.getCredentialsId(), is(nullValue()));
749+
assertThat(serverEndpoint.isCallCanMerge(), is(false));
750+
assertThat(serverEndpoint.isCallChanges(), is(true));
751+
assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN));
752+
assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_5_10));
753+
754+
serverEndpoint = (BitbucketServerEndpoint) instance.getEndpoints().get(10);
755+
assertThat(serverEndpoint.getDisplayName(), is("Example Inc"));
756+
assertThat(serverEndpoint.getServerUrl(), is("http://bitbucket.example.com:8090"));
757+
assertThat(serverEndpoint.isManageHooks(), is(false));
758+
assertThat(serverEndpoint.getCredentialsId(), is(nullValue()));
759+
assertThat(serverEndpoint.isCallCanMerge(), is(false));
760+
assertThat(serverEndpoint.isCallChanges(), is(true));
761+
assertThat(serverEndpoint.getWebhookImplementation(), is(BitbucketServerWebhookImplementation.PLUGIN));
762+
assertThat(serverEndpoint.getServerVersion(), is(BitbucketServerVersion.VERSION_5));
763+
744764
}
745765
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.cloudbees.jenkins.plugins.bitbucket.hooks;
2+
3+
import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource;
4+
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketWebHook;
5+
import io.jenkins.plugins.casc.ConfigurationAsCode;
6+
import io.jenkins.plugins.casc.ConfiguratorException;
7+
import org.junit.Before;
8+
import org.junit.ClassRule;
9+
import org.junit.Test;
10+
import org.jvnet.hudson.test.JenkinsRule;
11+
import org.mockito.Mockito;
12+
13+
import static org.junit.Assert.assertFalse;
14+
import static org.junit.Assert.assertTrue;
15+
import static org.mockito.Mockito.when;
16+
17+
public class WebhookConfigurationTest {
18+
19+
@ClassRule
20+
public static JenkinsRule j = new JenkinsRule();
21+
22+
@Before
23+
public void config() throws ConfiguratorException {
24+
ConfigurationAsCode.get().configure(
25+
getClass().getResource(getClass().getSimpleName() + "/configuration-as-code.yml").toString());
26+
}
27+
28+
@Test
29+
public void given_instanceWithServerVersion6_when_getHooks_SERVER_PR_RVWR_UPDATE_EVENT_exists() {
30+
WebhookConfiguration whc = new WebhookConfiguration();
31+
BitbucketSCMSource owner = Mockito.mock(BitbucketSCMSource.class);
32+
final String server = "http://bitbucket.example.com:8088";
33+
when(owner.getServerUrl()).thenReturn(server);
34+
when(owner.getEndpointJenkinsRootUrl()).thenReturn(server);
35+
BitbucketWebHook hook = whc.getHook(owner);
36+
assertTrue(hook.getEvents().contains(HookEventType.SERVER_PULL_REQUEST_REVIEWER_UPDATED.getKey()));
37+
}
38+
39+
@Test
40+
public void given_instanceWithServerVersion510_when_getHooks_SERVER_PR_RVWR_UPDATE_EVENT_exists() {
41+
WebhookConfiguration whc = new WebhookConfiguration();
42+
BitbucketSCMSource owner = Mockito.mock(BitbucketSCMSource.class);
43+
final String server = "http://bitbucket.example.com:8089";
44+
when(owner.getServerUrl()).thenReturn(server);
45+
when(owner.getEndpointJenkinsRootUrl()).thenReturn(server);
46+
BitbucketWebHook hook = whc.getHook(owner);
47+
assertTrue(hook.getEvents().contains(HookEventType.SERVER_PULL_REQUEST_REVIEWER_UPDATED.getKey()));
48+
}
49+
50+
@Test
51+
public void given_instanceWithServerVersion59_when_getHooks_SERVER_PR_RVWR_UPDATE_EVENT_not_exists() {
52+
WebhookConfiguration whc = new WebhookConfiguration();
53+
BitbucketSCMSource owner = Mockito.mock(BitbucketSCMSource.class);
54+
final String server = "http://bitbucket.example.com:8090";
55+
when(owner.getServerUrl()).thenReturn(server);
56+
when(owner.getEndpointJenkinsRootUrl()).thenReturn(server);
57+
BitbucketWebHook hook = whc.getHook(owner);
58+
assertFalse(hook.getEvents().contains(HookEventType.SERVER_PULL_REQUEST_REVIEWER_UPDATED.getKey()));
59+
}
60+
61+
@Test
62+
public void given_instanceWithServerVersion59_when_getHooks_SERVER_PR_MOD_EVENT_not_exists() {
63+
WebhookConfiguration whc = new WebhookConfiguration();
64+
BitbucketSCMSource owner = Mockito.mock(BitbucketSCMSource.class);
65+
final String server = "http://bitbucket.example.com:8090";
66+
when(owner.getServerUrl()).thenReturn(server);
67+
when(owner.getEndpointJenkinsRootUrl()).thenReturn(server);
68+
BitbucketWebHook hook = whc.getHook(owner);
69+
assertFalse(hook.getEvents().contains(HookEventType.SERVER_PULL_REQUEST_MODIFIED.getKey()));
70+
}
71+
72+
@Test
73+
public void given_instanceWithServerVersion7_when_getHooks_SERVER_PR_FROM_REF_UPDATED_EVENT_exists() {
74+
WebhookConfiguration whc = new WebhookConfiguration();
75+
BitbucketSCMSource owner = Mockito.mock(BitbucketSCMSource.class);
76+
final String server = "http://bitbucket.example.com:8087";
77+
when(owner.getServerUrl()).thenReturn(server);
78+
when(owner.getEndpointJenkinsRootUrl()).thenReturn(server);
79+
BitbucketWebHook hook = whc.getHook(owner);
80+
assertTrue(hook.getEvents().contains(HookEventType.SERVER_PULL_REQUEST_FROM_REF_UPDATED.getKey()));
81+
}
82+
83+
}

src/test/resources/com/cloudbees/jenkins/plugins/bitbucket/endpoints/BitbucketEndpointConfigurationTest/configuration-as-code.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,15 @@ unclassified:
5858
callCanMerge: false
5959
callChanges: true
6060
serverVersion: VERSION_6
61-
61+
- bitbucketServerEndpoint:
62+
displayName: "Example Inc"
63+
serverUrl: "http://bitbucket.example.com:8089"
64+
callCanMerge: false
65+
callChanges: true
66+
serverVersion: VERSION_5_10
67+
- bitbucketServerEndpoint:
68+
displayName: "Example Inc"
69+
serverUrl: "http://bitbucket.example.com:8090"
70+
callCanMerge: false
71+
callChanges: true
72+
serverVersion: VERSION_5
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
unclassified:
3+
bitbucketendpointconfiguration:
4+
endpoints:
5+
- bitbucketServerEndpoint:
6+
displayName: "Example Inc"
7+
serverUrl: "http://bitbucket.example.com:8087"
8+
callCanMerge: false
9+
callChanges: false
10+
serverVersion: VERSION_7
11+
webhookImplementation: NATIVE
12+
- bitbucketServerEndpoint:
13+
displayName: "Example Inc"
14+
serverUrl: "http://bitbucket.example.com:8088"
15+
callCanMerge: false
16+
callChanges: true
17+
serverVersion: VERSION_6
18+
webhookImplementation: NATIVE
19+
- bitbucketServerEndpoint:
20+
displayName: "Example Inc"
21+
serverUrl: "http://bitbucket.example.com:8089"
22+
callCanMerge: false
23+
callChanges: true
24+
serverVersion: VERSION_5_10
25+
webhookImplementation: NATIVE
26+
- bitbucketServerEndpoint:
27+
displayName: "Example Inc"
28+
serverUrl: "http://bitbucket.example.com:8090"
29+
callCanMerge: false
30+
callChanges: true
31+
serverVersion: VERSION_5
32+
webhookImplementation: NATIVE

0 commit comments

Comments
 (0)