1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-06-02 23:27:44 +02:00

fix: do not filter and sort github-native changelog (#2803)

* fix: do not filter and sort github-native

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>

* refactor: improve code a bit

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>

* refactor: improve code a bit

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>

* fix: changelog header

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
This commit is contained in:
Carlos Alexandro Becker 2022-01-08 09:24:36 -03:00 committed by GitHub
parent 72535f288c
commit bdfb09cfb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 166 additions and 86 deletions

View File

@ -14,7 +14,6 @@ import (
"github.com/goreleaser/goreleaser/internal/client" "github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/git" "github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/tmpl" "github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/context"
) )
@ -23,6 +22,19 @@ var ErrInvalidSortDirection = errors.New("invalid sort direction")
const li = "* " const li = "* "
type useChangelog string
func (u useChangelog) formatable() bool {
return u != "github-native"
}
const (
useGit = "git"
useGitHub = "github"
useGitLab = "gitlab"
useGitHubNative = "github-native"
)
// Pipe for checksums. // Pipe for checksums.
type Pipe struct{} type Pipe struct{}
@ -60,55 +72,11 @@ func (Pipe) Run(ctx *context.Context) error {
return err return err
} }
changelogStringJoiner := "\n" changes, err := formatChangelog(ctx, entries)
if ctx.TokenType == context.TokenTypeGitLab || ctx.TokenType == context.TokenTypeGitea { if err != nil {
// We need two or more whitespace to let markdown interpret return err
// it as newline. See https://docs.gitlab.com/ee/user/markdown.html#newlines for details
log.Debug("is gitlab or gitea changelog")
changelogStringJoiner = " \n"
}
changelogElements := []string{
"## Changelog",
}
if ctx.Config.Changelog.Use == "github-native" {
changelogElements = []string{strings.Join(entries, changelogStringJoiner)}
} else if shouldGroup(ctx.Config.Changelog) {
log.Debug("grouping entries")
groups := ctx.Config.Changelog.Groups
sort.Slice(groups, func(i, j int) bool { return groups[i].Order < groups[j].Order })
for _, group := range groups {
items := make([]string, 0)
if group.Regexp == "" {
// If no regexp is provided, we purge all strikethrough entries and add remaining entries to the list
items = getAllNonEmpty(entries)
// clear array
entries = nil
} else {
regex, err := regexp.Compile(group.Regexp)
if err != nil {
return fmt.Errorf("failed to group into %q: %w", group.Title, err)
}
for i, entry := range entries {
match := regex.MatchString(entry)
if match {
items = append(items, li+entry)
// Striking out the matched entry
entries[i] = ""
}
}
}
if len(items) > 0 {
changelogElements = append(changelogElements, fmt.Sprintf("### %s", group.Title))
changelogElements = append(changelogElements, strings.Join(items, changelogStringJoiner))
}
}
} else {
log.Debug("not grouping entries")
changelogElements = append(changelogElements, strings.Join(getAllNonEmpty(entries), changelogStringJoiner))
} }
changelogElements := []string{changes}
if header != "" { if header != "" {
changelogElements = append([]string{header}, changelogElements...) changelogElements = append([]string{header}, changelogElements...)
@ -127,11 +95,60 @@ func (Pipe) Run(ctx *context.Context) error {
return os.WriteFile(path, []byte(ctx.ReleaseNotes), 0o644) //nolint: gosec return os.WriteFile(path, []byte(ctx.ReleaseNotes), 0o644) //nolint: gosec
} }
func shouldGroup(cfg config.Changelog) bool { func formatChangelog(ctx *context.Context, entries []string) (string, error) {
return len(cfg.Groups) > 0 && cfg.Use != "github-native" newLine := "\n"
if ctx.TokenType == context.TokenTypeGitLab || ctx.TokenType == context.TokenTypeGitea {
// We need two or more whitespace to let markdown interpret
// it as newline. See https://docs.gitlab.com/ee/user/markdown.html#newlines for details
log.Debug("is gitlab or gitea changelog")
newLine = " \n"
}
if !useChangelog(ctx.Config.Changelog.Use).formatable() {
return strings.Join(entries, newLine), nil
}
result := []string{"## Changelog"}
if len(ctx.Config.Changelog.Groups) == 0 {
log.Debug("not grouping entries")
return strings.Join(append(result, filterAndPrefixItems(entries)...), newLine), nil
}
log.Debug("grouping entries")
groups := ctx.Config.Changelog.Groups
sort.Slice(groups, func(i, j int) bool { return groups[i].Order < groups[j].Order })
for _, group := range groups {
items := make([]string, 0)
if group.Regexp == "" {
// If no regexp is provided, we purge all strikethrough entries and add remaining entries to the list
items = filterAndPrefixItems(entries)
// clear array
entries = nil
} else {
regex, err := regexp.Compile(group.Regexp)
if err != nil {
return "", fmt.Errorf("failed to group into %q: %w", group.Title, err)
}
for i, entry := range entries {
match := regex.MatchString(entry)
if match {
items = append(items, li+entry)
// Striking out the matched entry
entries[i] = ""
}
}
}
if len(items) > 0 {
result = append(result, fmt.Sprintf("### %s", group.Title))
result = append(result, items...)
}
}
return strings.Join(result, newLine), nil
} }
func getAllNonEmpty(ss []string) []string { func filterAndPrefixItems(ss []string) []string {
var r []string var r []string
for _, s := range ss { for _, s := range ss {
if s != "" { if s != "" {
@ -171,6 +188,9 @@ func buildChangelog(ctx *context.Context) ([]string, error) {
if lastLine := entries[len(entries)-1]; strings.TrimSpace(lastLine) == "" { if lastLine := entries[len(entries)-1]; strings.TrimSpace(lastLine) == "" {
entries = entries[0 : len(entries)-1] entries = entries[0 : len(entries)-1]
} }
if !useChangelog(ctx.Config.Changelog.Use).formatable() {
return entries, nil
}
entries, err = filterEntries(ctx, entries) entries, err = filterEntries(ctx, entries)
if err != nil { if err != nil {
return entries, err return entries, err
@ -243,15 +263,15 @@ func doGetChangelog(ctx *context.Context, prev, tag string) (string, error) {
func getChangeloger(ctx *context.Context) (changeloger, error) { func getChangeloger(ctx *context.Context) (changeloger, error) {
switch ctx.Config.Changelog.Use { switch ctx.Config.Changelog.Use {
case "git": case useGit:
fallthrough fallthrough
case "": case "":
return gitChangeloger{}, nil return gitChangeloger{}, nil
case "github": case useGitHub:
fallthrough fallthrough
case "gitlab": case useGitLab:
return newSCMChangeloger(ctx) return newSCMChangeloger(ctx)
case "github-native": case useGitHubNative:
return newGithubChangeloger(ctx) return newGithubChangeloger(ctx)
default: default:
return nil, fmt.Errorf("invalid changelog.use: %q", ctx.Config.Changelog.Use) return nil, fmt.Errorf("invalid changelog.use: %q", ctx.Config.Changelog.Use)

View File

@ -69,6 +69,7 @@ func TestChangelog(t *testing.T) {
ctx := context.New(config.Project{ ctx := context.New(config.Project{
Dist: folder, Dist: folder,
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "git",
Filters: config.Filters{ Filters: config.Filters{
Exclude: []string{ Exclude: []string{
"docs:", "docs:",
@ -419,7 +420,7 @@ func TestChangeLogWithoutReleaseFooter(t *testing.T) {
func TestGetChangelogGitHub(t *testing.T) { func TestGetChangelogGitHub(t *testing.T) {
ctx := context.New(config.Project{ ctx := context.New(config.Project{
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "github", Use: useGitHub,
}, },
}) })
@ -441,11 +442,16 @@ func TestGetChangelogGitHub(t *testing.T) {
func TestGetChangelogGitHubNative(t *testing.T) { func TestGetChangelogGitHubNative(t *testing.T) {
ctx := context.New(config.Project{ ctx := context.New(config.Project{
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "github-native", Use: useGitHubNative,
}, },
}) })
expected := "**Full Changelog**: https://github.com/gorelease/goreleaser/compare/v0.180.1...v0.180.2" expected := `## What's changed
* Foo bar test
**Full Changelog**: https://github.com/gorelease/goreleaser/compare/v0.180.1...v0.180.2
`
mock := client.NewMock() mock := client.NewMock()
mock.ReleaseNotes = expected mock.ReleaseNotes = expected
l := githubNativeChangeloger{ l := githubNativeChangeloger{
@ -467,20 +473,20 @@ func TestGetChangeloger(t *testing.T) {
require.IsType(t, c, gitChangeloger{}) require.IsType(t, c, gitChangeloger{})
}) })
t.Run("git", func(t *testing.T) { t.Run(useGit, func(t *testing.T) {
c, err := getChangeloger(context.New(config.Project{ c, err := getChangeloger(context.New(config.Project{
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "git", Use: useGit,
}, },
})) }))
require.NoError(t, err) require.NoError(t, err)
require.IsType(t, c, gitChangeloger{}) require.IsType(t, c, gitChangeloger{})
}) })
t.Run("github", func(t *testing.T) { t.Run(useGitHub, func(t *testing.T) {
ctx := context.New(config.Project{ ctx := context.New(config.Project{
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "github", Use: useGitHub,
}, },
}) })
ctx.TokenType = context.TokenTypeGitHub ctx.TokenType = context.TokenTypeGitHub
@ -489,10 +495,10 @@ func TestGetChangeloger(t *testing.T) {
require.IsType(t, c, &scmChangeloger{}) require.IsType(t, c, &scmChangeloger{})
}) })
t.Run("github-native", func(t *testing.T) { t.Run(useGitHubNative, func(t *testing.T) {
ctx := context.New(config.Project{ ctx := context.New(config.Project{
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "github-native", Use: useGitHubNative,
}, },
}) })
ctx.TokenType = context.TokenTypeGitHub ctx.TokenType = context.TokenTypeGitHub
@ -501,10 +507,10 @@ func TestGetChangeloger(t *testing.T) {
require.IsType(t, c, &githubNativeChangeloger{}) require.IsType(t, c, &githubNativeChangeloger{})
}) })
t.Run("gitlab", func(t *testing.T) { t.Run(useGitLab, func(t *testing.T) {
ctx := context.New(config.Project{ ctx := context.New(config.Project{
Changelog: config.Changelog{ Changelog: config.Changelog{
Use: "gitlab", Use: useGitLab,
}, },
}) })
ctx.TokenType = context.TokenTypeGitLab ctx.TokenType = context.TokenTypeGitLab
@ -617,30 +623,84 @@ func TestGroupBadRegex(t *testing.T) {
require.EqualError(t, Pipe{}.Run(ctx), `failed to group into "Something": error parsing regexp: missing closing ]: `+"`"+`[(\w`+"`") require.EqualError(t, Pipe{}.Run(ctx), `failed to group into "Something": error parsing regexp: missing closing ]: `+"`"+`[(\w`+"`")
} }
func TestShouldGroup(t *testing.T) { func TestChangelogFormat(t *testing.T) {
t.Run("with groups", func(t *testing.T) { t.Run("without groups", func(t *testing.T) {
t.Run("github-native", func(t *testing.T) { makeConf := func(u string) config.Project {
require.False(t, shouldGroup(config.Changelog{ return config.Project{Changelog: config.Changelog{Use: u}}
Use: "github-native", }
Groups: []config.ChangeLogGroup{{}},
})) for _, use := range []string{useGit, useGitHub, useGitLab} {
}) t.Run(use, func(t *testing.T) {
for _, u := range []string{"git", "github", "gitlab"} { out, err := formatChangelog(
t.Run(u, func(t *testing.T) { context.New(makeConf(use)),
require.True(t, shouldGroup(config.Changelog{ []string{
Use: u, "aea123 foo",
Groups: []config.ChangeLogGroup{{}}, "aef653 bar",
})) },
)
require.NoError(t, err)
require.Equal(t, `## Changelog
* aea123 foo
* aef653 bar`, out)
}) })
} }
t.Run(useGitHubNative, func(t *testing.T) {
out, err := formatChangelog(
context.New(makeConf(useGitHubNative)),
[]string{
"# What's changed",
"* aea123 foo",
"* aef653 bar",
},
)
require.NoError(t, err)
require.Equal(t, `# What's changed
* aea123 foo
* aef653 bar`, out)
})
}) })
t.Run("without groups", func(t *testing.T) { t.Run("with groups", func(t *testing.T) {
for _, u := range []string{"git", "github", "gitlab", "github-native"} { makeConf := func(u string) config.Project {
t.Run(u, func(t *testing.T) { return config.Project{
require.False(t, shouldGroup(config.Changelog{ Changelog: config.Changelog{
Use: u, Use: u,
})) Groups: []config.ChangeLogGroup{
{Title: "catch-all"},
},
},
}
}
t.Run(useGitHubNative, func(t *testing.T) {
out, err := formatChangelog(
context.New(makeConf(useGitHubNative)),
[]string{
"# What's changed",
"* aea123 foo",
"* aef653 bar",
},
)
require.NoError(t, err)
require.Equal(t, `# What's changed
* aea123 foo
* aef653 bar`, out)
})
for _, use := range []string{useGit, useGitHub, useGitLab} {
t.Run(use, func(t *testing.T) {
out, err := formatChangelog(
context.New(makeConf(use)),
[]string{
"aea123 foo",
"aef653 bar",
},
)
require.NoError(t, err)
require.Equal(t, `## Changelog
### catch-all
* aea123 foo
* aef653 bar`, out)
}) })
} }
}) })