Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiple component support #116

Merged
merged 7 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions changelog/fragments/1666868151-Add-multiple-component-support.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Kind can be one of:
# - breaking-change: a change to previously-documented behavior
# - deprecation: functionality that is being removed in a later release
# - bug-fix: fixes a problem in a previous version
# - enhancement: extends functionality but does not break or fix existing behavior
# - feature: new functionality
# - known-issue: problems that we are aware of in a given version
# - security: impacts on the security of a product or a user’s deployment.
# - upgrade: important information for someone upgrading from a prior version
# - other: does not fit into any of the other categories
kind: feature

# Change summary; a 80ish characters long description of the change.
summary: Add multiple component support

# Long description; in case the summary is not enough to describe the change
# this field accommodate a description without length limits.
#description:

# Affected component; a word indicating the component this changeset affects.
component:

# PR number; optional; the PR number that added the changeset.
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
# Please provide it if you are adding a fragment for a different PR.
#pr: 1234

# Issue number; optional; the GitHub issue related to this changeset (either closes or is part of).
# If not present is automatically filled by the tooling with the issue linked to the PR number.
#issue: 1234
3 changes: 2 additions & 1 deletion config.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
owner: elastic
repo: elastic-agent-changelog-tool
repo: elastic-agent-changelog-tool
components: [elastic-agent-changelog-tool]
38 changes: 29 additions & 9 deletions internal/changelog/asciidoc-template.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
[[release-notes-{{.Version}}]]
== {{.Component}} {{.Version}}

// TODO: support multiple components
Review important information about the {{.Component}} {{.Version}} release.

{{ if .Security -}}
[discrete]
[[security-updates-{{.Version}}]]
=== Security updates

{{.Component}}::{{ range $item := .Security }}
{{ range $k, $v := .Security }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{- end }}
{{- end }}
{{- end }}
{{ if .BreakingChange -}}
[discrete]
[[breaking-changes-{{.Version}}]]
Expand All @@ -25,20 +27,26 @@ performance. Before you upgrade, review the breaking changes, then mitigate the
impact to your application.

// TODO: add details and impact
{{.Component}}::{{ range $item := .BreakingChange }}
{{ range $k, $v := .BreakingChange }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{- end }}
{{- end }}
{{- end }}
{{ if .KnownIssue -}}
[discrete]
[[known-issues-{{.Version}}]]
=== Known issues

// TODO: add details and impact
{{.Component}}::{{ range $item := .KnownIssue }}
{{ range $k, $v := .KnownIssue }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{- end }}
{{- end }}
{{- end }}
{{ if .Deprecation -}}
[discrete]
[[deprecations-{{.Version}}]]
Expand All @@ -49,8 +57,11 @@ The following functionality is deprecated in {{.Version}}, and will be removed i
application, but we strongly recommend you make the necessary updates after you
upgrade to {{.Version}}.

{{.Component}}::{{ range $item := .Deprecation }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{ range $k, $v := .Deprecation }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{ $k | section}}::$k }}::
{{- end }}
{{- end }}
{{- end }}
{{ if .Feature -}}
Expand All @@ -60,27 +71,36 @@ upgrade to {{.Version}}.

The {{.Version}} release adds the following new and notable features.

{{.Component}}::{{ range $item := .Feature }}
{{ range $k, $v := .Feature }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{- end }}
{{- end }}
{{- end }}
{{ if .Enhancement }}
[discrete]
[[enhancements-{{.Version}}]]
=== Enhancements

{{.Component}}::{{ range $item := .Enhancement }}
{{ range $k, $v := .Enhancement }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{- end }}
{{- end }}
{{- end }}
{{ if .BugFix }}
[discrete]
[[bug-fixes-{{.Version}}]]
=== Bug fixes

{{.Component}}::{{ range $item := .BugFix }}
{{ range $k, $v := .BugFix }}
{{ $k | header2}}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}
{{- end }}
{{- end }}
{{- end }}

// end {{.Version}} relnotes
107 changes: 84 additions & 23 deletions internal/changelog/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"strings"

