Skip to content
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
46 changes: 46 additions & 0 deletions changelog/fragments/1761335496-show-subsections.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# REQUIRED
# 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

# REQUIRED for all kinds
# Change summary; a 80ish characters long description of the change.
summary: Add a new `subsections` configuration option that specifies whether to show `component`s as subsections in rendered release notes.

# REQUIRED for breaking-change, deprecation, known-issue
# Long description; in case the summary is not enough to describe the change
# this field accommodate a description without length limits.
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.

# REQUIRED for breaking-change, deprecation, known-issue
# impact:

# REQUIRED for breaking-change, deprecation, known-issue
# action:

# REQUIRED for all kinds
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
component:

# AUTOMATED
# OPTIONAL to manually add other PR URLs
# PR URL: A link the PR 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:
- https://github.com/elastic/elastic-agent-changelog-tool/pull/221

# AUTOMATED
# OPTIONAL to manually add other issue URLs
# Issue URL; 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: https://github.com/owner/repo/1234
13 changes: 7 additions & 6 deletions cmd/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var RenderLongDescription = `Use this command to render the consolidated changel
func RenderCmd(fs afero.Fs) *cobra.Command {
renderCmd := &cobra.Command{
Use: "render",
Short: "Render a changelog in an asciidoc file",
Short: "Render a changelog in an AsciiDoc or Markdown file",
Long: RenderLongDescription,
Args: func(cmd *cobra.Command, args []string) error {
return nil
Expand All @@ -32,6 +32,7 @@ func RenderCmd(fs afero.Fs) *cobra.Command {
dest := viper.GetString("changelog_destination")
renderedDest := viper.GetString("rendered_changelog_destination")
repo := viper.GetString("repo")
subsections := viper.GetBool("subsections")

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

if file_type == "asciidoc" {
r := changelog.NewRenderer(fs, c, renderedDest, "asciidoc-embedded", repo)
r := changelog.NewRenderer(fs, c, renderedDest, "asciidoc-embedded", repo, subsections)
if err := r.Render(); err != nil {
return fmt.Errorf("cannot build asciidoc file: %w", err)
}
} else if file_type == "markdown" {
r_index := changelog.NewRenderer(fs, c, renderedDest, "markdown-index", repo)
r_index := changelog.NewRenderer(fs, c, renderedDest, "markdown-index", repo, subsections)
if err := r_index.Render(); err != nil {
return fmt.Errorf("cannot build markdown file: %w", err)
}
r_breaking := changelog.NewRenderer(fs, c, renderedDest, "markdown-breaking", repo)
r_breaking := changelog.NewRenderer(fs, c, renderedDest, "markdown-breaking", repo, subsections)
if err := r_breaking.Render(); err != nil {
return fmt.Errorf("cannot build markdown file: %w", err)
}
r_deprecations := changelog.NewRenderer(fs, c, renderedDest, "markdown-deprecations", repo)
r_deprecations := changelog.NewRenderer(fs, c, renderedDest, "markdown-deprecations", repo, subsections)
if err := r_deprecations.Render(); err != nil {
return fmt.Errorf("cannot build markdown file: %w", err)
}
} else {
r := changelog.NewRenderer(fs, c, renderedDest, template, repo)
r := changelog.NewRenderer(fs, c, renderedDest, template, repo, subsections)
if err := r.Render(); err != nil {
return fmt.Errorf("cannot build file: %w", err)
}
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ When generating Markdown files, at a minimum you should set the following settin
| `owner` (required) | `elastic` | The owner of the GitHub repo. |
| `repo` (required) | ‒ | The name of the GitHub repo. |
| `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`. |
| `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). |

## Supported Environment Variables

Expand Down
5 changes: 3 additions & 2 deletions internal/assets/markdown-breaking-template.md.tmpl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
## {{.Version}} [{{.Repo}}-{{.Version}}-breaking-changes]
{{ if .BreakingChange -}}{{ range $k, $v := .BreakingChange }}{{ range $item := $v }}
{{ if .BreakingChange -}}{{ range $k, $v := .BreakingChange }}{{ $k | header2 }}{{ range $item := $v }}

::::{dropdown} {{ $item.Summary | beautify }}
{{ if $item.Description }}{{ $item.Description }}{{ end }}
{{ if $item.Description }}{{ $item.Description }}{{ else }}% Describe the functionality that changed{{ end }}

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

Expand Down
4 changes: 2 additions & 2 deletions internal/assets/markdown-deprecations-template.md.tmpl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## {{.Version}} [{{.Repo}}-{{.Version}}-deprecations]
{{ if .Deprecation -}}{{ range $k, $v := .Deprecation }}{{ range $item := $v }}
{{ if .Deprecation -}}{{ range $k, $v := .Deprecation }}{{ $k | header2 }}{{ range $item := $v }}

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

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

