1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-05 13:15:26 +02:00

feat: add changelog sorting (#2670)

Signed-off-by: Engin Diri <engin.diri@mail.schwarz>
This commit is contained in:
Engin Diri 2021-11-24 02:23:53 +01:00 committed by GitHub
parent 6a081264f1
commit 5ac11a1cba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 6 deletions

View File

@ -67,8 +67,40 @@ func (Pipe) Run(ctx *context.Context) error {
changelogElements := []string{
"## Changelog",
strings.Join(entries, changelogStringJoiner),
}
if len(ctx.Config.Changelog.Groups) > 0 {
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 len(group.Regexp) > 0 {
for i, entry := range entries {
match := checkEntryType(group.Regexp, entry)
if match {
items = append(items, entry)
// Striking out the matched entry
entries[i] = ""
}
}
} else {
// If no regexp is provided, we purge all strikethrough entries and add remaining entries to the list
items = deleteEmptyElement(entries)
// clear array
entries = nil
}
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(entries, changelogStringJoiner))
}
if header != "" {
changelogElements = append([]string{header}, changelogElements...)
}
@ -86,6 +118,22 @@ func (Pipe) Run(ctx *context.Context) error {
return os.WriteFile(path, []byte(ctx.ReleaseNotes), 0o644) //nolint: gosec
}
func deleteEmptyElement(s []string) []string {
var r []string
for _, str := range s {
if str != "" {
r = append(r, str)
}
}
return r
}
func checkEntryType(expr, entry string) bool {
regex, _ := regexp.Compile(expr)
match := regex.Match([]byte(entry))
return match
}
func loadFromFile(file string) (string, error) {
bts, err := os.ReadFile(file)
if err != nil {
@ -272,7 +320,7 @@ type gitChangeloger struct{}
var validSHA1 = regexp.MustCompile(`^[a-fA-F0-9]{40}$`)
func (g gitChangeloger) Log(ctx *context.Context, prev, current string) (string, error) {
func (g gitChangeloger) Log(_ *context.Context, prev, current string) (string, error) {
args := []string{"log", "--pretty=oneline", "--abbrev-commit", "--no-decorate", "--no-color"}
if validSHA1.MatchString(prev) {
args = append(args, prev, current)

View File

@ -559,3 +559,47 @@ func TestSkip(t *testing.T) {
require.False(t, Pipe{}.Skip(ctx))
})
}
func TestGroup(t *testing.T) {
folder := testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitCommit(t, "first")
testlib.GitTag(t, "v0.0.1")
testlib.GitCommit(t, "added feature 1")
testlib.GitCommit(t, "fixed bug 2")
testlib.GitCommit(t, "ignored: whatever")
testlib.GitCommit(t, "fix: whatever")
testlib.GitCommit(t, "docs: whatever")
testlib.GitCommit(t, "chore: something about cArs we dont need")
testlib.GitCommit(t, "feat: added that thing")
testlib.GitCommit(t, "bug: Merge pull request #999 from goreleaser/some-branch")
testlib.GitCommit(t, "this is not a Merge pull request")
testlib.GitTag(t, "v0.0.2")
ctx := context.New(config.Project{
Dist: folder,
Changelog: config.Changelog{
Groups: []config.ChangeLogGroup{
{
Title: "Features",
Regexp: "^.*feat[(\\w)]*:+.*$",
Order: 0,
},
{
Title: "Bug Fixes",
Regexp: "^.*bug[(\\w)]*:+.*$",
Order: 1,
},
{
Title: "Others",
Order: 999,
},
},
},
})
ctx.Git.CurrentTag = "v0.0.2"
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Contains(t, ctx.ReleaseNotes, "### Features")
require.Contains(t, ctx.ReleaseNotes, "### Bug Fixes")
require.Contains(t, ctx.ReleaseNotes, "### Others")
}

View File

@ -715,10 +715,18 @@ type Filters struct {
// Changelog Config.
type Changelog struct {
Filters Filters `yaml:"filters,omitempty"`
Sort string `yaml:"sort,omitempty"`
Skip bool `yaml:"skip,omitempty"` // TODO(caarlos0): rename to Disable to match other pipes
Use string `yaml:"use,omitempty"`
Filters Filters `yaml:"filters,omitempty"`
Sort string `yaml:"sort,omitempty"`
Skip bool `yaml:"skip,omitempty"` // TODO(caarlos0): rename to Disable to match other pipes
Use string `yaml:"use,omitempty"`
Groups []ChangeLogGroup `yaml:"groups,omitempty"`
}
// ChangeLogGroup holds the grouping criteria for the changelog.
type ChangeLogGroup struct {
Title string `yaml:"title,omitempty"`
Regexp string `yaml:"regexp,omitempty"`
Order int `yaml:"order,omitempty"`
}
// EnvFiles holds paths to files that contains environment variables

View File

@ -25,6 +25,20 @@ changelog:
# Default is empty
sort: asc
# Group commits messages by given regex and title.
# Order value defines the order of the groups.
# Proving no regex means all commits will be grouped under the default group.
# Default is no groups.
groups:
- title: Features
regexp: "^.*feat[(\\w)]*:+.*$"
order: 0
- title: 'Bug fixes'
regexp: "^.*fix[(\\w)]*:+.*$"
order: 1
- title: Others
order: 999
filters:
# Commit messages matching the regexp listed here will be removed from
# the changelog