hack/release-notes/main.go (124 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License 2.0; // you may not use this file except in compliance with the Elastic License 2.0. package main import ( "fmt" "log" "os" "strings" "text/template" "github.com/elastic/cloud-on-k8s/v3/hack/release-notes/github" ) const ( noGroup = "nogroup" repoName = "elastic/cloud-on-k8s" releaseNotesTemplate = `## {{$.Version}} [elastic-cloud-kubernetes-{{replace $.Version "." "" }}-release-notes] {{range $group := .GroupOrder -}} {{$grouplbl := index $.LabelMapping $group}} {{with (index $.Groups $grouplbl)}} {{$header := index $.GroupLabels $grouplbl}} ### {{$header}} [elastic-cloud-kubernetes-{{replace $.Version "." ""}}-{{replace $header " " "-"}}] {{range .}} - {{.Title}} [#{{.Number}}](https://github.com/{{$.Repo}}/pull/{{.Number}}){{with .Issues -}} {{$length := len .}} (issue{{if gt $length 1}}s{{end}}: {{range $idx, $el := .}}{{if $idx}}, {{end}}[#{{$el}}](https://github.com/{{$.Repo}}/issues/{{$el}}){{end}}) {{- end}} {{- end}} {{- end}} {{end}}` ) var ( groupLabels = map[string]string{ "breaking": "Breaking changes", "deprecation": "Deprecations", "feature": "Features and enhancements", "bug": "Fixes", "docs": "Documentation improvements", noGroup: "Miscellaneous", } groupOrder = []string{ ">breaking", ">deprecation", ">feature", // This will include both >feature and >enhancement ">bug", ">docs", noGroup, } labelMapping = map[string]string{ ">bug": "bug", ">docs": "docs", ">feature": "feature", ">enhancement": "feature", ">deprecation": "deprecation", ">breaking": "breaking", noGroup: noGroup, } ignoredLabels = map[string]struct{}{ ">non-issue": {}, ">refactoring": {}, ">test": {}, ":ci": {}, "backport": {}, "exclude-from-release-notes": {}, } ) func main() { if len(os.Args) != 2 { fmt.Printf("Usage: GH_TOKEN=<github token> %s VERSION\n", os.Args[0]) os.Exit(2) } version := os.Args[1] prs, err := github.LoadPullRequests(repoName, version, ignoredLabels) if err != nil { log.Printf("ERROR: %v", err) os.Exit(1) } if len(prs) == 0 { log.Print("No pull requests found. Check the version argument.") os.Exit(2) } groupedPRs := groupPullRequests(prs) if err := render(version, groupedPRs); err != nil { log.Printf("Failed to render release notes: %v", err) os.Exit(1) } } func groupPullRequests(prs []github.PullRequest) map[string][]github.PullRequest { groups := make(map[string][]github.PullRequest) PR_LOOP: for _, pr := range prs { for prLabel, mappedLabel := range labelMapping { if _, ok := pr.Labels[prLabel]; ok { groups[mappedLabel] = append(groups[mappedLabel], pr) continue PR_LOOP } } groups[noGroup] = append(groups[noGroup], pr) } return groups } func render(version string, groups map[string][]github.PullRequest) error { params := struct { Version string Repo string Groups map[string][]github.PullRequest GroupLabels map[string]string GroupOrder []string LabelMapping map[string]string }{ Version: version, Repo: repoName, Groups: groups, GroupLabels: groupLabels, GroupOrder: groupOrder, LabelMapping: labelMapping, } funcs := template.FuncMap{ "id": func(s string) string { return strings.TrimPrefix(s, ">") }, "replace": func(input, old, new string) string { replacedString := strings.ReplaceAll(input, old, new) return strings.ToLower(replacedString) }, } tpl := template.Must(template.New("release_notes").Funcs(funcs).Parse(releaseNotesTemplate)) return tpl.Execute(os.Stdout, params) }