"github.com/spf13/afero"
"github.com/spf13/viper"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
Expand Down Expand Up @@ -47,36 +48,35 @@ func (r Renderer) Render() error {
Changelog Changelog
Kinds map[Kind]bool

BreakingChange []Entry
Deprecation []Entry
BugFix []Entry
Enhancement []Entry
Feature []Entry
KnownIssue []Entry
Security []Entry
Upgrade []Entry
Other []Entry
BreakingChange map[string][]Entry
Deprecation map[string][]Entry
BugFix map[string][]Entry
Enhancement map[string][]Entry
Feature map[string][]Entry
KnownIssue map[string][]Entry
Security map[string][]Entry
Upgrade map[string][]Entry
Other map[string][]Entry
}

td := TemplateData{
"{agent}", r.changelog.Version, r.changelog,
buildTitleByComponents(r.changelog.Entries), r.changelog.Version, r.changelog,
collectKinds(r.changelog.Entries),
collectByKind(r.changelog.Entries, BreakingChange),
collectByKind(r.changelog.Entries, Deprecation),
collectByKind(r.changelog.Entries, BugFix),
collectByKind(r.changelog.Entries, Enhancement),
collectByKind(r.changelog.Entries, Feature),
collectByKind(r.changelog.Entries, KnownIssue),
collectByKind(r.changelog.Entries, Security),
collectByKind(r.changelog.Entries, Upgrade),
collectByKind(r.changelog.Entries, Other),
collectByKindMap(r.changelog.Entries, BreakingChange),
collectByKindMap(r.changelog.Entries, Deprecation),
collectByKindMap(r.changelog.Entries, BugFix),
collectByKindMap(r.changelog.Entries, Enhancement),
collectByKindMap(r.changelog.Entries, Feature),
collectByKindMap(r.changelog.Entries, KnownIssue),
collectByKindMap(r.changelog.Entries, Security),
collectByKindMap(r.changelog.Entries, Upgrade),
collectByKindMap(r.changelog.Entries, Other),
}

tmpl, err := template.New("asciidoc-release-notes").
tmpl, err := template.New("release-notes").
Funcs(template.FuncMap{
// nolint:staticcheck // ignoring for now, supports for multiple component is not implemented
"linkPRSource": func(component string, ids []string) string {
component = "agent" // TODO: remove this when implementing support for multiple components

res := make([]string, len(ids))

for i, id := range ids {
Expand All @@ -87,7 +87,6 @@ func (r Renderer) Render() error {
},
// nolint:staticcheck // ignoring for now, supports for multiple component is not implemented
"linkIssueSource": func(component string, ids []string) string {
component = "agent" // TODO: remove this when implementing support for multiple components
res := make([]string, len(ids))

for i, id := range ids {
Expand All @@ -105,6 +104,15 @@ func (r Renderer) Render() error {
}
return s2.String()
},
// Ensure components have section styling
"header2": func(s1 string) string {
s2 := strings.Builder{}
s2.WriteString(s1)
if !strings.HasSuffix(s1, "::") && s1 != "" {
s2.WriteString("::")
}
return s2.String()
},
}).
Parse(string(tpl))
if err != nil {
Expand Down Expand Up @@ -147,6 +155,22 @@ func collectKinds(items []Entry) map[Kind]bool {
return kinds
}

func collectByKindMap(entries []Entry, k Kind) map[string][]Entry {
componentEntries := map[string][]Entry{}

for _, e := range entries {
if e.Kind == k {
if len(e.Component) > 0 {
componentEntries[e.Component] = append(componentEntries[e.Component], e)
} else {
componentEntries[""] = append(componentEntries[""], e)
}
}
}

return componentEntries
}

func collectByKind(items []Entry, k Kind) []Entry {
entries := []Entry{}

Expand All @@ -158,3 +182,40 @@ func collectByKind(items []Entry, k Kind) []Entry {

return entries
}

func buildTitleByComponents(entries []Entry) string {
configComponents := viper.GetStringSlice("components")

switch len(configComponents) {
case 0:
return ""
case 1:
c := configComponents[0]
for _, e := range entries {
if c != e.Component && len(e.Component) > 0 {
log.Fatalf("Component [%s] not found in config", e.Component)
}
}
return c
default:
var match string
for _, e := range entries {
if e.Component == "" {
log.Fatalf("Component cannot be assumed, choose it from config values: %s", e.File.Name)
}

match = ""
for _, c := range configComponents {
if e.Component != c {
continue
}
match = e.Component
}

if match == "" {
log.Fatalf("Component [%s] not found in config", e.Component)
}
}
return match
}
}