Skip to content

Commit 8e84739

Browse files
Break into component sections as needed (#221)
* break into component sections as needed * add new config option * add fragment
1 parent 49ad3b6 commit 8e84739

File tree

9 files changed

+108
-41
lines changed

9 files changed

+108
-41
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# REQUIRED
2+
# Kind can be one of:
3+
# - breaking-change: a change to previously-documented behavior
4+
# - deprecation: functionality that is being removed in a later release
5+
# - bug-fix: fixes a problem in a previous version
6+
# - enhancement: extends functionality but does not break or fix existing behavior
7+
# - feature: new functionality
8+
# - known-issue: problems that we are aware of in a given version
9+
# - security: impacts on the security of a product or a user’s deployment.
10+
# - upgrade: important information for someone upgrading from a prior version
11+
# - other: does not fit into any of the other categories
12+
kind: feature
13+
14+
# REQUIRED for all kinds
15+
# Change summary; a 80ish characters long description of the change.
16+
summary: Add a new `subsections` configuration option that specifies whether to show `component`s as subsections in rendered release notes.
17+
18+
# REQUIRED for breaking-change, deprecation, known-issue
19+
# Long description; in case the summary is not enough to describe the change
20+
# this field accommodate a description without length limits.
21+
description: This should be set to `true` in repos with multiple `component`s. For example, the Beats repo, which contains changelog entries for multiple `component`s like `filebeat`, `metricbeat`, etc.
22+
23+
# REQUIRED for breaking-change, deprecation, known-issue
24+
# impact:
25+
26+
# REQUIRED for breaking-change, deprecation, known-issue
27+
# action:
28+
29+
# REQUIRED for all kinds
30+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
31+
component:
32+
33+
# AUTOMATED
34+
# OPTIONAL to manually add other PR URLs
35+
# PR URL: A link the PR that added the changeset.
36+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
37+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
38+
# Please provide it if you are adding a fragment for a different PR.
39+
pr:
40+
- https://github.com/elastic/elastic-agent-changelog-tool/pull/221
41+
42+
# AUTOMATED
43+
# OPTIONAL to manually add other issue URLs
44+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
45+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
46+
# issue: https://github.com/owner/repo/1234

cmd/render.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var RenderLongDescription = `Use this command to render the consolidated changel
2323
func RenderCmd(fs afero.Fs) *cobra.Command {
2424
renderCmd := &cobra.Command{
2525
Use: "render",
26-
Short: "Render a changelog in an asciidoc file",
26+
Short: "Render a changelog in an AsciiDoc or Markdown file",
2727
Long: RenderLongDescription,
2828
Args: func(cmd *cobra.Command, args []string) error {
2929
return nil
@@ -32,6 +32,7 @@ func RenderCmd(fs afero.Fs) *cobra.Command {
3232
dest := viper.GetString("changelog_destination")
3333
renderedDest := viper.GetString("rendered_changelog_destination")
3434
repo := viper.GetString("repo")
35+
subsections := viper.GetBool("subsections")
3536

3637
version, err := cmd.Flags().GetString("version")
3738
if err != nil {
@@ -54,25 +55,25 @@ func RenderCmd(fs afero.Fs) *cobra.Command {
5455
}
5556

5657
if file_type == "asciidoc" {
57-
r := changelog.NewRenderer(fs, c, renderedDest, "asciidoc-embedded", repo)
58+
r := changelog.NewRenderer(fs, c, renderedDest, "asciidoc-embedded", repo, subsections)
5859
if err := r.Render(); err != nil {
5960
return fmt.Errorf("cannot build asciidoc file: %w", err)
6061
}
6162
} else if file_type == "markdown" {
62-
r_index := changelog.NewRenderer(fs, c, renderedDest, "markdown-index", repo)
63+
r_index := changelog.NewRenderer(fs, c, renderedDest, "markdown-index", repo, subsections)
6364
if err := r_index.Render(); err != nil {
6465
return fmt.Errorf("cannot build markdown file: %w", err)
6566
}
66-
r_breaking := changelog.NewRenderer(fs, c, renderedDest, "markdown-breaking", repo)
67+
r_breaking := changelog.NewRenderer(fs, c, renderedDest, "markdown-breaking", repo, subsections)
6768
if err := r_breaking.Render(); err != nil {
6869
return fmt.Errorf("cannot build markdown file: %w", err)
6970
}
70-
r_deprecations := changelog.NewRenderer(fs, c, renderedDest, "markdown-deprecations", repo)
71+
r_deprecations := changelog.NewRenderer(fs, c, renderedDest, "markdown-deprecations", repo, subsections)
7172
if err := r_deprecations.Render(); err != nil {
7273
return fmt.Errorf("cannot build markdown file: %w", err)
7374
}
7475
} else {
75-
r := changelog.NewRenderer(fs, c, renderedDest, template, repo)
76+
r := changelog.NewRenderer(fs, c, renderedDest, template, repo, subsections)
7677
if err := r.Render(); err != nil {
7778
return fmt.Errorf("cannot build file: %w", err)
7879
}

docs/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ When generating Markdown files, at a minimum you should set the following settin
2424
| `owner` (required) | `elastic` | The owner of the GitHub repo. |
2525
| `repo` (required) || The name of the GitHub repo. |
2626
| `rendered_changelog_destination` | `changelog` | The directory where you want to put the generated files.<br><br>When generating Markdown files, this should probably be `docs/release-notes/_snippets`. |
27+
| `subsections` | `false` | Whether to show `component`s as subsections in rendered release notes. This should be set to `true` in repos with multiple `component`s (for example, Beats). |
2728

2829
## Supported Environment Variables
2930

internal/assets/markdown-breaking-template.md.tmpl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
## {{.Version}} [{{.Repo}}-{{.Version}}-breaking-changes]
2-
{{ if .BreakingChange -}}{{ range $k, $v := .BreakingChange }}{{ range $item := $v }}
2+
{{ if .BreakingChange -}}{{ range $k, $v := .BreakingChange }}{{ $k | header2 }}{{ range $item := $v }}
3+
34
::::{dropdown} {{ $item.Summary | beautify }}
4-
{{ if $item.Description }}{{ $item.Description }}{{ end }}
5+
{{ if $item.Description }}{{ $item.Description }}{{ else }}% Describe the functionality that changed{{ end }}
56

67
For more information, check {{ linkPRSource $item.Component $item.LinkedPR }}{{ linkIssueSource $item.Component $item.LinkedIssue }}.
78

internal/assets/markdown-deprecations-template.md.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
## {{.Version}} [{{.Repo}}-{{.Version}}-deprecations]
2-
{{ if .Deprecation -}}{{ range $k, $v := .Deprecation }}{{ range $item := $v }}
2+
{{ if .Deprecation -}}{{ range $k, $v := .Deprecation }}{{ $k | header2 }}{{ range $item := $v }}
33

44
::::{dropdown} {{ $item.Summary | beautify }}
5-
{{ if $item.Description }}{{ $item.Description }}{{ end }}
5+
{{ if $item.Description }}{{ $item.Description }}{{ else }}% Describe the functionality that was deprecated{{ end }}
66

77
For more information, check {{ linkPRSource $item.Component $item.LinkedPR }}{{ linkIssueSource $item.Component $item.LinkedIssue }}.
88

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
11
## {{.Version}} [{{.Repo}}-release-notes-{{.Version}}]
22
{{ if or .KnownIssue .BreakingChange .Deprecation }}
33
{{ other_links }}{{- end }}
4-
{{ if or .Feature .Enhancement .Security .BugFix }}{{ if or .Feature .Enhancement }}
4+
{{ if or .Feature .Enhancement .Security .BugFix }}
5+
{{ if or .Feature .Enhancement }}
56
### Features and enhancements [{{.Repo}}-{{.Version}}-features-enhancements]
6-
{{ if .Feature }}{{ range $k, $v := .Feature }}{{ range $item := $v }}
7-
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
8-
{{ $item.Description | indent }}
9-
{{- end }}
10-
{{- end }}{{- end }}{{- end }}{{ if .Enhancement }}{{ range $k, $v := .Enhancement }}{{ range $item := $v }}
7+
{{ $additions := combine .Feature .Enhancement }}{{ range $k, $v := $additions }}{{ header2 $k }}
8+
{{ range $item := $v }}
119
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
1210
{{ $item.Description | indent }}
1311
{{- end }}
1412
{{- end }}{{- end }}{{- end }}
15-
{{- end }}
1613

1714
{{ if or .Security .BugFix }}
1815
### Fixes [{{.Repo}}-{{.Version}}-fixes]
19-
{{ if .Security }}{{ range $k, $v := .Security }}{{ range $item := $v }}
16+
{{ $fixes := combine .Security .BugFix }}{{ range $k, $v := $fixes }}{{ header2 $k }}
17+
{{ range $item := $v }}
2018
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
2119
{{ $item.Description | indent }}
2220
{{- end }}
23-
{{- end }}{{- end }}{{- end }}{{ if .BugFix }}{{ range $k, $v := .BugFix }}{{ range $item := $v }}
24-
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
25-
{{ $item.Description | indent }}
26-
{{- end }}
27-
{{- end }}{{- end }}{{- end }}{{- end }}
21+
{{- end }}{{- end }}{{- end }}
2822
{{ else }}
2923
_No new features, enhancements, or fixes._
3024
{{- end }}

internal/changelog/renderer.go

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,20 @@ type Renderer struct {
2323
changelog Changelog
2424
fs afero.Fs
2525
// dest is the destination location where the changelog is written to
26-
dest string
27-
templ string
28-
repo string
26+
dest string
27+
templ string
28+
repo string
29+
subsections bool
2930
}
3031

31-
func NewRenderer(fs afero.Fs, c Changelog, dest string, templ string, repo string) *Renderer {
32+
func NewRenderer(fs afero.Fs, c Changelog, dest string, templ string, repo string, subsections bool) *Renderer {
3233
return &Renderer{
33-
changelog: c,
34-
fs: fs,
35-
dest: dest,
36-
templ: templ,
37-
repo: repo,
34+
changelog: c,
35+
fs: fs,
36+
dest: dest,
37+
templ: templ,
38+
repo: repo,
39+
subsections: subsections,
3840
}
3941
}
4042

@@ -47,11 +49,12 @@ func (r Renderer) Render() error {
4749
}
4850

4951
type TemplateData struct {
50-
Component string
51-
Version string
52-
Repo string
53-
Changelog Changelog
54-
Kinds map[Kind]bool
52+
Component string
53+
Version string
54+
Repo string
55+
Changelog Changelog
56+
Kinds map[Kind]bool
57+
Subsections bool
5558

5659
// In Markdown, this goes to release notes
5760
Enhancement map[string][]Entry
@@ -75,6 +78,7 @@ func (r Renderer) Render() error {
7578
r.repo,
7679
r.changelog,
7780
collectKinds(r.changelog.Entries),
81+
r.subsections,
7882
// In Markdown, this goes to release notes
7983
collectByKindMap(r.changelog.Entries, Enhancement),
8084
collectByKindMap(r.changelog.Entries, Feature),
@@ -159,15 +163,33 @@ func (r Renderer) Render() error {
159163
if len(links) > 0 {
160164
return fmt.Sprintf(
161165
"_This release also includes: %s._",
162-
strings.Join(links, " and"),
166+
strings.Join(links, " and "),
163167
)
164168
} else {
165169
return ""
166170
}
167171
},
168172
// Ensure components have section styling
169-
"header2": func(s1 string) string {
170-
return fmt.Sprintf("**%s**", s1)
173+
"header2": func(s string) string {
174+
if r.subsections {
175+
s = strings.ToUpper(string(s[0])) + s[1:]
176+
s = strings.ReplaceAll(s, "-", " ")
177+
return fmt.Sprintf("\n\n**%s**", s)
178+
} else {
179+
return ""
180+
}
181+
},
182+
"combine": func(map1 map[string][]Entry, map2 map[string][]Entry) map[string][]Entry {
183+
combinedMap := make(map[string][]Entry)
184+
// Start with a copy of map1 entries
185+
for k, v := range map1 {
186+
combinedMap[k] = append([]Entry{}, v...)
187+
}
188+
// Merge entries from map2, appending to any existing entries
189+
for k, v := range map2 {
190+
combinedMap[k] = append(combinedMap[k], v...)
191+
}
192+
return combinedMap
171193
},
172194
}).
173195
Parse(string(tpl))

internal/changelog/renderer_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func TestRenderer(t *testing.T) {
2323
filename := "0.0.0.yaml"
2424
src := "testdata"
2525
dest := viper.GetString("changelog_destination")
26+
subsections := viper.GetBool("subsections")
2627

2728
t.Log("building changelog from test fragments")
2829
builder := changelog.NewBuilder(fs, filename, "0.0.0", src, dest)
@@ -34,7 +35,7 @@ func TestRenderer(t *testing.T) {
3435
c, err := changelog.FromFile(fs, inFile)
3536
require.NoError(t, err)
3637

37-
r := changelog.NewRenderer(fs, c, dest, "asciidoc-embedded", "elastic-agent")
38+
r := changelog.NewRenderer(fs, c, dest, "asciidoc-embedded", "elastic-agent", subsections)
3839

3940
err = r.Render()
4041
require.Nil(t, err)

internal/settings/settings.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func setDefaults() {
6161
viper.SetDefault("changelog_destination", "changelog")
6262
viper.SetDefault("rendered_changelog_destination", "changelog")
6363
viper.SetDefault("file_type", "markdown")
64+
viper.SetDefault("subsections", false)
6465
viper.SetDefault("template", "asciidoc-embedded")
6566
}
6667

0 commit comments

Comments
 (0)