Adding support for Bitbucket Server headers (#1046)

This commit is contained in:
Greg Jacobs
2018-06-13 10:24:32 -05:00
committed by Ryan Baxter
parent f352ecf5f3
commit 97bd640f94
5 changed files with 204 additions and 1 deletions

View File

@@ -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;
}

View File

@@ -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(),

View File

@@ -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": {
}
}

View File

@@ -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
}
}

View File

@@ -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"
}
]
}