#55 - Add support to assign Github release issues.

Support self-assignment of Github release issues. Added Apache httpclient to support HTTP PATCH as Java's HttpUrlConnection does not accept PATCH as HTTP method.
This commit is contained in:
Mark Paluch
2017-06-07 14:25:48 +02:00
parent 27900e144a
commit 4707e03d07
5 changed files with 66 additions and 17 deletions

View File

@@ -67,6 +67,11 @@
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.release.model.Project;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.plugin.core.OrderAwarePluginRegistry;
@@ -78,6 +79,7 @@ class IssueTrackerConfiguration {
converters.add(converter);
RestTemplate template = new RestTemplate();
template.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
template.setMessageConverters(converters);
return template;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -159,7 +159,7 @@ class GitHub implements IssueTracker {
return Changelog.of(moduleIteration, tickets);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.plugin.core.Plugin#supports(java.lang.Object)
*/
@@ -222,7 +222,7 @@ class GitHub implements IssueTracker {
}
/*
*
*
* (non-Javadoc)
* @see org.springframework.data.release.tracker.IssueTracker#createReleaseTicket(org.springframework.data.release.model.ModuleIteration)
*/
@@ -257,7 +257,6 @@ class GitHub implements IssueTracker {
}
/*
*
* (non-Javadoc)
* @see org.springframework.data.release.jira.IssueTracker#assignTicketToMe(org.springframework.data.release.jira.Ticket)
*/
@@ -266,15 +265,32 @@ class GitHub implements IssueTracker {
logger.log("Ticket", "Skipping ticket assignment for %s", ticket);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.release.jira.IssueTracker#assignReleaseTicketToMe(org.springframework.data.release.model.ModuleIteration)
*/
@Override
public Ticket assignReleaseTicketToMe(ModuleIteration module) {
logger.log("Ticket", "Skipping ticket assignment for %s", module);
return null;
Assert.notNull(module, "ModuleIteration must not be null.");
Ticket releaseTicketFor = getReleaseTicketFor(module);
String repositoryName = GitProject.of(module.getProject()).getRepositoryName();
Map<String, Object> parameters = newUrlTemplateVariables();
parameters.put("repoName", repositoryName);
parameters.put("id", stripHash(releaseTicketFor));
GitHubIssue edit = GitHubIssue.assignedTo(properties.getUsername());
GitHubIssue response = operations.exchange(ISSUE_BY_ID_URI_TEMPLATE, HttpMethod.PATCH,
new HttpEntity<>(edit, newUserScopedHttpHeaders()), ISSUE_TYPE, parameters).getBody();
return toTicket(response);
}
private String stripHash(Ticket ticket) {
return ticket.getId().startsWith("#") ? ticket.getId().substring(1) : ticket.getId();
}
private HttpHeaders newUserScopedHttpHeaders() {
@@ -324,7 +340,7 @@ class GitHub implements IssueTracker {
return Optional.empty();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.release.issues.IssueTracker#closeIteration(org.springframework.data.release.model.ModuleIteration)
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,11 @@ package org.springframework.data.release.issues.github;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import java.util.Collections;
import java.util.List;
import org.springframework.data.release.model.ModuleIteration;
import org.springframework.util.Assert;
/**
* @author Oliver Gierke
@@ -29,10 +33,17 @@ import org.springframework.data.release.model.ModuleIteration;
class GitHubIssue {
String number, title, state;
List<Object> assignees;
Object milestone;
public static GitHubIssue of(String title, Milestone milestone) {
return new GitHubIssue(null, title, null, milestone.number);
return new GitHubIssue(null, title, null, null, milestone.number);
}
public static GitHubIssue assignedTo(String username) {
Assert.hasText(username, "Username must not be null or empty!");
return new GitHubIssue(null, null, null, Collections.singletonList(username), null);
}
public String getId() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.release.issues.github;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
@@ -33,8 +32,6 @@ import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.release.AbstractIntegrationTests;
import org.springframework.data.release.issues.Ticket;
import org.springframework.data.release.issues.github.GitHub;
import org.springframework.data.release.issues.github.GitHubProperties;
import org.springframework.data.release.model.Iteration;
import org.springframework.data.release.model.ModuleIteration;
import org.springframework.data.release.model.Projects;
@@ -50,12 +47,13 @@ import com.github.tomakehurst.wiremock.junit.WireMockRule;
/**
* Integration Tests for {@link GitHub} using a local {@link WireMockRule} server.
*
*
* @author Mark Paluch
*/
public class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests {
public static final String ISSUES_URI = "/repos/spring-projects/spring-data-build/issues";
public static final String RELEASE_TICKET_URI = "/repos/spring-projects/spring-data-build/issues/233";
public static final String MILESTONES_URI = "/repos/spring-projects/spring-data-build/milestones";
public static final ModuleIteration BUILD_HOPPER_RC1 = ReleaseTrains.HOPPER.getModuleIteration(Iteration.RC1,
"Build");
@@ -75,7 +73,6 @@ public class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests
Assume.assumeThat(uriComponents.getHost(), is("localhost"));
github.reset();
}
/**
@@ -216,6 +213,24 @@ public class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests
verify(0, postRequestedFor(urlPathMatching(MILESTONES_URI)));
}
/**
* @see #55
*/
@Test
public void assignTicketToMe() {
mockGetMilestonesWith("milestones.json");
mockGetIssuesWith("issues.json");
mockService.stubFor(patch(urlPathMatching(RELEASE_TICKET_URI)).//
willReturn(json("issue.json")));
github.assignReleaseTicketToMe(BUILD_HOPPER_RC1);
verify(patchRequestedFor(urlPathMatching(RELEASE_TICKET_URI))
.withRequestBody(equalToJson("{\"assignees\":[\"mp911de\"]}")));
}
private void mockGetIssueWith(String fromClassPath, int issueId) {
mockService.stubFor(get(urlPathMatching(ISSUES_URI + "/" + issueId)).//
willReturn(json(fromClassPath)));