Skip to content

Commit 18f4d01

Browse files
committed
Add release notes expander functionality
Signed-off-by: chandankumar4 <chandan.kr404@gmail.com>
1 parent 5baca0f commit 18f4d01

File tree

5 files changed

+109
-36
lines changed

5 files changed

+109
-36
lines changed

hack/tools/release/notes/generator.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ type pr struct {
4949

5050
// prLister returns a list of PRs.
5151
type prLister interface {
52-
listPRs() ([]pr, error)
52+
listPRs(previousRelease ref) ([]pr, error)
5353
}
5454

5555
// notesEntry represents a line item for the release notes.
@@ -67,25 +67,39 @@ type prProcessor interface {
6767
// entriesPrinter formats and outputs to stdout the notes
6868
// based on a list of entries.
6969
type entriesPrinter interface {
70-
print([]notesEntry, int, string)
70+
print([]notesEntry, int, string, ref)
7171
}
7272

73-
// run generates and prints the notes.
74-
func (g *notesGenerator) run() error {
75-
prs, err := g.lister.listPRs()
73+
// run generating and prints the notes.
74+
func (g *notesGenerator) run(previousReleaseRef ref) error {
75+
if previousReleaseRef.value != "" {
76+
previousReleasePRs, err := g.lister.listPRs(previousReleaseRef)
77+
if err != nil {
78+
return err
79+
}
80+
previousEntries := g.processor.process(previousReleasePRs)
81+
82+
dependencies, err := g.dependenciesProcessor.generateDependencies(previousReleaseRef)
83+
if err != nil {
84+
return err
85+
}
86+
87+
g.printer.print(previousEntries, len(previousReleasePRs), dependencies, previousReleaseRef)
88+
}
89+
90+
prs, err := g.lister.listPRs(ref{})
7691
if err != nil {
7792
return err
7893
}
79-
8094
entries := g.processor.process(prs)
8195

82-
dependencies, err := g.dependenciesProcessor.generateDependencies()
96+
dependencies, err := g.dependenciesProcessor.generateDependencies(ref{})
8397
if err != nil {
8498
return err
8599
}
86100

87101
// Pass in length of PRs to printer as some PRs are excluded from the entries list
88-
g.printer.print(entries, len(prs), dependencies)
102+
g.printer.print(entries, len(prs), dependencies, ref{})
89103

90104
return nil
91105
}

hack/tools/release/notes/list.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,18 @@ func newGithubFromToPRLister(repo string, fromRef, toRef ref, branch string) *gi
5454
// between fromRef and toRef, discarding any PR not seeing in the commits list.
5555
// This ensures we don't include any PR merged in the same date range that
5656
// doesn't belong to our git timeline.
57-
func (l *githubFromToPRLister) listPRs() ([]pr, error) {
58-
log.Printf("Computing diff between %s and %s", l.fromRef, l.toRef)
59-
diff, err := l.client.getDiffAllCommits(l.fromRef.value, l.toRef.value)
57+
func (l *githubFromToPRLister) listPRs(previousReleaseRef ref) ([]pr, error) {
58+
var (
59+
diff *githubDiff
60+
err error
61+
)
62+
if previousReleaseRef.value != "" {
63+
log.Printf("Computing diff between %s and %s", previousReleaseRef.value, l.toRef)
64+
diff, err = l.client.getDiffAllCommits(previousReleaseRef.value, l.toRef.value)
65+
} else {
66+
log.Printf("Computing diff between %s and %s", l.fromRef, l.toRef)
67+
diff, err = l.client.getDiffAllCommits(l.fromRef.value, l.toRef.value)
68+
}
6069
if err != nil {
6170
return nil, err
6271
}

hack/tools/release/notes/main.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ This tool prints all the titles of all PRs in between to references.
3838
Use these as the base of your release notes.
3939
*/
4040

41+
const (
42+
betaRelease = "BETA RELEASE"
43+
releaseCandidate = "RELEASE CANDIDATE"
44+
)
45+
4146
func main() {
4247
cmd := newNotesCmd()
4348
if err := cmd.run(); err != nil {
@@ -51,6 +56,7 @@ type notesCmdConfig struct {
5156
toRef string
5257
newTag string
5358
branch string
59+
previousReleaseVersion string
5460
prefixAreaLabel bool
5561
deprecation bool
5662
addKubernetesVersionSupport bool
@@ -64,6 +70,7 @@ func readCmdConfig() *notesCmdConfig {
6470
flag.StringVar(&config.toRef, "to", "", "The ref (tag, branch or commit to stop at. It must be formatted as heads/<branch name> for branches and tags/<tag name> for tags. If not set, it will default to branch.")
6571
flag.StringVar(&config.branch, "branch", "", "The branch to generate the notes from. If not set, it will be calculated from release.")
6672
flag.StringVar(&config.newTag, "release", "", "The tag for the new release.")
73+
flag.StringVar(&config.previousReleaseVersion, "previous-release-version", "", "The tag for the previous beta release.")
6774

6875
flag.BoolVar(&config.prefixAreaLabel, "prefix-area-label", true, "If enabled, will prefix the area label.")
6976
flag.BoolVar(&config.deprecation, "deprecation", true, "If enabled, will add a templated deprecation warning header.")
@@ -86,7 +93,8 @@ func newNotesCmd() *notesCmd {
8693
}
8794

8895
func (cmd *notesCmd) run() error {
89-
if err := validateConfig(cmd.config); err != nil {
96+
releaseType := releaseTypeFromNewTag(cmd.config.newTag)
97+
if err := validateConfig(cmd.config, releaseType); err != nil {
9098
return err
9199
}
92100

@@ -100,8 +108,13 @@ func (cmd *notesCmd) run() error {
100108

101109
from, to := parseRef(cmd.config.fromRef), parseRef(cmd.config.toRef)
102110

111+
var previousReleaseRef ref
112+
if cmd.config.previousReleaseVersion != "" {
113+
previousReleaseRef = parseRef(cmd.config.previousReleaseVersion)
114+
}
115+
103116
printer := newReleaseNotesPrinter(cmd.config.repo, from.value)
104-
printer.releaseType = releaseTypeFromNewTag(cmd.config.newTag)
117+
printer.releaseType = releaseType
105118
printer.printDeprecation = cmd.config.deprecation
106119
printer.printKubernetesSupport = cmd.config.addKubernetesVersionSupport
107120

@@ -112,7 +125,7 @@ func (cmd *notesCmd) run() error {
112125
newDependenciesProcessor(cmd.config.repo, from.value, to.value),
113126
)
114127

115-
return generator.run()
128+
return generator.run(previousReleaseRef)
116129
}
117130

118131
func releaseTypeFromNewTag(newTagConfig string) string {
@@ -130,9 +143,9 @@ func releaseTypeFromNewTag(newTagConfig string) string {
130143
// If a new type is not defined, no warning banner will be printed.
131144
switch newTag.Pre[0].VersionStr {
132145
case "rc":
133-
return "RELEASE CANDIDATE"
146+
return releaseCandidate
134147
case "beta":
135-
return "BETA RELEASE"
148+
return betaRelease
136149
}
137150
return ""
138151
}
@@ -150,7 +163,7 @@ func commandExists(cmd string) bool {
150163
return err == nil
151164
}
152165

153-
func validateConfig(config *notesCmdConfig) error {
166+
func validateConfig(config *notesCmdConfig, releaseType string) error {
154167
if config.fromRef == "" && config.newTag == "" {
155168
return errors.New("at least one of --from or --release need to be set")
156169
}
@@ -171,6 +184,12 @@ func validateConfig(config *notesCmdConfig) error {
171184
}
172185
}
173186

187+
if releaseType != "" {
188+
if config.previousReleaseVersion == "" {
189+
return errors.New("--previous-release-version need to be set with RELEASE CANDIDATE/BETA RELEASE tag")
190+
}
191+
}
192+
174193
return nil
175194
}
176195

hack/tools/release/notes/print.go

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ var defaultOutputOrder = []string{
3737
release.Unknown,
3838
}
3939

40+
var isExpanderAdded = false
41+
var isPreReleasePrinted = false
42+
4043
// releaseNotesPrinter outputs the PR entries following
4144
// the right format for the release notes.
4245
type releaseNotesPrinter struct {
@@ -57,7 +60,7 @@ func newReleaseNotesPrinter(repo, fromTag string) *releaseNotesPrinter {
5760
}
5861

5962
// print outputs to stdout the release notes.
60-
func (p *releaseNotesPrinter) print(entries []notesEntry, commitsInRelease int, dependencies string) {
63+
func (p *releaseNotesPrinter) print(entries []notesEntry, commitsInRelease int, dependencies string, previousReleaseRef ref) {
6164
merges := map[string][]string{
6265
release.Features: {},
6366
release.Bugs: {},
@@ -75,11 +78,22 @@ func (p *releaseNotesPrinter) print(entries []notesEntry, commitsInRelease int,
7578
}
7679
}
7780

78-
if p.releaseType != "" {
81+
if p.releaseType != "" && !isPreReleasePrinted {
7982
fmt.Printf("🚨 This is a %s. Use it only for testing purposes. If you find any bugs, file an [issue](https://github.com/%s/issues/new).\n", p.releaseType, p.repo)
83+
isPreReleasePrinted = true
84+
}
85+
86+
if p.releaseType != "" && previousReleaseRef.value == "" {
87+
// This will add the release notes expansion functionality for a pre-release version
88+
fmt.Print(`<details>
89+
<summary>More details about the release</summary>
90+
`)
91+
fmt.Printf("\n:warning: **%s NOTES** :warning:\n", p.releaseType)
92+
93+
isExpanderAdded = true
8094
}
8195

82-
if p.printKubernetesSupport {
96+
if p.printKubernetesSupport && previousReleaseRef.value == "" {
8397
fmt.Print(`## 👌 Kubernetes version support
8498
8599
- Management Cluster: v1.**X**.x -> v1.**X**.x
@@ -106,7 +120,11 @@ REPLACE ME: A couple sentences describing the deprecation, including links to do
106120
`)
107121
}
108122

109-
fmt.Printf("## Changes since %s\n", p.fromTag)
123+
if previousReleaseRef.value != "" {
124+
fmt.Printf("## Changes since %s\n", previousReleaseRef.value)
125+
} else {
126+
fmt.Printf("## Changes since %s\n", p.fromTag)
127+
}
110128

111129
fmt.Printf("## :chart_with_upwards_trend: Overview\n")
112130
if commitsInRelease == 1 {
@@ -139,18 +157,20 @@ REPLACE ME: A couple sentences describing the deprecation, including links to do
139157

140158
switch key {
141159
case release.Documentation:
142-
sort.Strings(mergeslice)
143-
if len(mergeslice) == 1 {
144-
fmt.Printf(
145-
":book: Additionally, there has been 1 contribution to our documentation and book. (%s) \n\n",
146-
mergeslice[0],
147-
)
148-
} else {
149-
fmt.Printf(
150-
":book: Additionally, there have been %d contributions to our documentation and book. (%s) \n\n",
151-
len(mergeslice),
152-
strings.Join(mergeslice, ", "),
153-
)
160+
if previousReleaseRef.value == "" {
161+
sort.Strings(mergeslice)
162+
if len(mergeslice) == 1 {
163+
fmt.Printf(
164+
":book: Additionally, there has been 1 contribution to our documentation and book. (%s) \n\n",
165+
mergeslice[0],
166+
)
167+
} else {
168+
fmt.Printf(
169+
":book: Additionally, there have been %d contributions to our documentation and book. (%s) \n\n",
170+
len(mergeslice),
171+
strings.Join(mergeslice, ", "),
172+
)
173+
}
154174
}
155175
default:
156176
fmt.Println("## " + key)
@@ -170,5 +190,10 @@ REPLACE ME: A couple sentences describing the deprecation, including links to do
170190
fmt.Print(dependencies)
171191

172192
fmt.Println("")
173-
fmt.Println("_Thanks to all our contributors!_ 😊")
193+
if isExpanderAdded {
194+
fmt.Print("</details>\n<br/>\n")
195+
}
196+
if previousReleaseRef.value == "" {
197+
fmt.Println("_Thanks to all our contributors!_ 😊")
198+
}
174199
}

hack/tools/release/notes/process.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,16 @@ func (g prEntriesProcessor) process(prs []pr) []notesEntry {
117117
return entries
118118
}
119119

120-
func (d dependenciesProcessor) generateDependencies() (string, error) {
120+
func (d dependenciesProcessor) generateDependencies(previousRelease ref) (string, error) {
121121
repoURL := fmt.Sprintf("https://github.com/%s", d.repo)
122+
123+
fromTag := d.fromTag
124+
if previousRelease.value != "" {
125+
fromTag = previousRelease.value
126+
}
127+
122128
deps, err := notes.NewDependencies().ChangesForURL(
123-
repoURL, d.fromTag, d.toTag,
129+
repoURL, fromTag, d.toTag,
124130
)
125131
if err != nil {
126132
return "", err

0 commit comments

Comments
 (0)