Expand Down
20 changes: 7 additions & 13 deletions internal/assets/markdown-index-template.md.tmpl
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
## {{.Version}} [{{.Repo}}-release-notes-{{.Version}}]
{{ if or .KnownIssue .BreakingChange .Deprecation }}
{{ other_links }}{{- end }}
{{ if or .Feature .Enhancement .Security .BugFix }}{{ if or .Feature .Enhancement }}
{{ if or .Feature .Enhancement .Security .BugFix }}
{{ if or .Feature .Enhancement }}
### Features and enhancements [{{.Repo}}-{{.Version}}-features-enhancements]
{{ if .Feature }}{{ range $k, $v := .Feature }}{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
{{ $item.Description | indent }}
{{- end }}
{{- end }}{{- end }}{{- end }}{{ if .Enhancement }}{{ range $k, $v := .Enhancement }}{{ range $item := $v }}
{{ $additions := combine .Feature .Enhancement }}{{ range $k, $v := $additions }}{{ header2 $k }}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
{{ $item.Description | indent }}
{{- end }}
{{- end }}{{- end }}{{- end }}
{{- end }}

{{ if or .Security .BugFix }}
### Fixes [{{.Repo}}-{{.Version}}-fixes]
{{ if .Security }}{{ range $k, $v := .Security }}{{ range $item := $v }}
{{ $fixes := combine .Security .BugFix }}{{ range $k, $v := $fixes }}{{ header2 $k }}
{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
{{ $item.Description | indent }}
{{- end }}
{{- end }}{{- end }}{{- end }}{{ if .BugFix }}{{ range $k, $v := .BugFix }}{{ range $item := $v }}
* {{ $item.Summary | beautify }} {{ linkPRSource $item.Component $item.LinkedPR }} {{ linkIssueSource $item.Component $item.LinkedIssue }}{{ if $item.Description }}
{{ $item.Description | indent }}
{{- end }}
{{- end }}{{- end }}{{- end }}{{- end }}
{{- end }}{{- end }}{{- end }}
{{ else }}
_No new features, enhancements, or fixes._
{{- end }}
56 changes: 39 additions & 17 deletions internal/changelog/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,20 @@ type Renderer struct {
changelog Changelog
fs afero.Fs
// dest is the destination location where the changelog is written to
dest string
templ string
repo string
dest string
templ string
repo string
subsections bool
}

func NewRenderer(fs afero.Fs, c Changelog, dest string, templ string, repo string) *Renderer {
func NewRenderer(fs afero.Fs, c Changelog, dest string, templ string, repo string, subsections bool) *Renderer {
return &Renderer{
changelog: c,
fs: fs,
dest: dest,
templ: templ,
repo: repo,
changelog: c,
fs: fs,
dest: dest,
templ: templ,
repo: repo,
subsections: subsections,
}
}

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

type TemplateData struct {
Component string
Version string
Repo string
Changelog Changelog
Kinds map[Kind]bool
Component string
Version string
Repo string
Changelog Changelog
Kinds map[Kind]bool
Subsections bool

// In Markdown, this goes to release notes
Enhancement map[string][]Entry
Expand All @@ -75,6 +78,7 @@ func (r Renderer) Render() error {
r.repo,
r.changelog,
collectKinds(r.changelog.Entries),
r.subsections,
// In Markdown, this goes to release notes
collectByKindMap(r.changelog.Entries, Enhancement),
collectByKindMap(r.changelog.Entries, Feature),
Expand Down Expand Up @@ -159,15 +163,33 @@ func (r Renderer) Render() error {
if len(links) > 0 {
return fmt.Sprintf(
"_This release also includes: %s._",
strings.Join(links, " and"),
strings.Join(links, " and "),
)
} else {
return ""
}
},
// Ensure components have section styling
"header2": func(s1 string) string {
return fmt.Sprintf("**%s**", s1)
"header2": func(s string) string {
if r.subsections {
s = strings.ToUpper(string(s[0])) + s[1:]
s = strings.ReplaceAll(s, "-", " ")
return fmt.Sprintf("\n\n**%s**", s)
} else {
return ""
}
},
"combine": func(map1 map[string][]Entry, map2 map[string][]Entry) map[string][]Entry {
combinedMap := make(map[string][]Entry)
// Start with a copy of map1 entries
for k, v := range map1 {
combinedMap[k] = append([]Entry{}, v...)
}
// Merge entries from map2, appending to any existing entries
for k, v := range map2 {
combinedMap[k] = append(combinedMap[k], v...)
}
return combinedMap
},
}).
Parse(string(tpl))
Expand Down
3 changes: 2 additions & 1 deletion internal/changelog/renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func TestRenderer(t *testing.T) {
filename := "0.0.0.yaml"
src := "testdata"
dest := viper.GetString("changelog_destination")
subsections := viper.GetBool("subsections")

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

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

err = r.Render()
require.Nil(t, err)
Expand Down
1 change: 1 addition & 0 deletions internal/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func setDefaults() {
viper.SetDefault("changelog_destination", "changelog")
viper.SetDefault("rendered_changelog_destination", "changelog")
viper.SetDefault("file_type", "markdown")
viper.SetDefault("subsections", false)
viper.SetDefault("template", "asciidoc-embedded")
}

Expand Down
Loading