mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-26 04:22:05 +02:00
feat: changelog from github (#2548)
* feat: changelog from github Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * refactor: unifying client mocks Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * refactor: unifying client mocks Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: mocks Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * test: added tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: remove unused code Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * test: added more Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: testdata Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: fmt Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: improve docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
This commit is contained in:
parent
c739724f12
commit
89e5a4ebf1
@ -35,6 +35,7 @@ checksum:
|
||||
|
||||
changelog:
|
||||
sort: asc
|
||||
use: github
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
|
@ -12,6 +12,9 @@ import (
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
// ErrNotImplemented is returned when a client does not implement certain feature.
|
||||
var ErrNotImplemented = fmt.Errorf("not implemented")
|
||||
|
||||
// Info of the repository.
|
||||
type Info struct {
|
||||
Description string
|
||||
@ -40,6 +43,7 @@ type Client interface {
|
||||
CreateFile(ctx *context.Context, commitAuthor config.CommitAuthor, repo Repo, content []byte, path, message string) (err error)
|
||||
Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error)
|
||||
GetDefaultBranch(ctx *context.Context, repo Repo) (string, error)
|
||||
Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error)
|
||||
}
|
||||
|
||||
// New creates a new client depending on the token type.
|
||||
@ -56,8 +60,6 @@ func newWithToken(ctx *context.Context, token string) (Client, error) {
|
||||
return NewGitLab(ctx, token)
|
||||
case context.TokenTypeGitea:
|
||||
return NewGitea(ctx, token)
|
||||
case context.TokenTypeMock:
|
||||
return NewMock(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid client token type: %q", ctx.TokenType)
|
||||
}
|
||||
|
@ -66,6 +66,10 @@ func NewGitea(ctx *context.Context, token string) (Client, error) {
|
||||
return &giteaClient{client: client}, nil
|
||||
}
|
||||
|
||||
func (c *giteaClient) Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error) {
|
||||
return "", ErrNotImplemented
|
||||
}
|
||||
|
||||
// CloseMilestone closes a given milestone.
|
||||
func (c *giteaClient) CloseMilestone(ctx *context.Context, repo Repo, title string) error {
|
||||
closedState := gitea.StateClosed
|
||||
|
@ -601,3 +601,30 @@ func TestGiteaGetDefaultBranchErr(t *testing.T) {
|
||||
_, err = client.GetDefaultBranch(ctx, repo)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestGiteaChangelog(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
if strings.HasSuffix(r.URL.Path, "api/v1/version") {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprint(w, "{\"version\":\"1.12.0\"}")
|
||||
}
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
ctx := context.New(config.Project{
|
||||
GiteaURLs: config.GiteaURLs{
|
||||
API: srv.URL,
|
||||
},
|
||||
})
|
||||
client, err := NewGitea(ctx, "test-token")
|
||||
require.NoError(t, err)
|
||||
repo := Repo{
|
||||
Owner: "someone",
|
||||
Name: "something",
|
||||
Branch: "somebranch",
|
||||
}
|
||||
|
||||
_, err = client.Changelog(ctx, repo, "v1.0.0", "v1.1.0")
|
||||
require.EqualError(t, err, ErrNotImplemented.Error())
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/google/go-github/v35/github"
|
||||
@ -24,6 +25,12 @@ type githubClient struct {
|
||||
client *github.Client
|
||||
}
|
||||
|
||||
// NewUnauthenticatedGitHub returns a github client that is not authenticated.
|
||||
// Used in tests only.
|
||||
func NewUnauthenticatedGitHub() Client {
|
||||
return &githubClient{client: github.NewClient(nil)}
|
||||
}
|
||||
|
||||
// NewGitHub returns a github client implementation.
|
||||
func NewGitHub(ctx *context.Context, token string) (Client, error) {
|
||||
ts := oauth2.StaticTokenSource(
|
||||
@ -51,6 +58,23 @@ func NewGitHub(ctx *context.Context, token string) (Client, error) {
|
||||
return &githubClient{client: client}, nil
|
||||
}
|
||||
|
||||
func (c *githubClient) Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error) {
|
||||
result, _, err := c.client.Repositories.CompareCommits(ctx, repo.Owner, repo.Name, prev, current)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var log []string
|
||||
for _, commit := range result.Commits {
|
||||
log = append(log, fmt.Sprintf(
|
||||
"- %s: %s (@%s)",
|
||||
commit.GetSHA(),
|
||||
strings.Split(commit.Commit.GetMessage(), "\n")[0],
|
||||
commit.GetAuthor().GetLogin(),
|
||||
))
|
||||
}
|
||||
return strings.Join(log, "\n"), nil
|
||||
}
|
||||
|
||||
// GetDefaultBranch returns the default branch of a github repo
|
||||
func (c *githubClient) GetDefaultBranch(ctx *context.Context, repo Repo) (string, error) {
|
||||
p, res, err := c.client.Repositories.Get(ctx, repo.Owner, repo.Name)
|
||||
|
@ -2,8 +2,10 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"text/template"
|
||||
|
||||
@ -14,6 +16,17 @@ import (
|
||||
)
|
||||
|
||||
func TestNewGitHubClient(t *testing.T) {
|
||||
t.Run("unauthenticated", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{})
|
||||
repo := Repo{
|
||||
Owner: "goreleaser",
|
||||
Name: "goreleaser",
|
||||
}
|
||||
b, err := NewUnauthenticatedGitHub().GetDefaultBranch(ctx, repo)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "master", b)
|
||||
})
|
||||
|
||||
t.Run("good urls", func(t *testing.T) {
|
||||
githubURL := "https://github.mycompany.com"
|
||||
ctx := context.New(config.Project{
|
||||
@ -207,7 +220,7 @@ func TestGithubGetDefaultBranch(t *testing.T) {
|
||||
|
||||
// Assume the request to create a branch was good
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprint(w, "{}")
|
||||
fmt.Fprint(w, `{"default_branch": "main"}`)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
@ -216,6 +229,7 @@ func TestGithubGetDefaultBranch(t *testing.T) {
|
||||
API: srv.URL + "/",
|
||||
},
|
||||
})
|
||||
|
||||
client, err := NewGitHub(ctx, "test-token")
|
||||
require.NoError(t, err)
|
||||
repo := Repo{
|
||||
@ -224,8 +238,9 @@ func TestGithubGetDefaultBranch(t *testing.T) {
|
||||
Branch: "somebranch",
|
||||
}
|
||||
|
||||
_, err = client.GetDefaultBranch(ctx, repo)
|
||||
b, err := client.GetDefaultBranch(ctx, repo)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "main", b)
|
||||
require.Equal(t, 1, totalRequests)
|
||||
}
|
||||
|
||||
@ -255,3 +270,35 @@ func TestGithubGetDefaultBranchErr(t *testing.T) {
|
||||
_, err = client.GetDefaultBranch(ctx, repo)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestChangelog(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
if r.URL.Path == "/repos/someone/something/compare/v1.0.0...v1.1.0" {
|
||||
r, err := os.Open("testdata/github/compare.json")
|
||||
require.NoError(t, err)
|
||||
_, err = io.Copy(w, r)
|
||||
require.NoError(t, err)
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
ctx := context.New(config.Project{
|
||||
GitHubURLs: config.GitHubURLs{
|
||||
API: srv.URL + "/",
|
||||
},
|
||||
})
|
||||
client, err := NewGitHub(ctx, "test-token")
|
||||
require.NoError(t, err)
|
||||
repo := Repo{
|
||||
Owner: "someone",
|
||||
Name: "something",
|
||||
Branch: "somebranch",
|
||||
}
|
||||
|
||||
log, err := client.Changelog(ctx, repo, "v1.0.0", "v1.1.0")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "- 6dcb09b5b57875f334f61aebed695e2e4193db5e: Fix all the bugs (@octocat)", log)
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ func NewGitLab(ctx *context.Context, token string) (Client, error) {
|
||||
return &gitlabClient{client: client}, nil
|
||||
}
|
||||
|
||||
func (c *gitlabClient) Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error) {
|
||||
return "", ErrNotImplemented
|
||||
}
|
||||
|
||||
// GetDefaultBranch get the default branch
|
||||
func (c *gitlabClient) GetDefaultBranch(ctx *context.Context, repo Repo) (string, error) {
|
||||
projectID := repo.String()
|
||||
|
@ -380,3 +380,26 @@ func TestGitlabGetDefaultBranchErr(t *testing.T) {
|
||||
_, err = client.GetDefaultBranch(ctx, repo)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestGitlabChangelog(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
ctx := context.New(config.Project{
|
||||
GitLabURLs: config.GitLabURLs{
|
||||
API: srv.URL,
|
||||
},
|
||||
})
|
||||
client, err := NewGitLab(ctx, "test-token")
|
||||
require.NoError(t, err)
|
||||
repo := Repo{
|
||||
Owner: "someone",
|
||||
Name: "something",
|
||||
Branch: "somebranch",
|
||||
}
|
||||
|
||||
_, err = client.Changelog(ctx, repo, "v1.0.0", "v1.1.0")
|
||||
require.EqualError(t, err, ErrNotImplemented.Error())
|
||||
}
|
||||
|
@ -30,12 +30,16 @@ type Mock struct {
|
||||
Lock sync.Mutex
|
||||
}
|
||||
|
||||
func (c *Mock) Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error) {
|
||||
return "", ErrNotImplemented
|
||||
}
|
||||
|
||||
func (c *Mock) CloseMilestone(ctx *context.Context, repo Repo, title string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Mock) GetDefaultBranch(ctx *context.Context, repo Repo) (string, error) {
|
||||
return "", errors.New("Mock does not yet implement GetDefaultBranch")
|
||||
return "", ErrNotImplemented
|
||||
}
|
||||
|
||||
func (c *Mock) CreateRelease(ctx *context.Context, body string) (string, error) {
|
||||
|
13
internal/client/testdata/github/compare.json
vendored
Normal file
13
internal/client/testdata/github/compare.json
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"commits": [
|
||||
{
|
||||
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
||||
"commit": {
|
||||
"message": "Fix all the bugs\nlalalal"
|
||||
},
|
||||
"author": {
|
||||
"login": "octocat"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/goreleaser/goreleaser/internal/client"
|
||||
"github.com/goreleaser/goreleaser/internal/git"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
@ -106,7 +107,7 @@ func checkSortDirection(mode string) error {
|
||||
}
|
||||
|
||||
func buildChangelog(ctx *context.Context) ([]string, error) {
|
||||
log, err := getChangelog(ctx.Git.CurrentTag)
|
||||
log, err := getChangelog(ctx, ctx.Git.CurrentTag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -161,21 +162,37 @@ func extractCommitInfo(line string) string {
|
||||
return strings.Join(strings.Split(line, " ")[1:], " ")
|
||||
}
|
||||
|
||||
func getChangelog(tag string) (string, error) {
|
||||
func getChangelog(ctx *context.Context, tag string) (string, error) {
|
||||
prev, err := previous(tag)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if isSHA1(prev) {
|
||||
return gitLog(prev, tag)
|
||||
}
|
||||
return gitLog(fmt.Sprintf("tags/%s..tags/%s", prev, tag))
|
||||
return doGetChangelog(ctx, prev, tag)
|
||||
}
|
||||
|
||||
func gitLog(refs ...string) (string, error) {
|
||||
args := []string{"log", "--pretty=oneline", "--abbrev-commit", "--no-decorate", "--no-color"}
|
||||
args = append(args, refs...)
|
||||
return git.Run(args...)
|
||||
func doGetChangelog(ctx *context.Context, prev, tag string) (string, error) {
|
||||
l, err := getChangeloger(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return l.Log(ctx, prev, tag)
|
||||
}
|
||||
|
||||
func getChangeloger(ctx *context.Context) (changeloger, error) {
|
||||
switch ctx.Config.Changelog.Use {
|
||||
case "git":
|
||||
fallthrough
|
||||
case "":
|
||||
return gitChangeloger{}, nil
|
||||
case "github":
|
||||
client, err := client.New(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &scmChangeloger{client: client}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid changelog.use: %q", ctx.Config.Changelog.Use)
|
||||
}
|
||||
}
|
||||
|
||||
func previous(tag string) (result string, err error) {
|
||||
@ -190,13 +207,6 @@ func previous(tag string) (result string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
var validSHA1 = regexp.MustCompile(`^[a-fA-F0-9]{40}$`)
|
||||
|
||||
// isSHA1 te lets us know if the ref is a SHA1 or not.
|
||||
func isSHA1(ref string) bool {
|
||||
return validSHA1.MatchString(ref)
|
||||
}
|
||||
|
||||
func loadContent(ctx *context.Context, fileName, tmplName string) (string, error) {
|
||||
if tmplName != "" {
|
||||
log.Debugf("loading template %s", tmplName)
|
||||
@ -214,3 +224,36 @@ func loadContent(ctx *context.Context, fileName, tmplName string) (string, error
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
type changeloger interface {
|
||||
Log(ctx *context.Context, prev, current string) (string, error)
|
||||
}
|
||||
|
||||
type gitChangeloger struct{}
|
||||
|
||||
var validSHA1 = regexp.MustCompile(`^[a-fA-F0-9]{40}$`)
|
||||
|
||||
func (g gitChangeloger) Log(ctx *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)
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("tags/%s..tags/%s", prev, current))
|
||||
}
|
||||
return git.Run(args...)
|
||||
}
|
||||
|
||||
type scmChangeloger struct {
|
||||
client client.Client
|
||||
}
|
||||
|
||||
func (c *scmChangeloger) Log(ctx *context.Context, prev, current string) (string, error) {
|
||||
repo, err := git.ExtractRepoFromConfig()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return c.client.Changelog(ctx, client.Repo{
|
||||
Owner: repo.Owner,
|
||||
Name: repo.Name,
|
||||
}, prev, current)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/client"
|
||||
"github.com/goreleaser/goreleaser/internal/testlib"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
@ -103,8 +104,11 @@ func TestChangelogPreviousTagEnv(t *testing.T) {
|
||||
testlib.GitCommit(t, "third")
|
||||
testlib.GitTag(t, "v0.0.3")
|
||||
ctx := context.New(config.Project{
|
||||
Dist: folder,
|
||||
Changelog: config.Changelog{Filters: config.Filters{}},
|
||||
Dist: folder,
|
||||
Changelog: config.Changelog{
|
||||
Use: "git",
|
||||
Filters: config.Filters{},
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v0.0.3"
|
||||
require.NoError(t, os.Setenv("GORELEASER_PREVIOUS_TAG", "v0.0.1"))
|
||||
@ -426,6 +430,59 @@ func TestChangeLogWithoutReleaseFooter(t *testing.T) {
|
||||
require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
|
||||
}
|
||||
|
||||
func TestGetChangelogGitHub(t *testing.T) {
|
||||
ctx := context.New(config.Project{
|
||||
Changelog: config.Changelog{
|
||||
Use: "github",
|
||||
},
|
||||
})
|
||||
|
||||
l := scmChangeloger{client: client.NewUnauthenticatedGitHub()}
|
||||
log, err := l.Log(ctx, "v0.180.1", "v0.180.2")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "- c90f1085f255d0af0b055160bfff5ee40f47af79: fix: do not skip any defaults (#2521) (@caarlos0)", log)
|
||||
}
|
||||
|
||||
func TestGetChangeloger(t *testing.T) {
|
||||
t.Run("default", func(t *testing.T) {
|
||||
c, err := getChangeloger(context.New(config.Project{}))
|
||||
require.NoError(t, err)
|
||||
require.IsType(t, c, gitChangeloger{})
|
||||
})
|
||||
|
||||
t.Run("git", func(t *testing.T) {
|
||||
c, err := getChangeloger(context.New(config.Project{
|
||||
Changelog: config.Changelog{
|
||||
Use: "git",
|
||||
},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
require.IsType(t, c, gitChangeloger{})
|
||||
})
|
||||
|
||||
t.Run("gituhb", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{
|
||||
Changelog: config.Changelog{
|
||||
Use: "github",
|
||||
},
|
||||
})
|
||||
ctx.TokenType = context.TokenTypeGitHub
|
||||
c, err := getChangeloger(ctx)
|
||||
require.NoError(t, err)
|
||||
require.IsType(t, c, &scmChangeloger{})
|
||||
})
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
c, err := getChangeloger(context.New(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 on snapshot", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{})
|
||||
|
@ -242,3 +242,7 @@ func (c *DummyClient) CreateFile(ctx *context.Context, commitAuthor config.Commi
|
||||
func (c *DummyClient) Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *DummyClient) Changelog(ctx *context.Context, repo client.Repo, prev, current string) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
@ -595,6 +595,7 @@ type Changelog struct {
|
||||
Filters Filters `yaml:",omitempty"`
|
||||
Sort string `yaml:",omitempty"`
|
||||
Skip bool `yaml:",omitempty"` // TODO(caarlos0): rename to Disable to match other pipes
|
||||
Use string `yaml:",omitempty"`
|
||||
}
|
||||
|
||||
// EnvFiles holds paths to files that contains environment variables
|
||||
|
@ -59,8 +59,6 @@ const (
|
||||
TokenTypeGitLab TokenType = "gitlab"
|
||||
// TokenTypeGitea defines gitea as type of the token.
|
||||
TokenTypeGitea TokenType = "gitea"
|
||||
// TokenTypeMock is a mock token type used in tests.
|
||||
TokenTypeMock = "mock"
|
||||
)
|
||||
|
||||
// Context carries along some data through the pipes.
|
||||
|
34
www/docs/customization/changelog.md
Normal file
34
www/docs/customization/changelog.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Changelog
|
||||
|
||||
You can customize how the changelog is generated using the `changelog` section in the config file:
|
||||
|
||||
```yaml
|
||||
# .goreleaser.yml
|
||||
changelog:
|
||||
# Set it to true if you wish to skip the changelog generation.
|
||||
# This may result in an empty release notes on GitHub/GitLab/Gitea.
|
||||
skip: true
|
||||
|
||||
# Changelog generation implementation to use.
|
||||
#
|
||||
# Valid options are:
|
||||
# - `git`: uses `git log`;
|
||||
# - `github`: uses the compare GitHub API, appending the author login to the changelog.
|
||||
#
|
||||
# Defaults to `git`.
|
||||
use: github
|
||||
|
||||
# Sorts the changelog by the commit's messages.
|
||||
# Could either be asc, desc or empty
|
||||
# Default is empty
|
||||
sort: asc
|
||||
|
||||
filters:
|
||||
# Commit messages matching the regexp listed here will be removed from
|
||||
# the changelog
|
||||
# Default is empty
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- typo
|
||||
- (?i)foo
|
||||
```
|
@ -182,34 +182,6 @@ ALLOWED_TYPES = application/gzip|application/x-gzip|application/x-gtar|applicati
|
||||
!!! warning
|
||||
`draft` and `prerelease` are only supported by GitHub and Gitea.
|
||||
|
||||
## Customize the changelog
|
||||
|
||||
You can customize how the changelog is generated using the
|
||||
`changelog` section in the config file:
|
||||
|
||||
```yaml
|
||||
# .goreleaser.yml
|
||||
changelog:
|
||||
# Set it to true if you wish to skip the changelog generation.
|
||||
# This may result in an empty release notes on GitHub/GitLab/Gitea.
|
||||
skip: true
|
||||
|
||||
# Sorts the changelog by the commit's messages.
|
||||
# Could either be asc, desc or empty
|
||||
# Default is empty
|
||||
sort: asc
|
||||
|
||||
filters:
|
||||
|
||||
# Commit messages matching the regexp listed here will be removed from
|
||||
# the changelog
|
||||
# Default is empty
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- typo
|
||||
- (?i)foo
|
||||
```
|
||||
|
||||
### Define Previous Tag
|
||||
|
||||
GoReleaser uses `git describe` to get the previous tag used for generating the Changelog.
|
||||
|
@ -96,6 +96,7 @@ nav:
|
||||
- customization/homebrew.md
|
||||
- customization/gofish.md
|
||||
- customization/scoop.md
|
||||
- customization/changelog.md
|
||||
- customization/release.md
|
||||
- customization/artifactory.md
|
||||
- customization/publishers.md
|
||||
|
Loading…
x
Reference in New Issue
Block a user