Skip to content

Allow sections to filter entries by type (issues, pull requests, or both) #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* @author Phillip Webb
* @author Mahendra Bishnoi
* @author Gary Russell
* @author Steven Sheehy
*/
@ConfigurationProperties(prefix = "changelog")
@ConstructorBinding
Expand Down Expand Up @@ -142,11 +143,18 @@ public static class Section {
*/
private final Set<String> labels;

public Section(String title, @DefaultValue("default") String group, IssueSort sort, Set<String> labels) {
/**
* Whether issues, pull requests or both should be included in this section.
*/
private final IssueType type;

public Section(String title, @DefaultValue("default") String group, IssueSort sort, Set<String> labels,
@DefaultValue("ANY") IssueType type) {
this.title = title;
this.group = (group != null) ? group : "default";
this.sort = sort;
this.labels = labels;
this.type = type;
}

public String getTitle() {
Expand All @@ -165,6 +173,10 @@ public Set<String> getLabels() {
return this.labels;
}

public IssueType getType() {
return this.type;
}

}

/**
Expand Down Expand Up @@ -352,4 +364,26 @@ public enum IssueSort {

}

/**
* The type of changelog entry.
*/
public enum IssueType {

/**
* Either issue or pull requests.
*/
ANY,

/**
* GitHub issue.
*/
ISSUE,

/**
* GitHub pull request.
*/
PULL_REQUEST

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import org.springframework.util.CollectionUtils;

import io.spring.githubchangeloggenerator.ApplicationProperties.IssueSort;
import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType;
import io.spring.githubchangeloggenerator.github.payload.Issue;
import io.spring.githubchangeloggenerator.github.payload.Label;

/**
* A single section of a changelog report.
*
* @author Phillip Webb
* @author Steven Sheehy
*/
class ChangelogSection {

Expand All @@ -42,17 +44,20 @@ class ChangelogSection {

private final Set<String> labels;

private final IssueType type;

ChangelogSection(String title, String group, IssueSort sort, String... labels) {
this(title, group, sort, new LinkedHashSet<>(Arrays.asList(labels)));
this(title, group, sort, new LinkedHashSet<>(Arrays.asList(labels)), IssueType.ANY);
}

ChangelogSection(String title, String group, IssueSort sort, Set<String> labels) {
ChangelogSection(String title, String group, IssueSort sort, Set<String> labels, IssueType type) {
Assert.hasText(title, "Title must not be empty");
Assert.isTrue(!CollectionUtils.isEmpty(labels), "Labels must not be empty");
this.title = title;
this.group = group;
this.sort = sort;
this.labels = labels;
this.type = type;
}

String getGroup() {
Expand All @@ -67,7 +72,14 @@ boolean isMatchFor(Issue issue) {
for (String candidate : this.labels) {
for (Label label : issue.getLabels()) {
if (label.getName().contains(candidate)) {
return true;
switch (this.type) {
case ISSUE:
return issue.getPullRequest() == null;
case PULL_REQUEST:
return issue.getPullRequest() != null;
default:
return true;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
*
* @author Phillip Webb
* @author Gary Russell
* @author Steven Sheehy
*/
class ChangelogSections {

Expand Down Expand Up @@ -75,7 +76,7 @@ private List<ChangelogSection> adapt(ApplicationProperties properties) {

private ChangelogSection adapt(ApplicationProperties.Section propertySection) {
return new ChangelogSection(propertySection.getTitle(), propertySection.getGroup(), propertySection.getSort(),
propertySection.getLabels());
propertySection.getLabels(), propertySection.getType());
}

Map<ChangelogSection, List<Issue>> collate(List<Issue> issues) {
Expand All @@ -92,9 +93,9 @@ Map<ChangelogSection, List<Issue>> collate(List<Issue> issues) {

private List<ChangelogSection> getSections(Issue issue) {
List<ChangelogSection> result = new ArrayList<>();
Set<String> groupClaimes = new HashSet<>();
Set<String> groupClaims = new HashSet<>();
for (ChangelogSection section : this.sections) {
if (section.isMatchFor(issue) && groupClaimes.add(section.getGroup())) {
if (section.isMatchFor(issue) && groupClaims.add(section.getGroup())) {
result.add(section);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.core.io.ClassPathResource;

import io.spring.githubchangeloggenerator.ApplicationProperties.IssueSort;
import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType;
import io.spring.githubchangeloggenerator.ApplicationProperties.Section;
import io.spring.githubchangeloggenerator.github.service.Repository;

Expand All @@ -35,6 +36,7 @@
* Tests for {@link ApplicationProperties}.
*
* @author Phillip Webb
* @author Steven Sheehy
*/
class ApplicationPropertiesTests {

Expand All @@ -54,10 +56,12 @@ void loadYaml() throws Exception {
assertThat(sections.get(0).getLabels()).containsExactly("enhancement");
assertThat(sections.get(0).getGroup()).isEqualTo("default");
assertThat(sections.get(0).getSort()).isEqualTo(IssueSort.CREATED);
assertThat(sections.get(0).getType()).isEqualTo(IssueType.ISSUE);
assertThat(sections.get(1).getTitle()).isEqualTo("Bugs");
assertThat(sections.get(1).getLabels()).containsExactly("bug");
assertThat(sections.get(1).getGroup()).isEqualTo("test");
assertThat(sections.get(1).getSort()).isNull();
assertThat(sections.get(1).getType()).isEqualTo(IssueType.ANY);
assertThat(properties.getIssues().getExcludes().getLabels()).containsExactly("hide");
assertThat(properties.getIssues().getSort()).isEqualTo(IssueSort.TITLE);
assertThat(properties.getContributors().getTitle()).isEqualTo("Nice one!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import io.spring.githubchangeloggenerator.ApplicationProperties.ContributorsExclude;
import io.spring.githubchangeloggenerator.ApplicationProperties.ExternalLink;
import io.spring.githubchangeloggenerator.ApplicationProperties.IssueSort;
import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType;
import io.spring.githubchangeloggenerator.ApplicationProperties.Issues;
import io.spring.githubchangeloggenerator.ApplicationProperties.IssuesExclude;
import io.spring.githubchangeloggenerator.ApplicationProperties.PortedIssue;
Expand All @@ -61,6 +62,7 @@
* @author Phillip Webb
* @author Mahendra Bishnoi
* @author Gary Russell
* @author Steven Sheehy
*/
class ChangelogGeneratorTests {

Expand Down Expand Up @@ -297,7 +299,7 @@ void generateWhenEscapedMarkdownStylingIsInIssueTitleItIsNotEscapedAgain() throw
void generateWhenSectionSortedByTitle() throws Exception {
List<Section> sections = new ArrayList<>();
Set<String> labels = Collections.singleton("type: enhancement");
sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels));
sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels, IssueType.ANY));
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections,
new Issues(null, null, null), null, null, false);
this.generator = new ChangelogGenerator(this.service, properties);
Expand All @@ -313,7 +315,7 @@ void generateWhenSectionSortedByTitle() throws Exception {
void generateWhenAllIssuesSortedByTitle() throws Exception {
List<Section> sections = new ArrayList<>();
Set<String> labels = Collections.singleton("type: enhancement");
sections.add(new Section("Enhancements", null, null, labels));
sections.add(new Section("Enhancements", null, null, labels, IssueType.ANY));
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections,
new Issues(IssueSort.TITLE, null, null), null, null, false);
this.generator = new ChangelogGenerator(this.service, properties);
Expand Down Expand Up @@ -359,6 +361,42 @@ void generateWhenMultipleExternalLink() throws Exception {
assertChangelog("23").hasContent(from("output-with-multiple-external-link"));
}

@Test
void generateWhenIssuesOnly() throws Exception {
List<Section> sections = new ArrayList<>();
Set<String> labels = Collections.singleton("type: enhancement");
sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels, IssueType.ISSUE));
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections,
new Issues(null, null, null), null, null, false);
this.generator = new ChangelogGenerator(this.service, properties);
User contributor1 = createUser("contributor1");
List<Issue> issues = new ArrayList<>();
issues.add(newIssue("Issue 1", "1", "issue-1-url", Type.ENHANCEMENT));
issues.add(newIssue("Issue 2", "2", "issue-2-url", Type.ENHANCEMENT));
issues.add(newPullRequest("PR 3", "3", Type.ENHANCEMENT, "pr-3-url", contributor1));
issues.add(newPullRequest("PR 4", "4", Type.ENHANCEMENT, "pr-4-url", contributor1));
given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues);
assertChangelog("23").hasContent(from("output-with-issues-only"));
}

@Test
void generateWhenPullRequestsOnly() throws Exception {
List<Section> sections = new ArrayList<>();
Set<String> labels = Collections.singleton("type: enhancement");
sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels, IssueType.PULL_REQUEST));
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections,
new Issues(null, null, null), null, null, false);
this.generator = new ChangelogGenerator(this.service, properties);
User contributor1 = createUser("contributor1");
List<Issue> issues = new ArrayList<>();
issues.add(newIssue("Issue 1", "1", "issue-1-url", Type.ENHANCEMENT));
issues.add(newIssue("Issue 2", "2", "issue-2-url", Type.ENHANCEMENT));
issues.add(newPullRequest("PR 3", "3", Type.ENHANCEMENT, "pr-3-url", contributor1));
issues.add(newPullRequest("PR 4", "4", Type.ENHANCEMENT, "pr-4-url", contributor1));
given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues);
assertChangelog("23").hasContent(from("output-with-pull-requests-only"));
}

private void setupGenerator(MilestoneReference id) {
Set<String> labels = new HashSet<>(Arrays.asList("duplicate", "wontfix"));
PortedIssue forwardPort = new PortedIssue("status: forward-port", "Forward port of issue #(\\d+)");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import org.junit.jupiter.api.Test;

import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType;
import io.spring.githubchangeloggenerator.github.payload.Issue;
import io.spring.githubchangeloggenerator.github.payload.Label;
import io.spring.githubchangeloggenerator.github.service.Repository;
Expand All @@ -37,6 +38,7 @@
* @author Eleftheria Stein
* @author Phillip Webb
* @author Gary Russell
* @author Steven Sheehy
*/
class ChangelogSectionsTests {

Expand Down Expand Up @@ -65,9 +67,9 @@ void collateWhenNoCustomSectionsUsesDefaultSections() {
@Test
void collateWhenHasCustomSectionsUsesDefinedSections() {
ApplicationProperties.Section breaksPassivitySection = new ApplicationProperties.Section(":rewind: Non-passive",
null, null, Collections.singleton("breaks-passivity"));
null, null, Collections.singleton("breaks-passivity"), IssueType.ANY);
ApplicationProperties.Section bugsSection = new ApplicationProperties.Section(":lady_beetle: Bug Fixes", null,
null, Collections.singleton("bug"));
null, Collections.singleton("bug"), IssueType.ANY);
List<ApplicationProperties.Section> customSections = Arrays.asList(breaksPassivitySection, bugsSection);
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
null, null, null, false);
Expand All @@ -82,7 +84,7 @@ void collateWhenHasCustomSectionsUsesDefinedSections() {
@Test
void collateWhenHasCustomSectionsUsesDefinedSectionsAndDefault() {
ApplicationProperties.Section breaksPassivitySection = new ApplicationProperties.Section(":rewind: Non-passive",
null, null, Collections.singleton("breaks-passivity"));
null, null, Collections.singleton("breaks-passivity"), IssueType.ANY);
List<ApplicationProperties.Section> customSections = Arrays.asList(breaksPassivitySection);
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
null, null, null, true);
Expand Down Expand Up @@ -124,9 +126,9 @@ void collateWithDefaultsDoesNotAddIssueToMultipleSections() {
Issue highlight = createIssue("2", "highlight");
Issue bugAndHighlight = createIssue("3", "bug", "highlight");
ApplicationProperties.Section bugs = new ApplicationProperties.Section("Bugs", null, null,
Collections.singleton("bug"));
Collections.singleton("bug"), IssueType.ANY);
ApplicationProperties.Section highlights = new ApplicationProperties.Section("Highlights", null, null,
Collections.singleton("highlight"));
Collections.singleton("highlight"), IssueType.ANY);
List<ApplicationProperties.Section> customSections = Arrays.asList(bugs, highlights);
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
null, null, null, false);
Expand All @@ -144,9 +146,9 @@ void collateWithGroupsAddsIssuePerGroup() {
Issue highlight = createIssue("2", "highlight");
Issue bugAndHighlight = createIssue("3", "bug", "highlight");
ApplicationProperties.Section bugs = new ApplicationProperties.Section("Bugs", null, null,
Collections.singleton("bug"));
Collections.singleton("bug"), IssueType.ANY);
ApplicationProperties.Section highlights = new ApplicationProperties.Section("Highlights", "highlights", null,
Collections.singleton("highlight"));
Collections.singleton("highlight"), IssueType.ANY);
List<ApplicationProperties.Section> customSections = Arrays.asList(bugs, highlights);
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
null, null, null, false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Enhancements

- Issue 1 [#1](issue-1-url)
- Issue 2 [#2](issue-2-url)

## :heart: Contributors

Thank you to all the contributors who worked on this release:

@contributor1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Enhancements

- PR 3 [#3](pr-3-url)
- PR 4 [#4](pr-4-url)

## :heart: Contributors

Thank you to all the contributors who worked on this release:

@contributor1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ changelog:
- title: ":star: New Features"
labels: ["enhancement"]
sort: "created"
type: ISSUE
- title: "Bugs"
labels: ["bug"]
group: "test"
Expand Down