Repository: goreleaser/goreleaser
Pull request #2695 (2021-11-24 02:30:17)

feat: make each changelog commit a list item
Made a few changes here:

- commits are now list items (someone asked this, I always wanted to do this, don't see why not as it looks better)
- refactor some code from #2670
  - compile each regex only once
  - rename method
  - check if regex is valid and error otherwise
    - also added a test for this

cc/ @dirien 

-------

###### example output:

```
## Changelog

### New Features

* 81c53073a4d4b638cec836ccb6cee78052695b3a: feat(ci): add cosign public key to releases (#2636) (@erkanzileli)
* a94e28b77c40d0ff483f618e77d2defdc637e54f: feat(deps): bump golang from 1.17.2-alpine to 1.17.3-alpine (#2632) (@dependabot[bot])

### Bug fixes

* 1e718d2db0a612fe79e25292889c9ca10a97e563: Revert "fix: armv7 on linux is usually armv7l" (@caarlos0)
* c958e4cc5e18073116881a7dd79355ca9197871a: fix: changelog is too long (#2661) (@dirien)

### Other work

* 048557efdb35d87f628ff1206ebff48b44229075: Merge remote-tracking branch 'origin/main' (@caarlos0)
* cf73ede93248e0de9a3a1cc6e5d12f03d4492b7d: refactor: improve changelog code (@caarlos0)
```

codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) Report
> Merging [#2695](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (2dcbc0a) into [main](https://codecov.io/gh/goreleaser/goreleaser/commit/419b6fc7d26265dcf3ff8382c67d064b74535347?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (419b6fc) will **decrease** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/goreleaser/pull/2695/graphs/tree.svg?width=650&height=150&src=pr&token=3bJvv6b7hN&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)

```diff
@@            Coverage Diff             @@
##             main    #2695      +/-   ##
==========================================
- Coverage   84.76%   84.76%   -0.01%     
==========================================
  Files         103      103              
  Lines        7883     7882       -1     
==========================================
- Hits         6682     6681       -1     
  Misses        985      985              
  Partials      216      216              
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | Coverage Δ | |
|---|---|---|
| [internal/pipe/changelog/changelog.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2695/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9jaGFuZ2Vsb2cvY2hhbmdlbG9nLmdv) | `91.35% <100.00%> (-0.04%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Last update [419b6fc...2dcbc0a](https://codecov.io/gh/goreleaser/goreleaser/pull/2695?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).


Patch:
diff --git a/internal/pipe/changelog/changelog.go b/internal/pipe/changelog/changelog.go
index 655ab0ee..fc891934 100644
--- a/internal/pipe/changelog/changelog.go
+++ b/internal/pipe/changelog/changelog.go
@@ -20,6 +20,8 @@ import (
 // ErrInvalidSortDirection happens when the sort order is invalid.
 var ErrInvalidSortDirection = errors.New("invalid sort direction")
 
+const li = "* "
+
 // Pipe for checksums.
 type Pipe struct{}
 
@@ -76,20 +78,24 @@ func (Pipe) Run(ctx *context.Context) error {
 		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 {
+			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 := checkEntryType(group.Regexp, entry)
+					match := regex.MatchString(entry)
 					if match {
-						items = append(items, entry)
+						items = append(items, li+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))
@@ -98,7 +104,7 @@ func (Pipe) Run(ctx *context.Context) error {
 		}
 	} else {
 		log.Debug("not grouping entries")
-		changelogElements = append(changelogElements, strings.Join(entries, changelogStringJoiner))
+		changelogElements = append(changelogElements, strings.Join(getAllNonEmpty(entries), changelogStringJoiner))
 	}
 
 	if header != "" {
@@ -118,22 +124,16 @@ func (Pipe) Run(ctx *context.Context) error {
 	return os.WriteFile(path, []byte(ctx.ReleaseNotes), 0o644) //nolint: gosec
 }
 
-func deleteEmptyElement(s []string) []string {
+func getAllNonEmpty(ss []string) []string {
 	var r []string
-	for _, str := range s {
-		if str != "" {
-			r = append(r, str)
+	for _, s := range ss {
+		if s != "" {
+			r = append(r, li+s)
 		}
 	}
 	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 {


Test patch:
diff --git a/internal/pipe/changelog/changelog_test.go b/internal/pipe/changelog/changelog_test.go
index d04d7438..3f95e6a1 100644
--- a/internal/pipe/changelog/changelog_test.go
+++ b/internal/pipe/changelog/changelog_test.go
@@ -3,6 +3,7 @@ package changelog
 import (
 	"os"
 	"path/filepath"
+	"strings"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -89,6 +90,13 @@ func TestChangelog(t *testing.T) {
 	require.NotContains(t, ctx.ReleaseNotes, "cArs")
 	require.NotContains(t, ctx.ReleaseNotes, "from goreleaser/some-branch")
 
+	for _, line := range strings.Split(ctx.ReleaseNotes, "\n")[1:] {
+		if line == "" {
+			continue
+		}
+		require.Truef(t, strings.HasPrefix(line, "* "), "%q: changelog commit must be a list item", line)
+	}
+
 	bts, err := os.ReadFile(filepath.Join(folder, "CHANGELOG.md"))
 	require.NoError(t, err)
 	require.NotEmpty(t, string(bts))
@@ -609,3 +617,24 @@ func TestGroup(t *testing.T) {
 	require.NotContains(t, ctx.ReleaseNotes, "### Catch nothing")
 	require.Contains(t, ctx.ReleaseNotes, "### Others")
 }
+
+func TestGroupBadRegex(t *testing.T) {
+	folder := testlib.Mktmp(t)
+	testlib.GitInit(t)
+	testlib.GitCommit(t, "first")
+	testlib.GitTag(t, "v0.0.1")
+	testlib.GitTag(t, "v0.0.2")
+	ctx := context.New(config.Project{
+		Dist: folder,
+		Changelog: config.Changelog{
+			Groups: []config.ChangeLogGroup{
+				{
+					Title:  "Something",
+					Regexp: "^.*feat[(\\w", // unterminated regex
+				},
+			},
+		},
+	})
+	ctx.Git.CurrentTag = "v0.0.2"
+	require.EqualError(t, Pipe{}.Run(ctx), `failed to group into "Something": error parsing regexp: missing closing ]: `+"`"+`[(\w`+"`")
+}