1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-08 03:31:59 +02:00
goreleaser/internal/pipe/changelog/changelog_test.go
Carlos Alexandro Becker 82144cb2c0
test: improve file not found checkings (#3831)
using `errors.Is` everywhere, as file not found errors have different
messages on different OSes.
2023-03-04 12:16:26 -03:00

905 lines
25 KiB
Go

package changelog
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/testctx"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestChangelogProvidedViaFlag(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseNotesFile = "testdata/changes.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "c0ff33 coffeee\n", ctx.ReleaseNotes)
}
func TestChangelogProvidedViaFlagIsAWhitespaceOnlyFile(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseNotesFile = "testdata/changes-empty.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "\n", ctx.ReleaseNotes)
}
func TestChangelogProvidedViaFlagIsReallyEmpty(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseNotesFile = "testdata/changes-really-empty.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "", ctx.ReleaseNotes)
}
func TestChangelogTmplProvidedViaFlagIsReallyEmpty(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseNotesTmpl = "testdata/changes-really-empty.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "", ctx.ReleaseNotes)
}
func TestTemplatedChangelogProvidedViaFlag(t *testing.T) {
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
ctx.ReleaseNotesFile = "testdata/changes.md"
ctx.ReleaseNotesTmpl = "testdata/changes-templated.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "c0ff33 coffeee v0.0.1\n", ctx.ReleaseNotes)
}
func TestTemplatedChangelogProvidedViaFlagResultIsEmpty(t *testing.T) {
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
ctx.ReleaseNotesTmpl = "testdata/changes-templated-empty.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "\n\n", ctx.ReleaseNotes)
}
func TestChangelogProvidedViaFlagDoesntExist(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseNotesFile = "testdata/changes.nope"
require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist)
}
func TestReleaseHeaderProvidedViaFlagDoesntExist(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseHeaderFile = "testdata/header.nope"
require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist)
}
func TestReleaseFooterProvidedViaFlagDoesntExist(t *testing.T) {
ctx := testctx.New()
ctx.ReleaseFooterFile = "testdata/footer.nope"
require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist)
}
func TestChangelog(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, "docs: whatever")
testlib.GitCommit(t, "something about cArs we dont need")
testlib.GitCommit(t, "feat: added that thing")
testlib.GitCommit(t, "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 := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Use: "git",
Filters: config.Filters{
Exclude: []string{
"docs:",
"ignored:",
"(?i)cars",
"^Merge pull request",
},
},
},
}, testctx.WithCurrentTag("v0.0.2"), testctx.WithPreviousTag("v0.0.1"))
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.NotContains(t, ctx.ReleaseNotes, "first")
require.Contains(t, ctx.ReleaseNotes, "added feature 1")
require.Contains(t, ctx.ReleaseNotes, "fixed bug 2")
require.NotContains(t, ctx.ReleaseNotes, "docs")
require.NotContains(t, ctx.ReleaseNotes, "ignored")
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))
}
func TestChangelogForGitlab(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, "docs: whatever")
testlib.GitCommit(t, "something about cArs we dont need")
testlib.GitCommit(t, "feat: added that thing")
testlib.GitCommit(t, "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 := testctx.NewWithCfg(
config.Project{
Dist: folder,
Changelog: config.Changelog{
Filters: config.Filters{
Exclude: []string{
"docs:",
"ignored:",
"(?i)cars",
"^Merge pull request",
},
},
},
},
testctx.GitLabTokenType,
testctx.WithCurrentTag("v0.0.2"),
testctx.WithPreviousTag("v0.0.1"),
)
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.NotContains(t, ctx.ReleaseNotes, "first")
require.Contains(t, ctx.ReleaseNotes, "added feature 1") // no whitespace because its the last entry of the changelog
require.Contains(t, ctx.ReleaseNotes, "fixed bug 2 ") // whitespaces are on purpose
require.NotContains(t, ctx.ReleaseNotes, "docs")
require.NotContains(t, ctx.ReleaseNotes, "ignored")
require.NotContains(t, ctx.ReleaseNotes, "cArs")
require.NotContains(t, ctx.ReleaseNotes, "from goreleaser/some-branch")
bts, err := os.ReadFile(filepath.Join(folder, "CHANGELOG.md"))
require.NoError(t, err)
require.NotEmpty(t, string(bts))
}
func TestChangelogSort(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitCommit(t, "whatever")
testlib.GitTag(t, "v0.9.9")
testlib.GitCommit(t, "c: commit")
testlib.GitCommit(t, "a: commit")
testlib.GitCommit(t, "b: commit")
testlib.GitTag(t, "v1.0.0")
ctx := testctx.New(
testctx.WithCurrentTag("v1.0.0"),
testctx.WithPreviousTag("v0.9.9"),
)
for _, cfg := range []struct {
Sort string
Entries []string
}{
{
Sort: "",
Entries: []string{
"b: commit",
"a: commit",
"c: commit",
},
},
{
Sort: "asc",
Entries: []string{
"a: commit",
"b: commit",
"c: commit",
},
},
{
Sort: "desc",
Entries: []string{
"c: commit",
"b: commit",
"a: commit",
},
},
} {
t.Run("changelog sort='"+cfg.Sort+"'", func(t *testing.T) {
ctx.Config.Changelog.Sort = cfg.Sort
entries, err := buildChangelog(ctx)
require.NoError(t, err)
require.Len(t, entries, len(cfg.Entries))
var changes []string
for _, line := range entries {
changes = append(changes, extractCommitInfo(line))
}
require.EqualValues(t, cfg.Entries, changes)
})
}
}
func TestChangelogInvalidSort(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Sort: "dope",
},
})
require.EqualError(t, Pipe{}.Run(ctx), ErrInvalidSortDirection.Error())
}
func TestChangelogOfFirstRelease(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
for _, msg := range msgs {
require.Contains(t, ctx.ReleaseNotes, msg)
}
}
func TestChangelogFilterInvalidRegex(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitCommit(t, "commitssss")
testlib.GitTag(t, "v0.0.3")
testlib.GitCommit(t, "commitzzz")
testlib.GitTag(t, "v0.0.4")
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Filters: config.Filters{
Exclude: []string{
"(?iasdr4qasd)not a valid regex i guess",
},
},
},
}, testctx.WithCurrentTag("v0.0.4"), testctx.WithPreviousTag("v0.0.3"))
require.EqualError(t, Pipe{}.Run(ctx), "error parsing regexp: invalid or unsupported Perl syntax: `(?ia`")
}
func TestChangelogNoTags(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitCommit(t, "first")
ctx := testctx.New()
require.Error(t, Pipe{}.Run(ctx))
require.Empty(t, ctx.ReleaseNotes)
}
func TestChangelogOnBranchWithSameNameAsTag(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
testlib.GitCheckoutBranch(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
for _, msg := range msgs {
require.Contains(t, ctx.ReleaseNotes, msg)
}
}
func TestChangeLogWithReleaseHeader(t *testing.T) {
current, err := os.Getwd()
require.NoError(t, err)
tmpdir := testlib.Mktmp(t)
require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
testlib.GitCheckoutBranch(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
ctx.ReleaseHeaderFile = "testdata/release-header.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Contains(t, ctx.ReleaseNotes, "test header")
}
func TestChangeLogWithTemplatedReleaseHeader(t *testing.T) {
current, err := os.Getwd()
require.NoError(t, err)
tmpdir := testlib.Mktmp(t)
require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
testlib.GitCheckoutBranch(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
ctx.ReleaseHeaderTmpl = "testdata/release-header-templated.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Contains(t, ctx.ReleaseNotes, "test header with tag v0.0.1")
}
func TestChangeLogWithReleaseFooter(t *testing.T) {
current, err := os.Getwd()
require.NoError(t, err)
tmpdir := testlib.Mktmp(t)
require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
testlib.GitCheckoutBranch(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
ctx.ReleaseFooterFile = "testdata/release-footer.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Contains(t, ctx.ReleaseNotes, "test footer")
require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
}
func TestChangeLogWithTemplatedReleaseFooter(t *testing.T) {
current, err := os.Getwd()
require.NoError(t, err)
tmpdir := testlib.Mktmp(t)
require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
testlib.GitCheckoutBranch(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
ctx.ReleaseFooterTmpl = "testdata/release-footer-templated.md"
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Contains(t, ctx.ReleaseNotes, "test footer with tag v0.0.1")
require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
}
func TestChangeLogWithoutReleaseFooter(t *testing.T) {
current, err := os.Getwd()
require.NoError(t, err)
tmpdir := testlib.Mktmp(t)
require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
testlib.GitInit(t)
msgs := []string{
"initial commit",
"another one",
"one more",
"and finally this one",
}
for _, msg := range msgs {
testlib.GitCommit(t, msg)
}
testlib.GitTag(t, "v0.0.1")
testlib.GitCheckoutBranch(t, "v0.0.1")
ctx := testctx.New(testctx.WithCurrentTag("v0.0.1"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
}
func TestGetChangelogGitHub(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHub,
},
}, testctx.WithCurrentTag("v0.180.2"), testctx.WithPreviousTag("v0.180.1"))
expected := "c90f1085f255d0af0b055160bfff5ee40f47af79: fix: do not skip any defaults (#2521) (@caarlos0)"
mock := client.NewMock()
mock.Changes = expected
l := scmChangeloger{
client: mock,
repo: client.Repo{
Owner: "goreleaser",
Name: "goreleaser",
},
}
log, err := l.Log(ctx)
require.NoError(t, err)
require.Equal(t, expected, log)
}
func TestGetChangelogGitHubNative(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHubNative,
},
}, testctx.WithCurrentTag("v0.180.2"), testctx.WithPreviousTag("v0.180.1"))
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.ReleaseNotes = expected
l := githubNativeChangeloger{
client: mock,
repo: client.Repo{
Owner: "goreleaser",
Name: "goreleaser",
},
}
log, err := l.Log(ctx)
require.NoError(t, err)
require.Equal(t, expected, log)
require.Equal(t, []string{"v0.180.1", "v0.180.2"}, mock.ReleaseNotesParams)
}
func TestGetChangelogGitHubNativeFirstRelease(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHubNative,
},
}, testctx.WithCurrentTag("v0.1.0"))
expected := `## What's changed
* Foo bar test
**Full Changelog**: https://github.com/gorelease/goreleaser/commits/v0.1.0
`
mock := client.NewMock()
mock.ReleaseNotes = expected
l := githubNativeChangeloger{
client: mock,
repo: client.Repo{
Owner: "goreleaser",
Name: "goreleaser",
},
}
log, err := l.Log(ctx)
require.NoError(t, err)
require.Equal(t, expected, log)
require.Equal(t, []string{"", "v0.1.0"}, mock.ReleaseNotesParams)
}
func TestGetChangeloger(t *testing.T) {
t.Run("default", func(t *testing.T) {
c, err := getChangeloger(testctx.New())
require.NoError(t, err)
require.IsType(t, c, gitChangeloger{})
})
t.Run(useGit, func(t *testing.T) {
c, err := getChangeloger(testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGit,
},
}))
require.NoError(t, err)
require.IsType(t, c, gitChangeloger{})
})
t.Run(useGitHub, func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHub,
},
}, testctx.GitHubTokenType)
c, err := getChangeloger(ctx)
require.NoError(t, err)
require.IsType(t, c, &scmChangeloger{})
})
t.Run(useGitHubNative, func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHubNative,
},
}, testctx.GitHubTokenType)
c, err := getChangeloger(ctx)
require.NoError(t, err)
require.IsType(t, c, &githubNativeChangeloger{})
})
t.Run(useGitHubNative+"-invalid-repo", func(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "https://gist.github.com/")
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHubNative,
},
}, testctx.GitHubTokenType)
c, err := getChangeloger(ctx)
require.EqualError(t, err, "unsupported repository URL: https://gist.github.com/")
require.Nil(t, c)
})
t.Run(useGitLab, func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitLab,
},
}, testctx.GitHubTokenType)
c, err := getChangeloger(ctx)
require.NoError(t, err)
require.IsType(t, c, &scmChangeloger{})
})
t.Run(useGitHub+"-invalid-repo", func(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "https://gist.github.com/")
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: useGitHub,
},
}, testctx.GitHubTokenType)
c, err := getChangeloger(ctx)
require.EqualError(t, err, "unsupported repository URL: https://gist.github.com/")
require.Nil(t, c)
})
t.Run("invalid", func(t *testing.T) {
c, err := getChangeloger(testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Use: "nope",
},
}))
require.EqualError(t, err, `invalid changelog.use: "nope"`)
require.Nil(t, c)
})
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
ctx := testctx.New(testctx.Snapshot)
b, err := Pipe{}.Skip(ctx)
require.NoError(t, err)
require.True(t, b)
})
t.Run("skip on patches", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Skip: "{{gt .Patch 0}}",
},
}, testctx.WithSemver(0, 0, 1, ""))
b, err := Pipe{}.Skip(ctx)
require.NoError(t, err)
require.True(t, b)
})
t.Run("invalid template", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Skip: "{{if eq .Patch 123}",
},
}, testctx.WithSemver(0, 0, 1, ""))
_, err := Pipe{}.Skip(ctx)
require.Error(t, err)
})
t.Run("dont skip", func(t *testing.T) {
b, err := Pipe{}.Skip(testctx.New())
require.NoError(t, err)
require.False(t, b)
})
t.Run("dont skip based on template", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Changelog: config.Changelog{
Skip: "{{gt .Patch 0}}",
},
})
b, err := Pipe{}.Skip(ctx)
require.NoError(t, err)
require.False(t, b)
})
}
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, "feat(deps): update foobar [bot]")
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 := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Groups: []config.ChangelogGroup{
{
Title: "Bots",
Regexp: ".*bot.*",
Order: 900,
},
{
Title: "Features",
Regexp: `^.*?feat(\([[:word:]]+\))??!?:.+$`,
Order: 0,
},
{
Title: "Bug Fixes",
Regexp: `^.*?bug(\([[:word:]]+\))??!?:.+$`,
Order: 1,
},
{
Title: "Catch nothing",
Regexp: "yada yada yada honk the planet",
Order: 10,
},
{
Title: "Others",
Order: 999,
},
},
},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Contains(t, ctx.ReleaseNotes, "### Bots")
require.Contains(t, ctx.ReleaseNotes, "### Features")
require.Contains(t, ctx.ReleaseNotes, "### Bug Fixes")
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 := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Groups: []config.ChangelogGroup{
{
Title: "Something",
Regexp: "^.*feat[a-z", // unterminated regex
},
},
},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.EqualError(t, Pipe{}.Run(ctx), "failed to group into \"Something\": error parsing regexp: missing closing ]: `[a-z`")
}
func TestChangelogFormat(t *testing.T) {
t.Run("without groups", func(t *testing.T) {
makeConf := func(u string) config.Project {
return config.Project{Changelog: config.Changelog{Use: u}}
}
for _, use := range []string{useGit, useGitHub, useGitLab} {
t.Run(use, func(t *testing.T) {
out, err := formatChangelog(
testctx.NewWithCfg(makeConf(use)),
[]string{
"aea123 foo",
"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(
testctx.NewWithCfg(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("with groups", func(t *testing.T) {
makeConf := func(u string) config.Project {
return config.Project{
Changelog: config.Changelog{
Use: u,
Groups: []config.ChangelogGroup{
{Title: "catch-all"},
},
},
}
}
t.Run(useGitHubNative, func(t *testing.T) {
out, err := formatChangelog(
testctx.NewWithCfg(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(
testctx.NewWithCfg(makeConf(use)),
[]string{
"aea123 foo",
"aef653 bar",
},
)
require.NoError(t, err)
require.Equal(t, `## Changelog
### catch-all
* aea123 foo
* aef653 bar`, out)
})
}
})
}
func TestAbbrev(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, "feat(deps): update foobar [bot]")
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")
t.Run("no abbrev", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
ensureCommitHashLen(t, ctx.ReleaseNotes, 7)
})
t.Run("abbrev -1", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Abbrev: -1,
},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
})
t.Run("abbrev 3", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Abbrev: 3,
},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
ensureCommitHashLen(t, ctx.ReleaseNotes, 3)
})
t.Run("abbrev 7", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Abbrev: 7,
},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
ensureCommitHashLen(t, ctx.ReleaseNotes, 7)
})
t.Run("abbrev 40", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: folder,
Changelog: config.Changelog{
Abbrev: 40,
},
}, testctx.WithCurrentTag("v0.0.2"), withFirstCommit(t))
require.NoError(t, Pipe{}.Run(ctx))
ensureCommitHashLen(t, ctx.ReleaseNotes, 7)
})
}
func ensureCommitHashLen(tb testing.TB, log string, l int) {
tb.Helper()
for _, line := range strings.Split(log, "\n") {
if strings.HasPrefix(line, "#") || strings.TrimSpace(line) == "" {
continue
}
parts := strings.SplitN(line, " ", 3)
commit := strings.TrimPrefix(parts[1], "* ")
require.Len(tb, commit, l)
}
}
func withFirstCommit(tb testing.TB) testctx.Opt {
tb.Helper()
return func(ctx *context.Context) {
s, err := git.Clean(git.Run(testctx.New(), "rev-list", "--max-parents=0", "HEAD"))
require.NoError(tb, err)
ctx.Git.FirstCommit = s
}
}