diff --git a/src/main/java/org/springframework/data/release/git/GitCommands.java b/src/main/java/org/springframework/data/release/git/GitCommands.java index fda32d1..310288f 100644 --- a/src/main/java/org/springframework/data/release/git/GitCommands.java +++ b/src/main/java/org/springframework/data/release/git/GitCommands.java @@ -114,12 +114,12 @@ class GitCommands extends TimedCommand { private Tickets toTickets(ModuleIteration module, List ticketReferences) { - // TODO: Use only associated tracker - List tickets = new ArrayList<>(); + IssueTracker issueTracker = trackers.getRequiredPluginFor(module.getProject(), + () -> String.format("No issue tracker found for project %s!", module.getProject())); - for (IssueTracker tracker : trackers) { - tickets.addAll(tracker.findTickets(module, ticketReferences).getTickets()); - } + List ticketIds = ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList()); + + List tickets = new ArrayList<>(issueTracker.findTickets(module, ticketIds).getTickets()); return new Tickets(tickets); } diff --git a/src/main/java/org/springframework/data/release/issues/IssueTracker.java b/src/main/java/org/springframework/data/release/issues/IssueTracker.java index b049b93..17e9cd7 100644 --- a/src/main/java/org/springframework/data/release/issues/IssueTracker.java +++ b/src/main/java/org/springframework/data/release/issues/IssueTracker.java @@ -17,6 +17,7 @@ package org.springframework.data.release.issues; import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; @@ -81,6 +82,17 @@ public interface IssueTracker extends Plugin { */ Collection findTickets(Project project, Collection ticketIds); + /** + * Query the issue tracker for multiple {@link Ticket#id ticket Ids}. Tickets that are not found are not returned. The + * implementation ensures to resolve only references that match the issue tracker scheme this issue tracker is + * responsible for. + * + * @param moduleIteration must not be {@literal null}. + * @param ticketReferences must not be {@literal null}. + * @return + */ + Tickets findTickets(ModuleIteration moduleIteration, Collection ticketIds); + /** * Creates a release version if release version is missing. * @@ -155,7 +167,8 @@ public interface IssueTracker extends Plugin { */ default Changelog getChangelogFor(ModuleIteration module, List ticketReferences) { - Tickets tickets = findTickets(module, ticketReferences); + Tickets tickets = findTickets(module, + ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList())); return Changelog.of(module, tickets); } @@ -174,17 +187,6 @@ public interface IssueTracker extends Plugin { */ void closeTicket(ModuleIteration module, Ticket ticket); - /** - * Resolve a {@link List} of {@link TicketReference}s to {@link Tickets} for a given {@link ModuleIteration}. The - * implementation ensures to resolve only references that match the issue tracker scheme this issue tracker is - * responsible for. - * - * @param moduleIteration must not be {@literal null}. - * @param ticketReferences must not be {@literal null}. - * @return - */ - Tickets findTickets(ModuleIteration moduleIteration, List ticketReferences); - enum TicketType { Task, DependencyUpgrade; } diff --git a/src/main/java/org/springframework/data/release/issues/github/GitHub.java b/src/main/java/org/springframework/data/release/issues/github/GitHub.java index 0e3d6cc..c514b66 100644 --- a/src/main/java/org/springframework/data/release/issues/github/GitHub.java +++ b/src/main/java/org/springframework/data/release/issues/github/GitHub.java @@ -40,13 +40,13 @@ import org.springframework.data.release.git.VersionTags; import org.springframework.data.release.issues.Changelog; 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.model.ArtifactVersion; import org.springframework.data.release.model.DocumentationMetadata; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; +import org.springframework.data.release.model.Projects; import org.springframework.data.release.model.Tracker; import org.springframework.data.release.model.TrainIteration; import org.springframework.data.release.utils.ExecutionUtils; @@ -147,6 +147,13 @@ class GitHub extends GitHubSupport implements IssueTracker { return tickets; } + @Override + public Tickets findTickets(ModuleIteration moduleIteration, Collection ticketIds) { + + return findGitHubIssues(moduleIteration, ticketIds).stream().map(GitHub::toTicket) + .collect(Tickets.toTicketsCollector()); + } + /* * (non-Javadoc) * @see org.springframework.data.release.jira.IssueTracker#getChangelogFor(org.springframework.data.release.model.ModuleIteration) @@ -464,14 +471,7 @@ class GitHub extends GitHubSupport implements IssueTracker { close(module, ticket); } - @Override - public Tickets findTickets(ModuleIteration moduleIteration, List ticketReferences) { - - return findGitHubIssues(moduleIteration, ticketReferences).stream().map(GitHub::toTicket) - .collect(Tickets.toTicketsCollector()); - } - - List findGitHubIssues(ModuleIteration moduleIteration, List ticketReferences) { + List findGitHubIssues(ModuleIteration moduleIteration, Collection ticketIds) { logger.log(moduleIteration, "Looking up GitHub issues from milestone …"); @@ -480,9 +480,9 @@ class GitHub extends GitHubSupport implements IssueTracker { String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName(); - logger.log(moduleIteration, "Resolving GitHub issues …"); + logger.log(moduleIteration, "Looking up GitHub issues …"); Collection foundIssues = ExecutionUtils.runAndReturn(executorService, - Streamable.of(() -> ticketReferences.stream().filter(it -> it.getId().startsWith("#"))), + Streamable.of(() -> ticketIds.stream().filter(it -> it.startsWith("#"))), ticketReference -> getTicket(issues, repositoryName, ticketReference)); List gitHubIssues = foundIssues.stream().filter(it -> { @@ -490,19 +490,19 @@ class GitHub extends GitHubSupport implements IssueTracker { return !ticket.isReleaseTicketFor(moduleIteration) && !ticket.isReleaseTicket(); }).collect(Collectors.toList()); - logger.log(moduleIteration, "Resolved %s tickets.", gitHubIssues.size()); + logger.log(moduleIteration, "Found %s tickets.", gitHubIssues.size()); return gitHubIssues; } private GitHubReadIssue getTicket(Map cache, String repositoryName, - TicketReference reference) { + String ticketId) { - if (cache.containsKey(reference.getId())) { - return cache.get(reference.getId()); + if (cache.containsKey(ticketId)) { + return cache.get(ticketId); } - return findTicket(repositoryName, reference.getId()); + return findTicket(repositoryName, ticketId); } private Tickets getTicketsFor(ModuleIteration moduleIteration, boolean forCurrentUser) { @@ -541,11 +541,11 @@ class GitHub extends GitHubSupport implements IssueTracker { * @param module * @param ticketReferences */ - public void createOrUpdateRelease(ModuleIteration module, List ticketReferences) { + public void createOrUpdateRelease(ModuleIteration module, List ticketIds) { logger.log(module, "Preparing GitHub Release …"); - List gitHubIssues = findGitHubIssues(module, ticketReferences); + List gitHubIssues = findGitHubIssues(module, ticketIds); ArtifactVersion version = ArtifactVersion.of(module); DocumentationMetadata documentation = DocumentationMetadata.of(module.getProject(), version); @@ -554,7 +554,13 @@ class GitHub extends GitHubSupport implements IssueTracker { String releaseBody = generator.generate(gitHubIssues, (changelogSection, s) -> s); String documentationLinks = getDocumentationLinks(module, documentation); - createOrUpdateRelease(module, String.format("## :green_book: Links%n%s%n%s%n", documentationLinks, releaseBody)); + if (module.getProject() == Projects.BOM || module.getProject() == Projects.BUILD) { + // We don't ship Javadoc/reference doc for build and BOM + createOrUpdateRelease(module, String.format("%s%n", documentationLinks, releaseBody)); + } else { + createOrUpdateRelease(module, String.format("## :green_book: Links%n%s%n%s%n", documentationLinks, releaseBody)); + } + logger.log(module, "GitHub Release up to date"); } diff --git a/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java b/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java index 4efc8ff..a65c4a8 100644 --- a/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java +++ b/src/main/java/org/springframework/data/release/issues/github/GitHubCommands.java @@ -22,6 +22,7 @@ import lombok.experimental.FieldDefaults; import java.util.List; import java.util.concurrent.Executor; +import java.util.stream.Collectors; import org.springframework.data.release.CliComponent; import org.springframework.data.release.TimedCommand; @@ -63,11 +64,11 @@ class GitHubCommands extends TimedCommand { git.push(iteration); git.pushTags(iteration.getTrain()); - createOrUpdateLabels(iteration); + createOrUpdateRelease(iteration); } @CliCommand(value = "github create release") - public void createOrUpdateLabels(@CliOption(key = "", mandatory = true) TrainIteration iteration) { + public void createOrUpdateRelease(@CliOption(key = "", mandatory = true) TrainIteration iteration) { TrainIteration previousIteration = git.getPreviousIteration(iteration); @@ -75,8 +76,8 @@ class GitHubCommands extends TimedCommand { if (it.getProject().getTracker() == Tracker.GITHUB) { - List ticketReferences = git.getTicketReferencesBetween(it.getProject(), previousIteration, - iteration); + List ticketReferences = git.getTicketReferencesBetween(it.getProject(), previousIteration, iteration) + .stream().map(TicketReference::getId).collect(Collectors.toList()); gitHub.createOrUpdateRelease(it, ticketReferences); } }); diff --git a/src/main/java/org/springframework/data/release/issues/jira/Jira.java b/src/main/java/org/springframework/data/release/issues/jira/Jira.java index ade61ce..7864036 100644 --- a/src/main/java/org/springframework/data/release/issues/jira/Jira.java +++ b/src/main/java/org/springframework/data/release/issues/jira/Jira.java @@ -31,7 +31,6 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.release.issues.Changelog; 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.jira.JiraIssue.Fields; import org.springframework.data.release.issues.jira.JiraIssue.Resolution; @@ -137,6 +136,8 @@ class Jira implements JiraConnector { return Collections.emptyList(); } + logger.log(project, "Retrieving up JIRA issues…"); + JqlQuery query = JqlQuery.from(ticketIds).and(" resolution is not EMPTY"); Map parameters = newUrlTemplateVariables(); @@ -147,11 +148,40 @@ class Jira implements JiraConnector { JiraIssues issues = operations.exchange(SEARCH_TEMPLATE, HttpMethod.GET, null, JiraIssues.class, parameters) .getBody(); + logger.log(project, "Found %s tickets.", issues.getIssues().size()); + return issues.stream().// map(this::toTicket).// collect(Collectors.toList()); } + @Override + public Tickets findTickets(ModuleIteration moduleIteration, Collection ticketIds) { + + List ids = ticketIds.stream().filter(it -> it.startsWith(moduleIteration.getProjectKey().getKey())) + .collect(Collectors.toList()); + + if (ids.isEmpty()) { + return new Tickets(Collections.emptyList()); + } + + Map parameters = newUrlTemplateVariables(); + parameters.put("jql", JqlQuery.from(ids)); + parameters.put("fields", "summary,status,resolution,fixVersions"); + parameters.put("startAt", 0); + + logger.log(moduleIteration, "Retrieving up JIRA issues…"); + + JiraIssues issues = operations.getForObject(SEARCH_TEMPLATE, JiraIssues.class, parameters); + Tickets tickets = issues.stream().map(this::toTicket).filter(it -> { + return it.isReleaseTicketFor(moduleIteration) || !it.isReleaseTicket(); + }).collect(Tickets.toTicketsCollector()); + + logger.log(moduleIteration, "Found %s tickets.", tickets.getOverallTotal()); + + return tickets; + } + /* * (non-Javadoc) * @see org.springframework.data.release.jira.IssueTracker#getTicketsFor(org.springframework.data.release.model.TrainIteration) @@ -586,34 +616,6 @@ class Jira implements JiraConnector { return project.uses(Tracker.JIRA); } - @Override - public Tickets findTickets(ModuleIteration moduleIteration, List ticketReferences) { - - List ids = ticketReferences.stream() - .filter(it -> it.getId().startsWith(moduleIteration.getProjectKey().getKey())).map(TicketReference::getId) - .collect(Collectors.toList()); - - if (ids.isEmpty()) { - return new Tickets(Collections.emptyList()); - } - - Map parameters = newUrlTemplateVariables(); - parameters.put("jql", JqlQuery.from(ids)); - parameters.put("fields", "summary,status,resolution,fixVersions"); - parameters.put("startAt", 0); - - logger.log(moduleIteration, "Resolving JIRA issues…"); - - JiraIssues issues = operations.getForObject(SEARCH_TEMPLATE, JiraIssues.class, parameters); - Tickets tickets = issues.stream().map(this::toTicket).filter(it -> { - return it.isReleaseTicketFor(moduleIteration) || !it.isReleaseTicket(); - }).collect(Tickets.toTicketsCollector()); - - logger.log(moduleIteration, "Resolved %s tickets.", tickets.getOverallTotal()); - - return tickets; - } - protected JiraComponents getJiraComponents(ProjectKey projectKey) { HttpHeaders headers = new HttpHeaders(); diff --git a/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java b/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java index 48aceba..4d57508 100644 --- a/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java +++ b/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; import org.springframework.data.release.git.GitOperations; import org.springframework.data.release.io.Workspace; @@ -118,15 +119,10 @@ public class ReleaseOperations { protected Changelog getChangelog(TrainIteration iteration, TrainIteration previousIteration, ModuleIteration module, IssueTracker issueTracker) { - List ticketReferences = git.getTicketReferencesBetween(module.getProject(), previousIteration, - iteration); + List ticketIds = git.getTicketReferencesBetween(module.getProject(), previousIteration, iteration).stream() + .map(TicketReference::getId).collect(Collectors.toList()); - // TODO: Use only associated tracker - List tickets = new ArrayList<>(); - - for (IssueTracker tracker : trackers) { - tickets.addAll(tracker.findTickets(module, ticketReferences).getTickets()); - } + List tickets = new ArrayList<>(issueTracker.findTickets(module, ticketIds).getTickets()); return Changelog.of(module, new Tickets(tickets)); } diff --git a/src/test/java/org/springframework/data/release/misc/ReleaseOperationsIntegrationTests.java b/src/test/java/org/springframework/data/release/misc/ReleaseOperationsIntegrationTests.java index 0b4a323..498b43e 100644 --- a/src/test/java/org/springframework/data/release/misc/ReleaseOperationsIntegrationTests.java +++ b/src/test/java/org/springframework/data/release/misc/ReleaseOperationsIntegrationTests.java @@ -18,6 +18,7 @@ package org.springframework.data.release.misc; import static org.assertj.core.api.Assertions.*; import java.util.List; +import java.util.stream.Collectors; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -56,7 +57,8 @@ class ReleaseOperationsIntegrationTests extends AbstractIntegrationTests { List ticketReferences = gitOperations.getTicketReferencesBetween(Projects.MONGO_DB, from, to); IssueTracker tracker = trackers.getRequiredPluginFor(Projects.MONGO_DB); - Tickets tickets = tracker.findTickets(to.getModule(Projects.MONGO_DB), ticketReferences); + Tickets tickets = tracker.findTickets(to.getModule(Projects.MONGO_DB), + ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList())); assertThat(tickets).hasSize(15); } @@ -70,7 +72,8 @@ class ReleaseOperationsIntegrationTests extends AbstractIntegrationTests { List ticketReferences = gitOperations.getTicketReferencesBetween(Projects.R2DBC, from, to); IssueTracker tracker = trackers.getRequiredPluginFor(Projects.R2DBC); - Tickets tickets = tracker.findTickets(to.getModule(Projects.R2DBC), ticketReferences); + Tickets tickets = tracker.findTickets(to.getModule(Projects.R2DBC), + ticketReferences.stream().map(TicketReference::getId).collect(Collectors.toList())); assertThat(tickets).hasSize(22); }