diff --git a/hack/tools/release/notes.go b/hack/tools/release/notes.go index a41916af373e..4fe263d92c3b 100644 --- a/hack/tools/release/notes.go +++ b/hack/tools/release/notes.go @@ -22,6 +22,7 @@ package main import ( "bytes" + "encoding/json" "flag" "fmt" "os" @@ -105,26 +106,62 @@ func increaseDateByOneDay(date string) (string, error) { return datetime.Format(layout), nil } +const ( + missingAreaLabelPrefix = "MISSING_AREA" + areaLabelPrefix = "area/" + multipleAreaLabelsPrefix = "MULTIPLE_AREAS[" +) + +type githubPullRequest struct { + Labels []githubLabel `json:"labels"` +} + +type githubLabel struct { + Name string `json:"name"` +} + func getAreaLabel(merge string) (string, error) { // Get pr id from merge commit prID := strings.Replace(strings.TrimSpace(strings.Split(merge, " ")[3]), "#", "", -1) - // Get labels on the pr - cmd := exec.Command("gh", "api", "repos/kubernetes-sigs/cluster-api/pulls/"+prID, "--jq", ".labels[] | select(.name | contains (\"area\")) | .name") //nolint:gosec + cmd := exec.Command("gh", "api", "repos/kubernetes-sigs/cluster-api/pulls/"+prID) out, err := cmd.CombinedOutput() if err != nil { - fmt.Println("Error", err) return "", err } - areaLabel := string(out) - if areaLabel == "" { - return "TODO", nil + pr := &githubPullRequest{} + if err := json.Unmarshal(out, pr); err != nil { + return "", err } - area := strings.TrimSpace(strings.Split(areaLabel, "/")[1]) - return area, nil + var areaLabels []string + for _, label := range pr.Labels { + if area, ok := trimAreaLabel(label.Name); ok { + areaLabels = append(areaLabels, area) + } + } + + switch len(areaLabels) { + case 0: + return missingAreaLabelPrefix, nil + case 1: + return areaLabels[0], nil + default: + return multipleAreaLabelsPrefix + strings.Join(areaLabels, "|") + "]", nil + } +} + +// trimAreaLabel removes the "area/" prefix from area labels and returns it. +// If the label is an area label, the second return value is true, otherwise false. +func trimAreaLabel(label string) (string, bool) { + trimmed := strings.TrimPrefix(label, areaLabelPrefix) + if len(trimmed) < len(label) { + return trimmed, true + } + + return label, false } func run() int { @@ -145,7 +182,6 @@ func run() int { return 1 } else { commitRange = lastTag() - fmt.Println("git", "rev-list", commitRange+"..HEAD", "--merges", "--pretty=format:%B") cmd = exec.Command("git", "rev-list", commitRange+"..HEAD", "--merges", "--pretty=format:%B") //nolint:gosec } @@ -184,7 +220,11 @@ func run() int { for _, c := range commits { body := trimTitle(c.body) var key, prNumber, fork string - prefix, _ := getAreaLabel(c.merge) + prefix, err := getAreaLabel(c.merge) + if err != nil { + fmt.Println(err) + os.Exit(1) + } switch { case strings.HasPrefix(body, ":sparkles:"), strings.HasPrefix(body, "✨"): key = features