Adding support for Bitbucket Server headers (#1046)
This commit is contained in:
@@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @author Greg Jacobs
|
||||
*
|
||||
*/
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 100)
|
||||
@@ -39,6 +40,7 @@ public class BitbucketPropertyPathNotificationExtractor
|
||||
if (("repo:push".equals(headers.getFirst("X-Event-Key")) ||
|
||||
"pullrequest:fulfilled".equals(headers.getFirst("X-Event-Key"))) &&
|
||||
StringUtils.hasText(headers.getFirst("X-Hook-UUID"))) {
|
||||
// Bitbucket cloud
|
||||
Object push = request.get("push");
|
||||
if (push instanceof Map && ((Map<?,?>)push).get("changes") instanceof Collection) {
|
||||
// Bitbucket doesn't tell us the files that changed so this is a
|
||||
@@ -46,6 +48,16 @@ public class BitbucketPropertyPathNotificationExtractor
|
||||
return new PropertyPathNotification("application.yml");
|
||||
}
|
||||
}
|
||||
else if ( ("repo:refs_changed".equals(headers.getFirst("X-Event-Key")) ||
|
||||
"pr:merged".equals(headers.getFirst("X-Event-Key"))) &&
|
||||
StringUtils.hasText(headers.getFirst("X-Request-Id"))) {
|
||||
//Bitbucket server
|
||||
if (request.get("changes") instanceof Collection) {
|
||||
// Bitbucket doesn't tell us the files that changed so this is a
|
||||
// broadcast to all apps
|
||||
return new PropertyPathNotification("application.yml");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -33,13 +34,19 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @author Greg Jacobs
|
||||
*
|
||||
*/
|
||||
public class BitbucketPropertyPathNotificationExtractorTests {
|
||||
|
||||
private BitbucketPropertyPathNotificationExtractor extractor = new BitbucketPropertyPathNotificationExtractor();
|
||||
|
||||
private HttpHeaders headers = new HttpHeaders();
|
||||
private HttpHeaders headers;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
headers = new HttpHeaders();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitbucketSample() throws Exception {
|
||||
@@ -80,6 +87,24 @@ public class BitbucketPropertyPathNotificationExtractorTests {
|
||||
public void githubNotDetected() throws Exception {
|
||||
assertNotExtracted("github.json", "repo:push");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingUuidHeader() throws Exception {
|
||||
// https://confluence.atlassian.com/bitbucket/event-payloads-740262817.html#EventPayloads-Push
|
||||
Map<String, Object> value = readPayload("bitbucket.json");
|
||||
this.headers.set("X-Event-Key", "repo:push");
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNull(extracted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingChanges() throws Exception {
|
||||
// https://confluence.atlassian.com/bitbucket/event-payloads-740262817.html#EventPayloads-Push
|
||||
Map<String, Object> value = readPayload("bitbucket-invalid.json");
|
||||
setHeaders("repo:push");
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNull(extracted);
|
||||
}
|
||||
|
||||
private void assertNotExtracted(String path, String eventKey) throws java.io.IOException {
|
||||
Map<String, Object> value = readPayload(path);
|
||||
@@ -87,7 +112,62 @@ public class BitbucketPropertyPathNotificationExtractorTests {
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNull(extracted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitbucketServerSample() throws Exception {
|
||||
// https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html
|
||||
Map<String, Object> value = readPayload("bitbucketserver.json");
|
||||
setServerHeaders("repo:refs_changed");
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNotNull(extracted);
|
||||
assertEquals("application.yml", extracted.getPaths()[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitbucketServerSamplePullRequest() throws Exception {
|
||||
// https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html
|
||||
Map<String, Object> value = readPayload("bitbucketserver.json");
|
||||
setServerHeaders("pr:merged");
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNotNull(extracted);
|
||||
assertEquals("application.yml", extracted.getPaths()[0]);
|
||||
}
|
||||
|
||||
private void setServerHeaders(String eventKey) {
|
||||
this.headers.set("X-Event-Key", eventKey);
|
||||
this.headers.set("X-Request-Id", UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notAPushOrPullRequestServer() throws Exception {
|
||||
assertNotExtractedServer("bitbucketserver.json", "repo:comment:added");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingUuidHeaderServer() throws Exception {
|
||||
// https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html
|
||||
Map<String, Object> value = readPayload("bitbucketserver.json");
|
||||
this.headers.set("X-Event-Key", "repo:refs_changed");
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNull(extracted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingChangesServer() throws Exception {
|
||||
// https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html
|
||||
Map<String, Object> value = readPayload("bitbucketserver-invalid.json");
|
||||
setServerHeaders("repo:refs_changed");
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNull(extracted);
|
||||
}
|
||||
|
||||
private void assertNotExtractedServer(String path, String eventKey) throws java.io.IOException {
|
||||
Map<String, Object> value = readPayload(path);
|
||||
setServerHeaders(eventKey);
|
||||
PropertyPathNotification extracted = this.extractor.extract(this.headers, value);
|
||||
assertNull(extracted);
|
||||
}
|
||||
|
||||
private Map<String, Object> readPayload(String path) throws java.io.IOException {
|
||||
return new ObjectMapper().readValue(
|
||||
new ClassPathResource(path).getInputStream(),
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"actor": {
|
||||
"username": "emmap1",
|
||||
"display_name": "Emma",
|
||||
"uuid": "{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
|
||||
"links": {
|
||||
"self": {
|
||||
"href": "https://api.bitbucket.org/api/2.0/users/emmap1"
|
||||
},
|
||||
"html": {
|
||||
"href": "https://api.bitbucket.org/emmap1"
|
||||
},
|
||||
"avatar": {
|
||||
"href": "https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"links": {
|
||||
"self": {
|
||||
"href": "https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket"
|
||||
},
|
||||
"html": {
|
||||
"href": "https://api.bitbucket.org/bitbucket/bitbucket"
|
||||
},
|
||||
"avatar": {
|
||||
"href": "https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png"
|
||||
}
|
||||
},
|
||||
"uuid": "{673a6070-3421-46c9-9d48-90745f7bfe8e}",
|
||||
"full_name": "team_name/repo_name",
|
||||
"name": "repo_name",
|
||||
"scm": "git",
|
||||
"is_private": true
|
||||
},
|
||||
"push": {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"eventKey":"repo:refs_changed",
|
||||
"date":"2017-09-19T09:45:32+1000",
|
||||
"actor":{
|
||||
"name":"admin",
|
||||
"emailAddress":"admin@example.com",
|
||||
"id":1,
|
||||
"displayName":"Administrator",
|
||||
"active":true,
|
||||
"slug":"admin",
|
||||
"type":"NORMAL"
|
||||
},
|
||||
"repository":{
|
||||
"slug":"repository",
|
||||
"id":84,
|
||||
"name":"repository",
|
||||
"scmId":"git",
|
||||
"state":"AVAILABLE",
|
||||
"statusMessage":"Available",
|
||||
"forkable":true,
|
||||
"project":{
|
||||
"key":"PROJ",
|
||||
"id":84,
|
||||
"name":"project",
|
||||
"public":false,
|
||||
"type":"NORMAL"
|
||||
},
|
||||
"public":false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"eventKey":"repo:refs_changed",
|
||||
"date":"2017-09-19T09:45:32+1000",
|
||||
"actor":{
|
||||
"name":"admin",
|
||||
"emailAddress":"admin@example.com",
|
||||
"id":1,
|
||||
"displayName":"Administrator",
|
||||
"active":true,
|
||||
"slug":"admin",
|
||||
"type":"NORMAL"
|
||||
},
|
||||
"repository":{
|
||||
"slug":"repository",
|
||||
"id":84,
|
||||
"name":"repository",
|
||||
"scmId":"git",
|
||||
"state":"AVAILABLE",
|
||||
"statusMessage":"Available",
|
||||
"forkable":true,
|
||||
"project":{
|
||||
"key":"PROJ",
|
||||
"id":84,
|
||||
"name":"project",
|
||||
"public":false,
|
||||
"type":"NORMAL"
|
||||
},
|
||||
"public":false
|
||||
},
|
||||
"changes":[
|
||||
{
|
||||
"ref":{
|
||||
"id":"refs/heads/master",
|
||||
"displayId":"master",
|
||||
"type":"BRANCH"
|
||||
},
|
||||
"refId":"refs/heads/master",
|
||||
"fromHash":"ecddabb624f6f5ba43816f5926e580a5f680a932",
|
||||
"toHash":"178864a7d521b6f5e720b386b2c2b0ef8563e0dc",
|
||||
"type":"UPDATE"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user