Skip to content

Commit

Permalink
feat: hide issues closed as unplanned with no linked PRs
Browse files Browse the repository at this point in the history
Signed-off-by: Keith Zantow <[email protected]>
  • Loading branch information
kzantow committed Jan 24, 2023
1 parent 2b4b6b1 commit 76b422a
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 41 deletions.
56 changes: 39 additions & 17 deletions chronicle/release/releasers/github/gh_issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package github
import (
"context"
"os"
"strings"
"time"

"github.com/shurcooL/githubv4"
Expand All @@ -13,13 +14,14 @@ import (
)

type ghIssue struct {
Title string
Number int
Author string
ClosedAt time.Time
Closed bool
Labels []string
URL string
Title string
Number int
Author string
ClosedAt time.Time
Closed bool
NotPlanned bool
Labels []string
URL string
}

type issueFilter func(issue ghIssue) bool
Expand Down Expand Up @@ -117,6 +119,24 @@ func issuesWithoutLabel(labels ...string) issueFilter {
}
}

func excludeIssuesNotPlanned(allMergedPRs []ghPullRequest) issueFilter {
return func(issue ghIssue) bool {
if issue.NotPlanned {
for _, pr := range allMergedPRs {
for _, linkedIssue := range pr.LinkedIssues {
if linkedIssue.URL == issue.URL {
log.Tracef("issue #%d included: is closed as not planned but has linked PRs", issue.Number)
return true
}
}
}
log.Tracef("issue #%d filtered out: as not planned", issue.Number)
return false
}
return true
}
}

