#162 - Attach label/component to IssueTracker.createTicket(…).
This commit is contained in:
@@ -51,6 +51,7 @@ import org.springframework.shell.support.table.Table;
|
||||
public class DependencyCommands extends TimedCommand {
|
||||
|
||||
public static final String BUILD_PROPERTIES = "dependency-upgrade-build.properties";
|
||||
|
||||
DependencyOperations operations;
|
||||
GitOperations git;
|
||||
Logger logger;
|
||||
|
||||
@@ -134,7 +134,7 @@ public class DependencyOperations {
|
||||
ModuleIteration module = iteration.getModule(project);
|
||||
|
||||
logger.log(module, "Creating upgrade ticket for %s", upgradeTicketSummary);
|
||||
tracker.createTicket(module, upgradeTicketSummary);
|
||||
tracker.createTicket(module, upgradeTicketSummary, IssueTracker.TicketType.DependencyUpgrade);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,9 +101,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.
|
||||
* @return the created ticket.
|
||||
*/
|
||||
Ticket createTicket(ModuleIteration module, String text);
|
||||
Ticket createTicket(ModuleIteration module, String text, TicketType ticketType);
|
||||
|
||||
/**
|
||||
* Assigns the ticket to the current user.
|
||||
@@ -173,4 +174,8 @@ public interface IssueTracker extends Plugin<Project> {
|
||||
* @return
|
||||
*/
|
||||
Tickets findTickets(ModuleIteration moduleIteration, List<TicketReference> ticketReferences);
|
||||
|
||||
enum TicketType {
|
||||
Task, DependencyUpgrade;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,8 @@ class IssueTrackerCommands extends TimedCommand {
|
||||
@CliOption(key = "text", mandatory = true) String text) {
|
||||
|
||||
return iteration.stream().//
|
||||
map(module -> getTrackerFor(module).createTicket(module, text)).collect(Tickets.toTicketsCollector())
|
||||
map(module -> getTrackerFor(module).createTicket(module, text, IssueTracker.TicketType.Task))
|
||||
.collect(Tickets.toTicketsCollector())
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ public class ChangelogGenerator {
|
||||
* @param issues the issues to generate the changelog for
|
||||
* @param sectionContentPostProcessor the postprocessor for a changelog section
|
||||
*/
|
||||
public String generate(List<GitHubIssue> issues,
|
||||
public String generate(List<GitHubReadIssue> issues,
|
||||
BiFunction<ChangelogSection, String, String> sectionContentPostProcessor) {
|
||||
return generateContent(issues, sectionContentPostProcessor);
|
||||
}
|
||||
|
||||
private boolean isExcluded(GitHubIssue issue) {
|
||||
private boolean isExcluded(GitHubReadIssue issue) {
|
||||
return issue.getLabels().stream().anyMatch(this::isExcluded);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class ChangelogGenerator {
|
||||
return this.excludeLabels.contains(label.getName());
|
||||
}
|
||||
|
||||
private String generateContent(List<GitHubIssue> issues,
|
||||
private String generateContent(List<GitHubReadIssue> issues,
|
||||
BiFunction<ChangelogSection, String, String> sectionContentPostProcessor) {
|
||||
StringBuilder content = new StringBuilder();
|
||||
addSectionContent(content, this.sections.collate(issues), sectionContentPostProcessor);
|
||||
@@ -85,7 +85,7 @@ public class ChangelogGenerator {
|
||||
return content.toString();
|
||||
}
|
||||
|
||||
private void addSectionContent(StringBuilder result, Map<ChangelogSection, List<GitHubIssue>> sectionIssues,
|
||||
private void addSectionContent(StringBuilder result, Map<ChangelogSection, List<GitHubReadIssue>> sectionIssues,
|
||||
BiFunction<ChangelogSection, String, String> sectionContentPostProcessor) {
|
||||
|
||||
sectionIssues.forEach((section, issues) -> {
|
||||
@@ -102,7 +102,7 @@ public class ChangelogGenerator {
|
||||
});
|
||||
}
|
||||
|
||||
private String getFormattedIssue(GitHubIssue issue) {
|
||||
private String getFormattedIssue(GitHubReadIssue issue) {
|
||||
String title = issue.getTitle();
|
||||
title = ghUserMentionPattern.matcher(title).replaceAll("$1`$2`");
|
||||
return String.format("- %s %s%n", title, getLinkToIssue(issue));
|
||||
@@ -112,11 +112,11 @@ public class ChangelogGenerator {
|
||||
return "[" + issue.getId() + "]" + "(" + issue.getUrl() + ")";
|
||||
}
|
||||
|
||||
private Set<GitHubUser> getContributors(List<GitHubIssue> issues) {
|
||||
private Set<GitHubUser> getContributors(List<GitHubReadIssue> issues) {
|
||||
if (this.excludeContributors.contains("*")) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return issues.stream().filter((issue) -> issue.getPullRequest() != null).map(GitHubIssue::getUser)
|
||||
return issues.stream().filter((issue) -> issue.getPullRequest() != null).map(GitHubReadIssue::getUser)
|
||||
.filter(this::isIncludedContributor).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class ChangelogSection {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
boolean isMatchFor(GitHubIssue issue) {
|
||||
boolean isMatchFor(GitHubReadIssue issue) {
|
||||
for (String candidate : this.labels) {
|
||||
for (Label label : issue.getLabels()) {
|
||||
if (label.getName().contains(candidate)) {
|
||||
|
||||
@@ -52,12 +52,12 @@ class ChangelogSections {
|
||||
this.sections = DEFAULT_SECTIONS;
|
||||
}
|
||||
|
||||
Map<ChangelogSection, List<GitHubIssue>> collate(List<GitHubIssue> issues) {
|
||||
Map<ChangelogSection, List<GitHubReadIssue>> collate(List<GitHubReadIssue> issues) {
|
||||
|
||||
SortedMap<ChangelogSection, List<GitHubIssue>> collated = new TreeMap<>(
|
||||
SortedMap<ChangelogSection, List<GitHubReadIssue>> collated = new TreeMap<>(
|
||||
Comparator.comparing(this.sections::indexOf));
|
||||
|
||||
for (GitHubIssue issue : issues) {
|
||||
for (GitHubReadIssue issue : issues) {
|
||||
List<ChangelogSection> sections = getSections(issue);
|
||||
for (ChangelogSection section : sections) {
|
||||
collated.computeIfAbsent(section, (key) -> new ArrayList<>());
|
||||
@@ -67,7 +67,7 @@ class ChangelogSections {
|
||||
return collated;
|
||||
}
|
||||
|
||||
private List<ChangelogSection> getSections(GitHubIssue issue) {
|
||||
private List<ChangelogSection> getSections(GitHubReadIssue issue) {
|
||||
List<ChangelogSection> result = new ArrayList<>();
|
||||
Set<String> groupClaimes = new HashSet<>();
|
||||
for (ChangelogSection section : this.sections) {
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.springframework.data.release.issues.IssueTracker;
|
||||
import org.springframework.data.release.issues.Ticket;
|
||||
import org.springframework.data.release.issues.TicketReference;
|
||||
import org.springframework.data.release.issues.Tickets;
|
||||
import org.springframework.data.release.issues.github.GitHubIssue.Milestone;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.DocumentationMetadata;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
@@ -79,13 +78,22 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
private static final String RELEASE_BY_ID_URI_TEMPLATE = "/repos/spring-projects/{repoName}/releases/{id}";
|
||||
|
||||
private static final ParameterizedTypeReference<List<Milestone>> MILESTONES_TYPE = new ParameterizedTypeReference<List<Milestone>>() {};
|
||||
private static final ParameterizedTypeReference<List<GitHubIssue>> ISSUES_TYPE = new ParameterizedTypeReference<List<GitHubIssue>>() {};
|
||||
private static final ParameterizedTypeReference<GitHubIssue> ISSUE_TYPE = new ParameterizedTypeReference<GitHubIssue>() {};
|
||||
private static final ParameterizedTypeReference<List<GitHubReadIssue>> ISSUES_TYPE = new ParameterizedTypeReference<List<GitHubReadIssue>>() {};
|
||||
private static final ParameterizedTypeReference<GitHubReadIssue> ISSUE_TYPE = new ParameterizedTypeReference<GitHubReadIssue>() {};
|
||||
|
||||
private static final Map<TicketType, Label> TICKET_LABELS = new HashMap<>();
|
||||
|
||||
static {
|
||||
|
||||
TICKET_LABELS.put(TicketType.Task, LabelConfiguration.TYPE_TASK);
|
||||
TICKET_LABELS.put(TicketType.DependencyUpgrade, LabelConfiguration.TYPE_DEPENDENCY_UPGRADE);
|
||||
}
|
||||
|
||||
private final Logger logger;
|
||||
private final GitHubProperties properties;
|
||||
private final ExecutorService executorService;
|
||||
|
||||
|
||||
public GitHub(@Qualifier("tracker") RestTemplateBuilder templateBuilder, Logger logger, GitHubProperties properties,
|
||||
ExecutorService executorService) {
|
||||
|
||||
@@ -129,7 +137,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
ticketIds.forEach(ticketId -> {
|
||||
|
||||
GitHubIssue ticket = findTicket(repositoryName, ticketId);
|
||||
GitHubReadIssue ticket = findTicket(repositoryName, ticketId);
|
||||
if (ticket != null) {
|
||||
tickets.add(toTicket(ticket));
|
||||
}
|
||||
@@ -214,7 +222,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
parameters.put("repoName", repositoryName);
|
||||
|
||||
operations.exchange(MILESTONES_URI_TEMPLATE, HttpMethod.POST,
|
||||
new HttpEntity<Object>(githubMilestone.toMilestone(), httpHeaders), GitHubIssue.Milestone.class, parameters);
|
||||
new HttpEntity<Object>(githubMilestone.toMilestone(), httpHeaders), Milestone.class, parameters);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -243,29 +251,31 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
logger.log(moduleIteration, "Creating release ticket…");
|
||||
|
||||
doCreateTicket(moduleIteration, Tracker.releaseTicketSummary(moduleIteration));
|
||||
doCreateTicket(moduleIteration, Tracker.releaseTicketSummary(moduleIteration), TicketType.Task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text) {
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text, TicketType ticketType) {
|
||||
|
||||
logger.log(moduleIteration, "Creating ticket…");
|
||||
|
||||
return doCreateTicket(moduleIteration, text);
|
||||
return doCreateTicket(moduleIteration, text, ticketType);
|
||||
}
|
||||
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
private Ticket doCreateTicket(ModuleIteration moduleIteration, String text, TicketType ticketType) {
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
Milestone milestone = getMilestone(moduleIteration, repositoryName);
|
||||
GitHubIssue gitHubIssue = GitHubIssue.of(text, milestone);
|
||||
|
||||
Label label = TICKET_LABELS.get(ticketType);
|
||||
|
||||
GitHubWriteIssue gitHubIssue = GitHubWriteIssue.of(text, milestone).withLabel(label.getName());
|
||||
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
|
||||
GitHubIssue body = operations.exchange(ISSUES_URI_TEMPLATE, HttpMethod.POST,
|
||||
new HttpEntity<Object>(gitHubIssue, httpHeaders), GitHubIssue.class, parameters).getBody();
|
||||
GitHubReadIssue body = operations.exchange(ISSUES_URI_TEMPLATE, HttpMethod.POST,
|
||||
new HttpEntity<Object>(gitHubIssue), GitHubReadIssue.class, parameters).getBody();
|
||||
|
||||
return toTicket(body);
|
||||
}
|
||||
@@ -300,9 +310,9 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
parameters.put("repoName", repositoryName);
|
||||
parameters.put("id", stripHash(releaseTicketFor));
|
||||
|
||||
GitHubIssue edit = GitHubIssue.assignedTo(properties.getUsername());
|
||||
GitHubWriteIssue edit = GitHubWriteIssue.assignedTo(properties.getUsername());
|
||||
|
||||
GitHubIssue response = operations.exchange(ISSUE_BY_ID_URI_TEMPLATE, HttpMethod.PATCH,
|
||||
GitHubReadIssue response = operations.exchange(ISSUE_BY_ID_URI_TEMPLATE, HttpMethod.PATCH,
|
||||
new HttpEntity<>(edit, new HttpHeaders()), ISSUE_TYPE, parameters).getBody();
|
||||
|
||||
return toTicket(response);
|
||||
@@ -328,12 +338,12 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
Assert.notNull(module, "ModuleIteration must not be null.");
|
||||
|
||||
Ticket releaseTicketFor = getReleaseTicketFor(module);
|
||||
GitHubIssue response = close(module, releaseTicketFor);
|
||||
GitHubReadIssue response = close(module, releaseTicketFor);
|
||||
|
||||
return toTicket(response);
|
||||
}
|
||||
|
||||
private GitHubIssue close(ModuleIteration module, Ticket ticket) {
|
||||
private GitHubReadIssue close(ModuleIteration module, Ticket ticket) {
|
||||
|
||||
String repositoryName = GitProject.of(module.getProject()).getRepositoryName();
|
||||
|
||||
@@ -341,7 +351,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
parameters.put("repoName", repositoryName);
|
||||
parameters.put("id", stripHash(ticket));
|
||||
|
||||
GitHubIssue edit = GitHubIssue.assignedTo(properties.getUsername()).close();
|
||||
GitHubWriteIssue edit = GitHubWriteIssue.assignedTo(properties.getUsername()).close();
|
||||
|
||||
return operations.exchange(ISSUE_BY_ID_URI_TEMPLATE, HttpMethod.PATCH,
|
||||
new HttpEntity<>(edit, new HttpHeaders()), ISSUE_TYPE, parameters).getBody();
|
||||
@@ -372,7 +382,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
doWithPaging(MILESTONE_URI, HttpMethod.GET, parameters, new HttpEntity<>(new HttpHeaders()),
|
||||
MILESTONES_TYPE, milestones -> {
|
||||
|
||||
Optional<GitHubIssue.Milestone> milestone = milestones.stream(). //
|
||||
Optional<Milestone> milestone = milestones.stream(). //
|
||||
filter(m -> m.matches(moduleIteration)). //
|
||||
findFirst(). //
|
||||
map(m -> {
|
||||
@@ -448,21 +458,21 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
.collect(Tickets.toTicketsCollector());
|
||||
}
|
||||
|
||||
List<GitHubIssue> findGitHubIssues(ModuleIteration moduleIteration, List<TicketReference> ticketReferences) {
|
||||
List<GitHubReadIssue> findGitHubIssues(ModuleIteration moduleIteration, List<TicketReference> ticketReferences) {
|
||||
|
||||
logger.log(moduleIteration, "Looking up GitHub issues from milestone …");
|
||||
|
||||
Map<String, GitHubIssue> issues = getIssuesFor(moduleIteration, false, true)
|
||||
Map<String, GitHubReadIssue> issues = getIssuesFor(moduleIteration, false, true)
|
||||
.collect(Collectors.toMap(GitHubIssue::getId, Function.identity()));
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
|
||||
logger.log(moduleIteration, "Resolving GitHub issues …");
|
||||
Collection<GitHubIssue> foundIssues = ExecutionUtils.runAndReturn(executorService,
|
||||
Collection<GitHubReadIssue> foundIssues = ExecutionUtils.runAndReturn(executorService,
|
||||
Streamable.of(() -> ticketReferences.stream().filter(it -> it.getId().startsWith("#"))),
|
||||
ticketReference -> getTicket(issues, repositoryName, ticketReference));
|
||||
|
||||
List<GitHubIssue> gitHubIssues = foundIssues.stream().filter(it -> {
|
||||
List<GitHubReadIssue> gitHubIssues = foundIssues.stream().filter(it -> {
|
||||
Ticket ticket = toTicket(it);
|
||||
return !ticket.isReleaseTicketFor(moduleIteration) && !ticket.isReleaseTicket();
|
||||
}).collect(Collectors.toList());
|
||||
@@ -472,7 +482,8 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
return gitHubIssues;
|
||||
}
|
||||
|
||||
private GitHubIssue getTicket(Map<String, GitHubIssue> cache, String repositoryName, TicketReference reference) {
|
||||
private GitHubReadIssue getTicket(Map<String, GitHubReadIssue> cache, String repositoryName,
|
||||
TicketReference reference) {
|
||||
|
||||
if (cache.containsKey(reference.getId())) {
|
||||
return cache.get(reference.getId());
|
||||
@@ -493,7 +504,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
* @param ticketId
|
||||
* @return
|
||||
*/
|
||||
private GitHubIssue findTicket(String repositoryName, String ticketId) {
|
||||
private GitHubReadIssue findTicket(String repositoryName, String ticketId) {
|
||||
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
@@ -503,7 +514,6 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
return operations.exchange(ISSUE_BY_ID_URI_TEMPLATE, HttpMethod.GET,
|
||||
new HttpEntity<>(new HttpHeaders()), ISSUE_TYPE, parameters).getBody();
|
||||
|
||||
} catch (HttpStatusCodeException e) {
|
||||
|
||||
if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
@@ -522,7 +532,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
|
||||
logger.log(module, "Preparing GitHub Release …");
|
||||
|
||||
List<GitHubIssue> gitHubIssues = findGitHubIssues(module, ticketReferences);
|
||||
List<GitHubReadIssue> gitHubIssues = findGitHubIssues(module, ticketReferences);
|
||||
|
||||
ArtifactVersion version = ArtifactVersion.of(module);
|
||||
DocumentationMetadata documentation = DocumentationMetadata.of(module.getProject(), version);
|
||||
@@ -608,7 +618,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
parameters);
|
||||
}
|
||||
|
||||
private Stream<GitHubIssue> getIssuesFor(ModuleIteration moduleIteration, boolean forCurrentUser,
|
||||
private Stream<GitHubReadIssue> getIssuesFor(ModuleIteration moduleIteration, boolean forCurrentUser,
|
||||
boolean ignoreMissingMilestone) {
|
||||
|
||||
String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName();
|
||||
@@ -619,7 +629,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
GitHubIssue.Milestone milestone = optionalMilestone.orElseThrow(() -> noSuchMilestone(moduleIteration));
|
||||
Milestone milestone = optionalMilestone.orElseThrow(() -> noSuchMilestone(moduleIteration));
|
||||
|
||||
Map<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("repoName", repositoryName);
|
||||
@@ -634,9 +644,9 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
return getForIssues(ISSUES_BY_MILESTONE_URI_TEMPLATE, parameters);
|
||||
}
|
||||
|
||||
private Stream<GitHubIssue> getForIssues(String template, Map<String, Object> parameters) {
|
||||
private Stream<GitHubReadIssue> getForIssues(String template, Map<String, Object> parameters) {
|
||||
|
||||
List<GitHubIssue> issues = new ArrayList<>();
|
||||
List<GitHubReadIssue> issues = new ArrayList<>();
|
||||
doWithPaging(template, HttpMethod.GET, parameters, new HttpEntity<>(new HttpHeaders()), ISSUES_TYPE,
|
||||
tickets -> {
|
||||
issues.addAll(tickets);
|
||||
@@ -661,7 +671,7 @@ class GitHub extends GitHubSupport implements IssueTracker {
|
||||
}
|
||||
|
||||
private static Ticket toTicket(GitHubIssue issue) {
|
||||
return new Ticket(issue.getId(), issue.getTitle(), issue.getHtmlUrl(), new GithubTicketStatus(issue.getState()));
|
||||
return new Ticket(issue.getId(), issue.getTitle(), issue.getUrl(), new GithubTicketStatus(issue.getState()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
* Copyright 2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -15,100 +15,24 @@
|
||||
*/
|
||||
package org.springframework.data.release.issues.github;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Value
|
||||
class GitHubIssue implements Comparable<GitHubIssue> {
|
||||
public interface GitHubIssue {
|
||||
|
||||
String number, title, state, url;
|
||||
GitHubUser user;
|
||||
List<Object> assignees;
|
||||
String htmlUrl;
|
||||
Object milestone;
|
||||
PullRequest pullRequest;
|
||||
List<Label> labels;
|
||||
String getNumber();
|
||||
|
||||
public GitHubIssue(String number, String title, String state, String url, GitHubUser user, List<Object> assignees,
|
||||
@JsonProperty("html_url") String htmlUrl, Object milestone, @JsonProperty("pull_request") PullRequest pullRequest,
|
||||
List<Label> labels) {
|
||||
this.number = number;
|
||||
this.title = title;
|
||||
this.state = state;
|
||||
this.url = url;
|
||||
this.user = user;
|
||||
this.assignees = assignees;
|
||||
this.htmlUrl = htmlUrl;
|
||||
this.milestone = milestone;
|
||||
this.pullRequest = pullRequest;
|
||||
this.labels = labels;
|
||||
default String getId() {
|
||||
return getNumber() == null ? null : "#".concat(getNumber());
|
||||
}
|
||||
|
||||
public static GitHubIssue of(String title, Milestone milestone) {
|
||||
return new GitHubIssue(null, title, null, null, null, null, null, milestone.number, null, null);
|
||||
}
|
||||
String getTitle();
|
||||
|
||||
public static GitHubIssue assignedTo(String username) {
|
||||
|
||||
Assert.hasText(username, "Username must not be null or empty!");
|
||||
return new GitHubIssue(null, null, null, null, null, Collections.singletonList(username), null, null, null, null);
|
||||
}
|
||||
|
||||
public GitHubIssue close() {
|
||||
return new GitHubIssue(this.number, this.title, "closed", null, null, this.assignees, null, this.milestone, null,
|
||||
null);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return number == null ? null : "#".concat(number);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GitHubIssue o) {
|
||||
|
||||
int number = this.number != null ? Integer.parseInt(this.number) : -1;
|
||||
int other = o.number != null ? Integer.parseInt(o.number) : -1;
|
||||
|
||||
return Integer.compare(number, other);
|
||||
}
|
||||
String getState();
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
* @return HTML URL.
|
||||
*/
|
||||
@Value
|
||||
static class Milestone {
|
||||
String getUrl();
|
||||
|
||||
Long number;
|
||||
String title, description, state;
|
||||
|
||||
public static Milestone of(String title, String description) {
|
||||
return new Milestone(null, title, description, null);
|
||||
}
|
||||
|
||||
public boolean matches(ModuleIteration moduleIteration) {
|
||||
return title.contains(moduleIteration.getShortVersionString());
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isOpen() {
|
||||
return "open".equals(state);
|
||||
}
|
||||
|
||||
public Milestone markReleased() {
|
||||
return new Milestone(number, null, null, "closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.data.release.issues.github;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import org.springframework.data.release.issues.github.GitHubIssue.Milestone;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.issues.github;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Read-representation of a GitHub issue.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Value
|
||||
class GitHubReadIssue implements Comparable<GitHubReadIssue>, GitHubIssue {
|
||||
|
||||
String number, title, state, url;
|
||||
GitHubUser user;
|
||||
List<GitHubUser> assignees;
|
||||
Milestone milestone;
|
||||
PullRequest pullRequest;
|
||||
List<Label> labels;
|
||||
|
||||
public GitHubReadIssue(String number, String title, String state, @JsonProperty("html_url") String url,
|
||||
GitHubUser user, List<GitHubUser> assignees, Milestone milestone,
|
||||
@JsonProperty("pull_request") PullRequest pullRequest, List<Label> labels) {
|
||||
this.number = number;
|
||||
this.title = title;
|
||||
this.state = state;
|
||||
this.url = url;
|
||||
this.user = user;
|
||||
this.assignees = assignees;
|
||||
this.milestone = milestone;
|
||||
this.pullRequest = pullRequest;
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GitHubReadIssue o) {
|
||||
|
||||
int number = this.number != null ? Integer.parseInt(this.number) : -1;
|
||||
int other = o.number != null ? Integer.parseInt(o.number) : -1;
|
||||
|
||||
return Integer.compare(number, other);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014-2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.issues.github;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Value
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@With
|
||||
class GitHubWriteIssue implements GitHubIssue {
|
||||
|
||||
String number, title, state;
|
||||
List<Object> assignees;
|
||||
Long milestone;
|
||||
List<String> labels;
|
||||
|
||||
@Override
|
||||
public String getUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static GitHubWriteIssue of(String title, Milestone milestone) {
|
||||
return new GitHubWriteIssue(null, title, null, null, milestone.getNumber(), null);
|
||||
}
|
||||
|
||||
public static GitHubWriteIssue assignedTo(String username) {
|
||||
|
||||
Assert.hasText(username, "Username must not be null or empty!");
|
||||
return new GitHubWriteIssue(null, null, null, Collections.singletonList(username), null, null);
|
||||
}
|
||||
|
||||
public GitHubWriteIssue close() {
|
||||
return new GitHubWriteIssue(this.number, this.title, "closed", this.assignees, null, null);
|
||||
}
|
||||
|
||||
public GitHubWriteIssue withLabel(String labelName) {
|
||||
|
||||
List<String> labels = new ArrayList<>(this.labels == null ? Collections.emptyList() : this.labels);
|
||||
labels.add(labelName);
|
||||
|
||||
return withLabels(labels);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,12 @@ import org.springframework.data.util.Streamable;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class LabelConfiguration implements Streamable<Label> {
|
||||
class LabelConfiguration implements Streamable<Label> {
|
||||
|
||||
public static final Label TYPE_DEPENDENCY_UPGRADE = LabelFactories.TYPE_LABEL.apply("dependency-upgrade",
|
||||
"A dependency upgrade");
|
||||
|
||||
public static final Label TYPE_TASK = LabelFactories.TYPE_LABEL.apply("task", "A general task");
|
||||
|
||||
private final Set<Label> labels;
|
||||
|
||||
@@ -131,11 +136,11 @@ public class LabelConfiguration implements Streamable<Label> {
|
||||
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "blocker", "An issue that is blocking us from releasing");
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "bug", "A general bug");
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "dependency-upgrade", "A dependency upgrade");
|
||||
configurer.register(TYPE_DEPENDENCY_UPGRADE);
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "documentation", "A documentation update");
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "enhancement", "A general enhancement");
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "regression", "A regression from a previous release");
|
||||
configurer.register(LabelFactories.TYPE_LABEL, "task", "A general task");
|
||||
configurer.register(TYPE_TASK);
|
||||
});
|
||||
|
||||
return configuration;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.issues.github;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Value
|
||||
class Milestone {
|
||||
|
||||
Long number;
|
||||
String title, description, state;
|
||||
|
||||
public static Milestone of(String title, String description) {
|
||||
return new Milestone(null, title, description, null);
|
||||
}
|
||||
|
||||
public boolean matches(ModuleIteration moduleIteration) {
|
||||
return title.contains(moduleIteration.getShortVersionString());
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isOpen() {
|
||||
return "open".equals(state);
|
||||
}
|
||||
|
||||
public Milestone markReleased() {
|
||||
return new Milestone(number, null, null, "closed");
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ class Jira implements JiraConnector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text) {
|
||||
public Ticket createTicket(ModuleIteration moduleIteration, String text, TicketType ticketType) {
|
||||
|
||||
Assert.notNull(moduleIteration, "ModuleIteration must not be null.");
|
||||
|
||||
|
||||
@@ -156,7 +156,8 @@ class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests {
|
||||
github.createReleaseTicket(BUILD_HOPPER_RC1);
|
||||
|
||||
verify(postRequestedFor(urlPathMatching(ISSUES_URI))
|
||||
.withRequestBody(equalToJson("{\"title\":\"Release 1.8 RC1 (Hopper)\",\"milestone\":45}")));
|
||||
.withRequestBody(
|
||||
equalToJson("{\"title\":\"Release 1.8 RC1 (Hopper)\",\"milestone\":45,\"labels\":[ \"type: task\" ]}")));
|
||||
}
|
||||
|
||||
@Test // #5
|
||||
|
||||
@@ -25,11 +25,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.json.JsonTest;
|
||||
import org.springframework.boot.test.json.JacksonTester;
|
||||
import org.springframework.data.release.issues.github.GitHubIssue.Milestone;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GitHubIssue}.
|
||||
* Unit tests for {@link GitHubWriteIssue}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user