@@ -110,9 +110,10 @@ public interface IssueTracker extends Plugin<Project> {
|
||||
* @param module must not be {@literal null}.
|
||||
* @param text the text to use.
|
||||
* @param ticketType the ticket type.
|
||||
* @param assignToCurrentUser
|
||||
* @return the created ticket.
|
||||
*/
|
||||
Ticket createTicket(ModuleIteration module, String text, TicketType ticketType);
|
||||
Ticket createTicket(ModuleIteration module, String text, TicketType ticketType, boolean assignToCurrentUser);
|
||||
|
||||
/**
|
||||
* Assigns the ticket to the current user.
|
||||
|
||||
@@ -127,11 +127,11 @@ class IssueTrackerCommands extends TimedCommand {
|
||||
}
|
||||
|
||||
@CliCommand(value = "tracker create tickets")
|
||||
public String createTickets(@CliOption(key = "", mandatory = true) TrainIteration iteration,
|
||||
public String createTickets(@CliOption(key = "iteration", mandatory = true) TrainIteration iteration,
|
||||
@CliOption(key = "text", mandatory = true) String text) {
|
||||
|
||||
return iteration.stream().//
|
||||
map(module -> getTrackerFor(module).createTicket(module, text, IssueTracker.TicketType.Task))
|
||||
map(module -> getTrackerFor(module).createTicket(module, text, IssueTracker.TicketType.Task, false))
|
||||
.collect(Tickets.toTicketsCollector())
|
||||
.toString();
|
||||
}
|
||||
|
||||
@@ -33,8 +33,25 @@ public class Ticket {
|
||||
|
||||
String id, summary;
|
||||
String url;
|
||||
String assignee;
|
||||
TicketStatus ticketStatus;
|
||||
|
||||
public Ticket(String id, String summary, String url, String assignee, TicketStatus ticketStatus) {
|
||||
this.id = id;
|
||||
this.summary = summary;
|
||||
this.url = url;
|
||||
this.assignee = assignee;
|
||||
this.ticketStatus = ticketStatus;
|
||||
}
|
||||
|
||||
public Ticket(String id, String summary, TicketStatus ticketStatus) {
|
||||
this.id = id;
|
||||
this.summary = summary;
|
||||
this.assignee = null;
|
||||
this.url = null;
|
||||
this.ticketStatus = ticketStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
@@ -78,4 +95,8 @@ public class Ticket {
|
||||
public boolean isReleaseTicketFor(TrainIteration train) {
|
||||
return train.stream().anyMatch(this::isReleaseTicketFor);
|
||||
}
|
||||
|
||||
public boolean isAssignedTo(String username) {
|
||||
return username.equals(assignee);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.release.issues.github;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -251,18 +252,20 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
logger.log(moduleIteration, "Creating release ticket…");
|
||||
|
||||
doCreateTicket(moduleIteration, Tracker.releaseTicketSummary(moduleIteration), TicketType.Task);
|
||||
doCreateTicket(moduleIteration, Tracker.releaseTicketSummary(moduleIteration), TicketType.Task, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text, TicketType ticketType) {
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text, TicketType ticketType,
|
||||
boolean assignToCurrentUser) {
|
||||
|
||||
logger.log(moduleIteration, "Creating ticket…");
|
||||
|
||||
return doCreateTicket(moduleIteration, text, ticketType);
|
||||
return doCreateTicket(moduleIteration, text, ticketType, assignToCurrentUser);
|
||||
}
|
||||
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text, TicketType ticketType) {
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text, TicketType ticketType,
|
||||
boolean assignToCurrentUser) {
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
Milestone milestone = getMilestone(moduleIteration, repositoryName);
|
||||
@@ -271,6 +274,10 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
GitHubWriteIssue gitHubIssue = GitHubWriteIssue.of(text, milestone).withLabel(label.getName());
|
||||
|
||||
if (assignToCurrentUser) {
|
||||
gitHubIssue = gitHubIssue.withAssignees(Collections.singletonList(properties.getUsername()));
|
||||
}
|
||||
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
|
||||
@@ -294,8 +301,12 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
Assert.notNull(ticket, "Ticket must not be null.");
|
||||
|
||||
String repositoryName = GitProject.of(project).getRepositoryName();
|
||||
if (ticket.isAssignedTo(properties.getUsername())) {
|
||||
logger.log("Ticket", "Skipping self-assignment of %s", ticket);
|
||||
return ticket;
|
||||
}
|
||||
|
||||
String repositoryName = GitProject.of(project).getRepositoryName();
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
parameters.put("id", stripHash(ticket));
|
||||
@@ -673,7 +684,8 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
}
|
||||
|
||||
private static Ticket toTicket(GitHubIssue issue) {
|
||||
return new Ticket(issue.getId(), issue.getTitle(), issue.getUrl(), new GithubTicketStatus(issue.getState()));
|
||||
return new Ticket(issue.getId(), issue.getTitle(), issue.getUrl(),
|
||||
issue.getAssignees().isEmpty() ? null : issue.getAssignees().get(0), new GithubTicketStatus(issue.getState()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.release.issues.github;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@@ -30,6 +32,8 @@ public interface GitHubIssue {
|
||||
|
||||
String getState();
|
||||
|
||||
List<String> getAssignees();
|
||||
|
||||
/**
|
||||
* @return HTML URL.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.release.issues.github;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@@ -51,6 +52,11 @@ class GitHubReadIssue implements Comparable<GitHubReadIssue>, GitHubIssue {
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAssignees() {
|
||||
return assignees.stream().map(GitHubUser::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GitHubReadIssue o) {
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import lombok.With;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -66,4 +68,10 @@ class GitHubWriteIssue implements GitHubIssue {
|
||||
|
||||
return withLabels(labels);
|
||||
}
|
||||
|
||||
public List<String> getAssignees() {
|
||||
return assignees == null ? Collections.emptyList()
|
||||
: assignees.stream().map(Objects::toString).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -313,20 +313,21 @@ class Jira implements JiraConnector {
|
||||
|
||||
logger.log(moduleIteration, "Creating release ticket…");
|
||||
|
||||
doCreateTicket(moduleIteration, Tracker.releaseTicketSummary(moduleIteration));
|
||||
doCreateTicket(moduleIteration, Tracker.releaseTicketSummary(moduleIteration), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text, TicketType ticketType) {
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text, TicketType ticketType,
|
||||
boolean assignToCurrentUser) {
|
||||
|
||||
Assert.notNull(moduleIteration, "ModuleIteration must not be null.");
|
||||
|
||||
logger.log(moduleIteration, "Creating ticket…");
|
||||
|
||||
return doCreateTicket(moduleIteration, text);
|
||||
return doCreateTicket(moduleIteration, text, assignToCurrentUser);
|
||||
}
|
||||
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text) {
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text, boolean assignToCurrentUser) {
|
||||
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
@@ -337,6 +338,10 @@ class Jira implements JiraConnector {
|
||||
JiraComponents jiraComponents = getJiraComponents(moduleIteration.getProjectKey());
|
||||
JiraIssue jiraIssue = prepareJiraIssueToCreate(text, moduleIteration, jiraComponents);
|
||||
|
||||
if (assignToCurrentUser) {
|
||||
jiraIssue.assignTo(jiraProperties.getUsername());
|
||||
}
|
||||
|
||||
CreatedJiraIssue created = operations.exchange(CREATE_ISSUES_TEMPLATE, HttpMethod.POST,
|
||||
new HttpEntity<Object>(jiraIssue, httpHeaders), CreatedJiraIssue.class, parameters).getBody();
|
||||
|
||||
@@ -739,7 +744,8 @@ class Jira implements JiraConnector {
|
||||
}
|
||||
|
||||
return new Ticket(issue.getKey(), fields.getSummary(),
|
||||
String.format("%s/browse/%s", jiraProperties.getApiUrl(), issue.getKey()), jiraTicketStatus);
|
||||
String.format("%s/browse/%s", jiraProperties.getApiUrl(), issue.getKey()),
|
||||
fields.getAssignee() != null ? fields.getAssignee().getName() : null, jiraTicketStatus);
|
||||
}
|
||||
|
||||
private Map<String, Object> newUrlTemplateVariables() {
|
||||
|
||||
@@ -139,6 +139,10 @@ class JiraIssue {
|
||||
isPresent();
|
||||
}
|
||||
|
||||
public void assignTo(String username) {
|
||||
getFields().setAssignee(new JiraUser(username, null));
|
||||
}
|
||||
|
||||
@Data
|
||||
static class Fields {
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ class JiraConnectorIntegrationTests extends AbstractIntegrationTests {
|
||||
mockService.stubFor(put(urlPathMatching("/rest/api/2/issue/DATAREDIS-302")).//
|
||||
willReturn(aResponse().withStatus(204)));
|
||||
|
||||
jira.assignTicketToMe(Projects.REDIS, new Ticket("DATAREDIS-302", "", null, null));
|
||||
jira.assignTicketToMe(Projects.REDIS, new Ticket("DATAREDIS-302", "", null));
|
||||
|
||||
verify(putRequestedFor(urlPathMatching("/rest/api/2/issue/DATAREDIS-302")).withRequestBody(equalToJson(
|
||||
"{\"update\":{\"assignee\":[ {\"set\":{\"name\":\"dummy\"}} ] }, \"transition\":{}, \"fields\":{}}")));
|
||||
@@ -271,7 +271,7 @@ class JiraConnectorIntegrationTests extends AbstractIntegrationTests {
|
||||
mockService.stubFor(post(urlPathMatching("/rest/api/2/issue/DATACASS-302")).//
|
||||
willReturn(aResponse().withStatus(204)));
|
||||
|
||||
jira.assignTicketToMe(Projects.CASSANDRA, new Ticket("DATACASS-302", "", null, null));
|
||||
jira.assignTicketToMe(Projects.CASSANDRA, new Ticket("DATACASS-302", "", null));
|
||||
|
||||
verify(0, postRequestedFor(urlPathMatching("/rest/api/2/issue/DATACASS-302")));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class TicketsUnitTests {
|
||||
@Test
|
||||
void hasReleaseTicketShouldReturnTrue() {
|
||||
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", null, JiraTicketStatus.of(false, "", ""));
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", JiraTicketStatus.of(false, "", ""));
|
||||
Tickets tickets = new Tickets(Collections.singletonList(ticket));
|
||||
|
||||
boolean result = tickets.hasReleaseTicket(ReleaseTrains.HOPPER.getModuleIteration(Projects.JPA, Iteration.GA));
|
||||
@@ -47,7 +47,7 @@ class TicketsUnitTests {
|
||||
@Test
|
||||
void hasReleaseTickeForTicketWithoutTrainNameShouldReturnFalse() {
|
||||
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA", null, JiraTicketStatus.of(false, "", ""));
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA", JiraTicketStatus.of(false, "", ""));
|
||||
Tickets tickets = new Tickets(Collections.singletonList(ticket));
|
||||
|
||||
boolean result = tickets.hasReleaseTicket(ReleaseTrains.HOPPER.getModuleIteration(Projects.JPA, Iteration.GA));
|
||||
@@ -57,7 +57,7 @@ class TicketsUnitTests {
|
||||
@Test
|
||||
void getReleaseTicketReturnsReleaseTicket() {
|
||||
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", null, JiraTicketStatus.of(false, "", ""));
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", JiraTicketStatus.of(false, "", ""));
|
||||
Tickets tickets = new Tickets(Collections.singletonList(ticket));
|
||||
|
||||
Ticket releaseTicket = tickets
|
||||
@@ -70,7 +70,7 @@ class TicketsUnitTests {
|
||||
|
||||
Tickets tickets = new Tickets(
|
||||
Collections
|
||||
.singletonList(new Ticket("1234", "Release 2.4 GA (2020.0.0)", null, JiraTicketStatus.of(false, "", ""))));
|
||||
.singletonList(new Ticket("1234", "Release 2.4 GA (2020.0.0)", JiraTicketStatus.of(false, "", ""))));
|
||||
|
||||
Ticket releaseTicket = tickets
|
||||
.getReleaseTicket(ReleaseTrains.OCKHAM.getModuleIteration(Projects.JPA, Iteration.GA));
|
||||
@@ -78,14 +78,14 @@ class TicketsUnitTests {
|
||||
|
||||
tickets = new Tickets(
|
||||
Collections
|
||||
.singletonList(new Ticket("1234", "Release 2.4 M1 (2020.0.0)", null, JiraTicketStatus.of(false, "", ""))));
|
||||
.singletonList(new Ticket("1234", "Release 2.4 M1 (2020.0.0)", JiraTicketStatus.of(false, "", ""))));
|
||||
|
||||
releaseTicket = tickets.getReleaseTicket(ReleaseTrains.OCKHAM.getModuleIteration(Projects.JPA, Iteration.M1));
|
||||
assertThat(releaseTicket).isNotNull();
|
||||
|
||||
tickets = new Tickets(
|
||||
Collections
|
||||
.singletonList(new Ticket("1234", "Release 2.4.1 (2020.0.1)", null, JiraTicketStatus.of(false, "", ""))));
|
||||
.singletonList(new Ticket("1234", "Release 2.4.1 (2020.0.1)", JiraTicketStatus.of(false, "", ""))));
|
||||
|
||||
releaseTicket = tickets.getReleaseTicket(ReleaseTrains.OCKHAM.getModuleIteration(Projects.JPA, Iteration.SR1));
|
||||
assertThat(releaseTicket).isNotNull();
|
||||
@@ -94,7 +94,7 @@ class TicketsUnitTests {
|
||||
@Test
|
||||
void getReleaseTicketThrowsExceptionWithoutAReleaseTicket() {
|
||||
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA", null, JiraTicketStatus.of(false, "", ""));
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA", JiraTicketStatus.of(false, "", ""));
|
||||
Tickets tickets = new Tickets(Collections.singletonList(ticket));
|
||||
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
@@ -104,7 +104,7 @@ class TicketsUnitTests {
|
||||
@Test
|
||||
void getResolvedReleaseTicket() {
|
||||
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", null, JiraTicketStatus.of(true, "", ""));
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", JiraTicketStatus.of(true, "", ""));
|
||||
Tickets tickets = new Tickets(Collections.singletonList(ticket));
|
||||
|
||||
Ticket releaseTicket = tickets
|
||||
@@ -115,7 +115,7 @@ class TicketsUnitTests {
|
||||
@Test
|
||||
void getReleaseTicketsReturnsReleaseTickets() {
|
||||
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", null, JiraTicketStatus.of(false, "", ""));
|
||||
Ticket ticket = new Ticket("1234", "Release 1.10 GA (Hopper)", JiraTicketStatus.of(false, "", ""));
|
||||
Tickets tickets = new Tickets(Collections.singletonList(ticket));
|
||||
|
||||
Tickets result = tickets
|
||||
|
||||
Reference in New Issue
Block a user