Skip to content

Commit

Permalink
feat(changelog): omit version heading in forge release notes
Browse files Browse the repository at this point in the history
The forge ui usually shows the release name right above the description,
so this removes an unecessary duplicate bit of information.

In addition this also cleans up the changelog interface a bit and moves
functionality where it belongs. Prepares a bit for custom changelogs in
the future.

Closes #32
  • Loading branch information
apricote authored Sep 22, 2024
1 parent 997b649 commit 2621c48
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 35 deletions.
46 changes: 28 additions & 18 deletions internal/changelog/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,37 @@ func init() {
}
}

func NewChangelogEntry(logger *slog.Logger, commits []commitparser.AnalyzedCommit, version, link, prefix, suffix string) (string, error) {
features := make([]commitparser.AnalyzedCommit, 0)
fixes := make([]commitparser.AnalyzedCommit, 0)

for _, commit := range commits {
switch commit.Type {
case "feat":
features = append(features, commit)
case "fix":
fixes = append(fixes, commit)
}
func DefaultTemplate() *template.Template {
return changelogTemplate
}

type Data struct {
Commits map[string][]commitparser.AnalyzedCommit
Version string
VersionLink string
Prefix string
Suffix string
}

func New(commits map[string][]commitparser.AnalyzedCommit, version, versionLink, prefix, suffix string) Data {
return Data{
Commits: commits,
Version: version,
VersionLink: versionLink,
Prefix: prefix,
Suffix: suffix,
}
}

type Formatting struct {
HideVersionTitle bool
}

func Entry(logger *slog.Logger, tpl *template.Template, data Data, formatting Formatting) (string, error) {
var changelog bytes.Buffer
err := changelogTemplate.Execute(&changelog, map[string]any{
"Features": features,
"Fixes": fixes,
"Version": version,
"VersionLink": link,
"Prefix": prefix,
"Suffix": suffix,
err := tpl.Execute(&changelog, map[string]any{
"Data": data,
"Formatting": formatting,
})
if err != nil {
return "", err
Expand Down
28 changes: 15 additions & 13 deletions internal/changelog/changelog.md.tpl
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
## [{{.Version}}]({{.VersionLink}})
{{- if .Prefix }}
{{ .Prefix }}
{{define "entry" -}}
- {{ if .Scope }}**{{.Scope}}**: {{end}}{{.Description}}
{{ end }}

{{- if not .Formatting.HideVersionTitle }}
## [{{.Data.Version}}]({{.Data.VersionLink}})
{{ end -}}
{{- if .Data.Prefix }}
{{ .Data.Prefix }}
{{ end -}}
{{- if (gt (len .Features) 0) }}
{{- with .Data.Commits.feat }}
### Features

{{ range .Features -}}
- {{ if .Scope }}**{{.Scope}}**: {{end}}{{.Description}}
{{ end -}}
{{ range . -}}{{template "entry" .}}{{end}}
{{- end -}}
{{- if (gt (len .Fixes) 0) }}
{{- with .Data.Commits.fix }}
### Bug Fixes

{{ range .Fixes -}}
- {{ if .Scope }}**{{.Scope}}**: {{end}}{{.Description}}
{{ end -}}
{{ range . -}}{{template "entry" .}}{{end}}
{{- end -}}

{{- if .Suffix }}
{{ .Suffix }}
{{- if .Data.Suffix }}
{{ .Data.Suffix }}
{{ end }}
3 changes: 2 additions & 1 deletion internal/changelog/changelog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ This version is compatible with flux-compensator v2.2 - v2.9.

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewChangelogEntry(slog.Default(), tt.args.analyzedCommits, tt.args.version, tt.args.link, tt.args.prefix, tt.args.suffix)
data := New(commitparser.ByType(tt.args.analyzedCommits), tt.args.version, tt.args.link, tt.args.prefix, tt.args.suffix)
got, err := Entry(slog.Default(), DefaultTemplate(), data, Formatting{})
if !tt.wantErr(t, err) {
return
}
Expand Down
15 changes: 15 additions & 0 deletions internal/commitparser/commitparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,18 @@ type AnalyzedCommit struct {
Scope *string
BreakingChange bool
}

// ByType groups the Commits by the type field. Used by the Changelog.
func ByType(in []AnalyzedCommit) map[string][]AnalyzedCommit {
out := map[string][]AnalyzedCommit{}

for _, commit := range in {
if out[commit.Type] == nil {
out[commit.Type] = make([]AnalyzedCommit, 0, 1)
}

out[commit.Type] = append(out[commit.Type], commit)
}

return out
}
15 changes: 12 additions & 3 deletions releaserpleaser.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
return err
}

changelogEntry, err := changelog.NewChangelogEntry(logger, analyzedCommits, nextVersion, rp.forge.ReleaseURL(nextVersion), releaseOverrides.Prefix, releaseOverrides.Suffix)
changelogData := changelog.New(commitparser.ByType(analyzedCommits), nextVersion, rp.forge.ReleaseURL(nextVersion), releaseOverrides.Prefix, releaseOverrides.Suffix)

changelogEntry, err := changelog.Entry(logger, changelog.DefaultTemplate(), changelogData, changelog.Formatting{})
if err != nil {
return fmt.Errorf("failed to build changelog entry: %w", err)
}
Expand Down Expand Up @@ -289,9 +291,16 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
logger.InfoContext(ctx, "file content is already up-to-date in remote branch, skipping push")
}

// We do not need the version title here. In the pull request the version is available from the title, and in the
// release on the Forge its usually in a heading somewhere above the text.
changelogEntryPullRequest, err := changelog.Entry(logger, changelog.DefaultTemplate(), changelogData, changelog.Formatting{HideVersionTitle: true})
if err != nil {
return fmt.Errorf("failed to build pull request changelog entry: %w", err)
}

// Open/Update PR
if pr == nil {
pr, err = releasepr.NewReleasePullRequest(rpBranch, rp.targetBranch, nextVersion, changelogEntry)
pr, err = releasepr.NewReleasePullRequest(rpBranch, rp.targetBranch, nextVersion, changelogEntryPullRequest)
if err != nil {
return err
}
Expand All @@ -308,7 +317,7 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
if err != nil {
return err
}
err = pr.SetDescription(changelogEntry, overrides)
err = pr.SetDescription(changelogEntryPullRequest, overrides)
if err != nil {
return err
}
Expand Down

0 comments on commit 2621c48

Please sign in to comment.