#162 - Attach label/component to IssueTracker.createTicket(…).

This commit is contained in:
Mark Paluch
2020-11-23 08:50:26 +01:00
parent e1f220fe25
commit 2777a349bc
17 changed files with 268 additions and 141 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)) {

View File

@@ -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) {

View File

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

View File

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

View File

@@ -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;
/**

View File

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

View File

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

View File

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

View File

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

View File

@@ -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.");

View File

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

View File

@@ -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
*/