// nolint:funlen
func fetchClosedIssues(user, repo string) ([]ghIssue, error) {
src := oauth2.StaticTokenSource(
Expand Down Expand Up @@ -153,9 +173,10 @@ func fetchClosedIssues(user, repo string) ([]ghIssue, error) {
Author struct {
Login githubv4.String
}
Closed githubv4.Boolean
ClosedAt githubv4.DateTime
Labels struct {
Closed githubv4.Boolean
ClosedAt githubv4.DateTime
StateReason githubv4.String
Labels struct {
Edges []struct {
Node struct {
Name githubv4.String
Expand Down Expand Up @@ -189,13 +210,14 @@ func fetchClosedIssues(user, repo string) ([]ghIssue, error) {
labels = append(labels, string(lEdge.Node.Name))
}
allIssues = append(allIssues, ghIssue{
Title: string(iEdge.Node.Title),
Author: string(iEdge.Node.Author.Login),
ClosedAt: iEdge.Node.ClosedAt.Time,
Closed: bool(iEdge.Node.Closed),
Labels: labels,
URL: string(iEdge.Node.URL),
Number: int(iEdge.Node.Number),
Title: string(iEdge.Node.Title),
Author: string(iEdge.Node.Author.Login),
ClosedAt: iEdge.Node.ClosedAt.Time,
Closed: bool(iEdge.Node.Closed),
Labels: labels,
URL: string(iEdge.Node.URL),
Number: int(iEdge.Node.Number),
NotPlanned: strings.EqualFold("NOT_PLANNED", string(iEdge.Node.StateReason)),
})
}

Expand Down
83 changes: 83 additions & 0 deletions chronicle/release/releasers/github/gh_issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,86 @@ func Test_issuesWithoutLabel(t *testing.T) {
})
}
}

func Test_excludeIssuesNotPlanned(t *testing.T) {
issue1 := ghIssue{
Title: "Issue 1",
Number: 1,
URL: "issue-1-url",
Closed: true,
NotPlanned: true,
}

issue2 := ghIssue{
Title: "Issue 2",
Number: 2,
URL: "issue-2-url",
}

issue3 := ghIssue{
Title: "Issue 3 no links",
Number: 3,
URL: "issue-3-url",
Closed: true,
NotPlanned: true,
}

prWithLinkedIssues1 := ghPullRequest{
Title: "pr 1 with linked issues",
Number: 1,
LinkedIssues: []ghIssue{
issue1,
},
}

prWithLinkedIssues2 := ghPullRequest{
Title: "pr 2 with linked issues",
Number: 2,
Author: "some-author-2",
URL: "some-url-2",
LinkedIssues: []ghIssue{
issue2,
},
}

prWithoutLinkedIssues1 := ghPullRequest{
Title: "pr 3 without linked issues",
Number: 3,
Author: "some-author",
URL: "some-url",
}

tests := []struct {
name string
config Config
prs []ghPullRequest
issues []ghIssue
expected []ghIssue
}{
{
name: "includes author for issues",
config: Config{},
prs: []ghPullRequest{
prWithLinkedIssues1,
prWithLinkedIssues2,
prWithoutLinkedIssues1,
},
issues: []ghIssue{
issue1,
issue2,
issue3,
},
expected: []ghIssue{
issue1,
issue2,
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
filtered := filterIssues(test.issues, excludeIssuesNotPlanned(test.prs))
assert.Equal(t, test.expected, filtered)
})
}
}
21 changes: 13 additions & 8 deletions chronicle/release/releasers/github/summarizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ const (
var _ release.Summarizer = (*Summarizer)(nil)

type Config struct {
Host string
IncludeIssuePRAuthors bool
IncludeIssues bool
IncludePRs bool
ExcludeLabels []string
ChangeTypesByLabel change.TypeSet
IssuesRequireLinkedPR bool
ConsiderPRMergeCommits bool
Host string
IncludeIssuePRAuthors bool
IncludeIssues bool
IncludeIssuesClosedAsNotPlanned bool
IncludePRs bool
ExcludeLabels []string
ChangeTypesByLabel change.TypeSet
IssuesRequireLinkedPR bool
ConsiderPRMergeCommits bool
}

type Summarizer struct {
Expand Down Expand Up @@ -170,6 +171,10 @@ func (s *Summarizer) Changes(sinceRef, untilRef string) ([]change.Change, error)
return nil, err
}

if !s.config.IncludeIssuesClosedAsNotPlanned {
allClosedIssues = filterIssues(allClosedIssues, excludeIssuesNotPlanned(allMergedPRs))
}

log.Debugf("total closed issues discovered: %d", len(allClosedIssues))

changes = append(changes, changesFromIssues(s.config, allMergedPRs, allClosedIssues, sinceTag, untilTag)...)
Expand Down
35 changes: 19 additions & 16 deletions internal/config/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import (
)

type githubSummarizer struct {
Host string `yaml:"host" json:"host" mapstructure:"host"`
ExcludeLabels []string `yaml:"exclude-labels" json:"exclude-labels" mapstructure:"exclude-labels"`
IncludeIssuePRAuthors bool `yaml:"include-issue-pr-authors" json:"include-issue-pr-authors" mapstructure:"include-issue-pr-authors"`
IncludePRs bool `yaml:"include-prs" json:"include-prs" mapstructure:"include-prs"`
IncludeIssues bool `yaml:"include-issues" json:"include-issues" mapstructure:"include-issues"`
IssuesRequireLinkedPR bool `yaml:"issues-require-linked-prs" json:"issues-require-linked-prs" mapstructure:"issues-require-linked-prs"`
ConsiderPRMergeCommits bool `yaml:"consider-pr-merge-commits" json:"consider-pr-merge-commits" mapstructure:"consider-pr-merge-commits"`
Changes []githubChange `yaml:"changes" json:"changes" mapstructure:"changes"`
Host string `yaml:"host" json:"host" mapstructure:"host"`
ExcludeLabels []string `yaml:"exclude-labels" json:"exclude-labels" mapstructure:"exclude-labels"`
IncludeIssuePRAuthors bool `yaml:"include-issue-pr-authors" json:"include-issue-pr-authors" mapstructure:"include-issue-pr-authors"`
IncludeIssuesClosedAsNotPlanned bool `yaml:"include-issues-not-planned" json:"include-issues-not-planned" mapstructure:"include-issues-not-planned"`
IncludePRs bool `yaml:"include-prs" json:"include-prs" mapstructure:"include-prs"`
IncludeIssues bool `yaml:"include-issues" json:"include-issues" mapstructure:"include-issues"`
IssuesRequireLinkedPR bool `yaml:"issues-require-linked-prs" json:"issues-require-linked-prs" mapstructure:"issues-require-linked-prs"`
ConsiderPRMergeCommits bool `yaml:"consider-pr-merge-commits" json:"consider-pr-merge-commits" mapstructure:"consider-pr-merge-commits"`
Changes []githubChange `yaml:"changes" json:"changes" mapstructure:"changes"`
}

type githubChange struct {
Expand All @@ -40,14 +41,15 @@ func (cfg githubSummarizer) ToGithubConfig() (github.Config, error) {
}
}
return github.Config{
Host: cfg.Host,
IncludeIssuePRAuthors: cfg.IncludeIssuePRAuthors,
IncludeIssues: cfg.IncludeIssues,
IncludePRs: cfg.IncludePRs,
ExcludeLabels: cfg.ExcludeLabels,
IssuesRequireLinkedPR: cfg.IssuesRequireLinkedPR,
ConsiderPRMergeCommits: cfg.ConsiderPRMergeCommits,
ChangeTypesByLabel: typeSet,
Host: cfg.Host,
IncludeIssuePRAuthors: cfg.IncludeIssuePRAuthors,
IncludeIssues: cfg.IncludeIssues,
IncludeIssuesClosedAsNotPlanned: cfg.IncludeIssuesClosedAsNotPlanned,
IncludePRs: cfg.IncludePRs,
ExcludeLabels: cfg.ExcludeLabels,
IssuesRequireLinkedPR: cfg.IssuesRequireLinkedPR,
ConsiderPRMergeCommits: cfg.ConsiderPRMergeCommits,
ChangeTypesByLabel: typeSet,
}, nil
}

Expand All @@ -58,6 +60,7 @@ func (cfg githubSummarizer) loadDefaultValues(v *viper.Viper) {
v.SetDefault("github.include-prs", true)
v.SetDefault("github.include-issue-pr-authors", true)
v.SetDefault("github.include-issues", true)
v.SetDefault("github.include-issues-not-planned", false)
v.SetDefault("github.exclude-labels", []string{"duplicate", "question", "invalid", "wontfix", "wont-fix", "release-ignore", "changelog-ignore", "ignore"})
v.SetDefault("github.changes", []githubChange{
{
Expand Down

0 comments on commit 76b422a

Please sign in to comment.