diff --git a/internal/client/github.go b/internal/client/github.go index eccefb1bbbb..278bbfa9e44 100644 --- a/internal/client/github.go +++ b/internal/client/github.go @@ -13,7 +13,6 @@ import ( "github.com/caarlos0/log" "github.com/google/go-github/v47/github" "github.com/goreleaser/goreleaser/internal/artifact" - "github.com/goreleaser/goreleaser/internal/git" "github.com/goreleaser/goreleaser/internal/tmpl" "github.com/goreleaser/goreleaser/pkg/config" "github.com/goreleaser/goreleaser/pkg/context" @@ -64,17 +63,8 @@ func (c *githubClient) GenerateReleaseNotes(ctx *context.Context, repo Repo, pre return notes.Body, err } -func commitAbbrevLen(ctx *context.Context) int { - hash, err := git.Clean(git.Run(ctx, "rev-parse", "--short", "HEAD", "--quiet")) - if err != nil || len(hash) > 40 { - return 40 // max sha1 len - } - return len(hash) -} - func (c *githubClient) Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error) { var log []string - commitlen := commitAbbrevLen(ctx) opts := &github.ListOptions{PerPage: 100} for { @@ -85,7 +75,7 @@ func (c *githubClient) Changelog(ctx *context.Context, repo Repo, prev, current for _, commit := range result.Commits { log = append(log, fmt.Sprintf( "%s: %s (@%s)", - commit.GetSHA()[0:commitlen-1], + commit.GetSHA(), strings.Split(commit.Commit.GetMessage(), "\n")[0], commit.GetAuthor().GetLogin(), )) diff --git a/internal/client/github_test.go b/internal/client/github_test.go index 057fa413769..98340452703 100644 --- a/internal/client/github_test.go +++ b/internal/client/github_test.go @@ -289,7 +289,7 @@ func TestChangelog(t *testing.T) { log, err := client.Changelog(ctx, repo, "v1.0.0", "v1.1.0") require.NoError(t, err) - require.Equal(t, "6dcb09b: Fix all the bugs (@octocat)", log) + require.Equal(t, "6dcb09b5b57875f334f61aebed695e2e4193db5e: Fix all the bugs (@octocat)", log) } func TestReleaseNotes(t *testing.T) { diff --git a/internal/pipe/changelog/changelog.go b/internal/pipe/changelog/changelog.go index a234ad297df..8c384009365 100644 --- a/internal/pipe/changelog/changelog.go +++ b/internal/pipe/changelog/changelog.go @@ -114,6 +114,24 @@ func formatChangelog(ctx *context.Context, entries []string) (string, error) { return strings.Join(entries, newLine), nil } + for i := range entries { + entry := entries[i] + abbr := ctx.Config.Changelog.Abbrev + switch abbr { + case 0: + continue + case -1: + _, rest, _ := strings.Cut(entry, " ") + entries[i] = rest + default: + commit, rest, _ := strings.Cut(entry, " ") + if abbr > len(commit) { + continue + } + entries[i] = fmt.Sprintf("%s %s", commit[:abbr], rest) + } + } + result := []string{"## Changelog"} if len(ctx.Config.Changelog.Groups) == 0 { log.Debug("not grouping entries") diff --git a/internal/pipe/changelog/changelog_test.go b/internal/pipe/changelog/changelog_test.go index ce6492c07a5..55bc2deab4b 100644 --- a/internal/pipe/changelog/changelog_test.go +++ b/internal/pipe/changelog/changelog_test.go @@ -772,3 +772,90 @@ func TestChangelogFormat(t *testing.T) { } }) } + +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 := context.New(config.Project{ + Dist: folder, + Changelog: config.Changelog{}, + }) + ctx.Git.CurrentTag = "v0.0.2" + require.NoError(t, Pipe{}.Run(ctx)) + ensureCommitHashLen(t, ctx.ReleaseNotes, 7) + }) + + t.Run("abbrev -1", func(t *testing.T) { + ctx := context.New(config.Project{ + Dist: folder, + Changelog: config.Changelog{ + Abbrev: -1, + }, + }) + ctx.Git.CurrentTag = "v0.0.2" + require.NoError(t, Pipe{}.Run(ctx)) + }) + + t.Run("abbrev 3", func(t *testing.T) { + ctx := context.New(config.Project{ + Dist: folder, + Changelog: config.Changelog{ + Abbrev: 3, + }, + }) + ctx.Git.CurrentTag = "v0.0.2" + require.NoError(t, Pipe{}.Run(ctx)) + ensureCommitHashLen(t, ctx.ReleaseNotes, 3) + }) + + t.Run("abbrev 7", func(t *testing.T) { + ctx := context.New(config.Project{ + Dist: folder, + Changelog: config.Changelog{ + Abbrev: 7, + }, + }) + ctx.Git.CurrentTag = "v0.0.2" + require.NoError(t, Pipe{}.Run(ctx)) + ensureCommitHashLen(t, ctx.ReleaseNotes, 7) + }) + + t.Run("abbrev 40", func(t *testing.T) { + ctx := context.New(config.Project{ + Dist: folder, + Changelog: config.Changelog{ + Abbrev: 40, + }, + }) + ctx.Git.CurrentTag = "v0.0.2" + 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) + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 0bab72524f3..86407bfdc8e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -808,6 +808,7 @@ type Changelog struct { Skip bool `yaml:"skip,omitempty" json:"skip,omitempty"` // TODO(caarlos0): rename to Disable to match other pipes Use string `yaml:"use,omitempty" json:"use,omitempty" jsonschema:"enum=git,enum=github,enum=github-native,enum=gitlab,default=git"` Groups []ChangeLogGroup `yaml:"groups,omitempty" json:"groups,omitempty"` + Abbrev int `yaml:"abbrev,omitempty" json:"abbrev,omitempty"` } // ChangeLogGroup holds the grouping criteria for the changelog. diff --git a/www/docs/customization/changelog.md b/www/docs/customization/changelog.md index 65c6bc67701..343fd4a5236 100644 --- a/www/docs/customization/changelog.md +++ b/www/docs/customization/changelog.md @@ -27,6 +27,15 @@ changelog: # Default is empty sort: asc + # Max commit hash length to use in the changelog. + # + # 0: use whatever the changelog implementation gives you + # -1: remove the commit hash from the changelog + # any other number: max length. + # + # Default is 0. + abbrev: -1 + # 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.