Skip to content

Commit

Permalink
Add release notes expander functionality
Browse files Browse the repository at this point in the history
Signed-off-by: chandankumar4 <chandan.kr404@gmail.com>
  • Loading branch information
chandankumar4 committed Mar 28, 2024
1 parent 5baca0f commit 8054541
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 36 deletions.
30 changes: 22 additions & 8 deletions hack/tools/release/notes/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type pr struct {

// prLister returns a list of PRs.
type prLister interface {
listPRs() ([]pr, error)
listPRs(previousRelease ref) ([]pr, error)
}

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

// run generates and prints the notes.
func (g *notesGenerator) run() error {
prs, err := g.lister.listPRs()
// run generating and prints the notes.
func (g *notesGenerator) run(previousReleaseRef ref) error {
if previousReleaseRef.value != "" {
previousReleasePRs, err := g.lister.listPRs(previousReleaseRef)
if err != nil {
return err
}
previousEntries := g.processor.process(previousReleasePRs)

dependencies, err := g.dependenciesProcessor.generateDependencies(previousReleaseRef)
if err != nil {
return err
}

g.printer.print(previousEntries, len(previousReleasePRs), dependencies, previousReleaseRef)
}

prs, err := g.lister.listPRs(ref{})
if err != nil {
return err
}

entries := g.processor.process(prs)

dependencies, err := g.dependenciesProcessor.generateDependencies()
dependencies, err := g.dependenciesProcessor.generateDependencies(ref{})
if err != nil {
return err
}

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

return nil
}
15 changes: 12 additions & 3 deletions hack/tools/release/notes/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,18 @@ func newGithubFromToPRLister(repo string, fromRef, toRef ref, branch string) *gi
// between fromRef and toRef, discarding any PR not seeing in the commits list.
// This ensures we don't include any PR merged in the same date range that
// doesn't belong to our git timeline.
func (l *githubFromToPRLister) listPRs() ([]pr, error) {
log.Printf("Computing diff between %s and %s", l.fromRef, l.toRef)
diff, err := l.client.getDiffAllCommits(l.fromRef.value, l.toRef.value)
func (l *githubFromToPRLister) listPRs(previousReleaseRef ref) ([]pr, error) {
var (
diff *githubDiff
err error
)
if previousReleaseRef.value != "" {
log.Printf("Computing diff between %s and %s", previousReleaseRef.value, l.toRef)
diff, err = l.client.getDiffAllCommits(previousReleaseRef.value, l.toRef.value)
} else {
log.Printf("Computing diff between %s and %s", l.fromRef, l.toRef)
diff, err = l.client.getDiffAllCommits(l.fromRef.value, l.toRef.value)
}
if err != nil {
return nil, err
}
Expand Down
31 changes: 25 additions & 6 deletions hack/tools/release/notes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ This tool prints all the titles of all PRs in between to references.
Use these as the base of your release notes.
*/

const (
betaRelease = "BETA RELEASE"
releaseCandidate = "RELEASE CANDIDATE"
)

func main() {
cmd := newNotesCmd()
if err := cmd.run(); err != nil {
Expand All @@ -51,6 +56,7 @@ type notesCmdConfig struct {
toRef string
newTag string
branch string
previousReleaseVersion string
prefixAreaLabel bool
deprecation bool
addKubernetesVersionSupport bool
Expand All @@ -64,6 +70,7 @@ func readCmdConfig() *notesCmdConfig {
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.")
flag.StringVar(&config.branch, "branch", "", "The branch to generate the notes from. If not set, it will be calculated from release.")
flag.StringVar(&config.newTag, "release", "", "The tag for the new release.")
flag.StringVar(&config.previousReleaseVersion, "previous-release-version", "", "The tag for the previous beta release.")

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

func (cmd *notesCmd) run() error {
if err := validateConfig(cmd.config); err != nil {
releaseType := releaseTypeFromNewTag(cmd.config.newTag)
if err := validateConfig(cmd.config, releaseType); err != nil {
return err
}

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

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

var previousReleaseRef ref
if cmd.config.previousReleaseVersion != "" {
previousReleaseRef = parseRef(cmd.config.previousReleaseVersion)
}

printer := newReleaseNotesPrinter(cmd.config.repo, from.value)
printer.releaseType = releaseTypeFromNewTag(cmd.config.newTag)
printer.releaseType = releaseType
printer.printDeprecation = cmd.config.deprecation
printer.printKubernetesSupport = cmd.config.addKubernetesVersionSupport

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

return generator.run()
return generator.run(previousReleaseRef)
}

func releaseTypeFromNewTag(newTagConfig string) string {
Expand All @@ -130,9 +143,9 @@ func releaseTypeFromNewTag(newTagConfig string) string {
// If a new type is not defined, no warning banner will be printed.
switch newTag.Pre[0].VersionStr {
case "rc":
return "RELEASE CANDIDATE"
return releaseCandidate
case "beta":
return "BETA RELEASE"
return betaRelease
}
return ""
}
Expand All @@ -150,7 +163,7 @@ func commandExists(cmd string) bool {
return err == nil
}

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

if releaseType == betaRelease {
if config.previousReleaseVersion == "" {
return errors.New("--previous-release-version need to be set with BETA RELEASE tag")
}
}

return nil
}

Expand Down
60 changes: 43 additions & 17 deletions hack/tools/release/notes/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ var defaultOutputOrder = []string{
release.Unknown,
}

var isExpanderAdded = false
var isPreReleasePrinted = false

// releaseNotesPrinter outputs the PR entries following
// the right format for the release notes.
type releaseNotesPrinter struct {
Expand All @@ -57,7 +60,7 @@ func newReleaseNotesPrinter(repo, fromTag string) *releaseNotesPrinter {
}

// print outputs to stdout the release notes.
func (p *releaseNotesPrinter) print(entries []notesEntry, commitsInRelease int, dependencies string) {
func (p *releaseNotesPrinter) print(entries []notesEntry, commitsInRelease int, dependencies string, previousReleaseRef ref) {
merges := map[string][]string{
release.Features: {},
release.Bugs: {},
Expand All @@ -75,11 +78,23 @@ func (p *releaseNotesPrinter) print(entries []notesEntry, commitsInRelease int,
}
}

if p.releaseType != "" {
if p.releaseType != "" && !isPreReleasePrinted {
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)
isPreReleasePrinted = true
}

if p.printKubernetesSupport {
if p.releaseType != "" && previousReleaseRef.value == "" {
// This will add the release notes expansion functionality for a pre-release version
fmt.Print(`<details>
<summary>More details about the release</summary>
:warning: **RELEASE CANDIDATE NOTES** :warning:
`)
isExpanderAdded = true
}

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

fmt.Printf("## Changes since %s\n", p.fromTag)
if previousReleaseRef.value != "" {
fmt.Printf("## Changes since %s\n", previousReleaseRef.value)
} else {
fmt.Printf("## Changes since %s\n", p.fromTag)
}

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

switch key {
case release.Documentation:
sort.Strings(mergeslice)
if len(mergeslice) == 1 {
fmt.Printf(
":book: Additionally, there has been 1 contribution to our documentation and book. (%s) \n\n",
mergeslice[0],
)
} else {
fmt.Printf(
":book: Additionally, there have been %d contributions to our documentation and book. (%s) \n\n",
len(mergeslice),
strings.Join(mergeslice, ", "),
)
if previousReleaseRef.value == "" {
sort.Strings(mergeslice)
if len(mergeslice) == 1 {
fmt.Printf(
":book: Additionally, there has been 1 contribution to our documentation and book. (%s) \n\n",
mergeslice[0],
)
} else {
fmt.Printf(
":book: Additionally, there have been %d contributions to our documentation and book. (%s) \n\n",
len(mergeslice),
strings.Join(mergeslice, ", "),
)
}
}
default:
fmt.Println("## " + key)
Expand All @@ -170,5 +191,10 @@ REPLACE ME: A couple sentences describing the deprecation, including links to do
fmt.Print(dependencies)

fmt.Println("")
fmt.Println("_Thanks to all our contributors!_ 😊")
if isExpanderAdded {
fmt.Print("</details>\n<br/>\n")
}
if previousReleaseRef.value == "" {
fmt.Println("_Thanks to all our contributors!_ 😊")
}
}
12 changes: 10 additions & 2 deletions hack/tools/release/notes/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,18 @@ func (g prEntriesProcessor) process(prs []pr) []notesEntry {
return entries
}

func (d dependenciesProcessor) generateDependencies() (string, error) {
func (d dependenciesProcessor) generateDependencies(previousRelease ref) (string, error) {
repoURL := fmt.Sprintf("https://github.com/%s", d.repo)

var fromTag string
if previousRelease.value != "" {
fromTag = previousRelease.value
} else {
fromTag = d.fromTag
}

deps, err := notes.NewDependencies().ChangesForURL(
repoURL, d.fromTag, d.toTag,
repoURL, fromTag, d.toTag,
)
if err != nil {
return "", err
Expand Down

0 comments on commit 8054541

Please sign in to comment.