mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-11 14:39:28 +02:00
feat: allow to use .PreviousTag on templates (#2683)
* feat: expose .PreviousTag * fix: previous tag will never be a commit Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: tag Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
This commit is contained in:
parent
df0c31dea1
commit
cd261a527a
@ -48,6 +48,7 @@ changelog:
|
||||
- '^test:'
|
||||
- '^chore'
|
||||
- Merge pull request
|
||||
- Merge remote-tracking branch
|
||||
- Merge branch
|
||||
- go mod tidy
|
||||
groups:
|
||||
@ -60,7 +61,6 @@ changelog:
|
||||
- title: Other work
|
||||
order: 999
|
||||
|
||||
|
||||
dockers:
|
||||
- image_templates:
|
||||
- 'goreleaser/goreleaser:{{ .Tag }}-amd64'
|
||||
@ -226,6 +226,8 @@ release:
|
||||
extra_files:
|
||||
- glob: ./cosign.pub
|
||||
footer: |
|
||||
**Full Changelog**: https://github.com/goreleaser/goreleaser/{{ .PreviousTag }}...{{ .Tag }}
|
||||
|
||||
## What to do next?
|
||||
|
||||
- Check out the [GoReleaser Pro](https://goreleaser.com/pro) distribution;
|
||||
|
@ -214,9 +214,14 @@ func extractCommitInfo(line string) string {
|
||||
}
|
||||
|
||||
func getChangelog(ctx *context.Context, tag string) (string, error) {
|
||||
prev, err := previous(tag)
|
||||
if err != nil {
|
||||
return "", err
|
||||
prev := ctx.Git.PreviousTag
|
||||
if prev == "" {
|
||||
// get first commit
|
||||
result, err := git.Clean(git.Run("rev-list", "--max-parents=0", "HEAD"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
prev = result
|
||||
}
|
||||
return doGetChangelog(ctx, prev, tag)
|
||||
}
|
||||
@ -282,18 +287,6 @@ func newSCMChangeloger(ctx *context.Context) (changeloger, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func previous(tag string) (result string, err error) {
|
||||
if tag := os.Getenv("GORELEASER_PREVIOUS_TAG"); tag != "" {
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
result, err = git.Clean(git.Run("describe", "--tags", "--abbrev=0", fmt.Sprintf("tags/%s^", tag)))
|
||||
if err != nil {
|
||||
result, err = git.Clean(git.Run("rev-list", "--max-parents=0", "HEAD"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func loadContent(ctx *context.Context, fileName, tmplName string) (string, error) {
|
||||
if tmplName != "" {
|
||||
log.Debugf("loading template %s", tmplName)
|
||||
|
@ -79,6 +79,7 @@ func TestChangelog(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx.Git.PreviousTag = "v0.0.1"
|
||||
ctx.Git.CurrentTag = "v0.0.2"
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
||||
@ -102,32 +103,6 @@ func TestChangelog(t *testing.T) {
|
||||
require.NotEmpty(t, string(bts))
|
||||
}
|
||||
|
||||
func TestChangelogPreviousTagEnv(t *testing.T) {
|
||||
folder := testlib.Mktmp(t)
|
||||
testlib.GitInit(t)
|
||||
testlib.GitCommit(t, "first")
|
||||
testlib.GitTag(t, "v0.0.1")
|
||||
testlib.GitCommit(t, "second")
|
||||
testlib.GitTag(t, "v0.0.2")
|
||||
testlib.GitCommit(t, "third")
|
||||
testlib.GitTag(t, "v0.0.3")
|
||||
ctx := context.New(config.Project{
|
||||
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"))
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.NoError(t, os.Setenv("GORELEASER_PREVIOUS_TAG", ""))
|
||||
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
||||
require.NotContains(t, ctx.ReleaseNotes, "first")
|
||||
require.Contains(t, ctx.ReleaseNotes, "second")
|
||||
require.Contains(t, ctx.ReleaseNotes, "third")
|
||||
}
|
||||
|
||||
func TestChangelogForGitlab(t *testing.T) {
|
||||
folder := testlib.Mktmp(t)
|
||||
testlib.GitInit(t)
|
||||
@ -156,6 +131,7 @@ func TestChangelogForGitlab(t *testing.T) {
|
||||
},
|
||||
})
|
||||
ctx.TokenType = context.TokenTypeGitLab
|
||||
ctx.Git.PreviousTag = "v0.0.1"
|
||||
ctx.Git.CurrentTag = "v0.0.2"
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
||||
@ -184,6 +160,7 @@ func TestChangelogSort(t *testing.T) {
|
||||
ctx := context.New(config.Project{
|
||||
Changelog: config.Changelog{},
|
||||
})
|
||||
ctx.Git.PreviousTag = "v0.9.9"
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
|
||||
for _, cfg := range []struct {
|
||||
@ -276,6 +253,7 @@ func TestChangelogFilterInvalidRegex(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx.Git.PreviousTag = "v0.0.3"
|
||||
ctx.Git.CurrentTag = "v0.0.4"
|
||||
require.EqualError(t, Pipe{}.Run(ctx), "error parsing regexp: invalid or unsupported Perl syntax: `(?ia`")
|
||||
}
|
||||
|
@ -109,9 +109,17 @@ func getGitInfo() (context.GitInfo, error) {
|
||||
CurrentTag: "v0.0.0",
|
||||
}, ErrNoTag
|
||||
}
|
||||
|
||||
previous, err := getPreviousTag(tag)
|
||||
if err != nil {
|
||||
// shouldn't error, will only affect templates
|
||||
log.Warnf("couldn't find any tags before %q", tag)
|
||||
}
|
||||
|
||||
return context.GitInfo{
|
||||
Branch: branch,
|
||||
CurrentTag: tag,
|
||||
PreviousTag: previous,
|
||||
Commit: full,
|
||||
FullCommit: full,
|
||||
ShortCommit: short,
|
||||
@ -203,6 +211,14 @@ func getTag() (string, error) {
|
||||
return tag, err
|
||||
}
|
||||
|
||||
func getPreviousTag(current string) (string, error) {
|
||||
if tag := os.Getenv("GORELEASER_PREVIOUS_TAG"); tag != "" {
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
return git.Clean(git.Run("describe", "--tags", "--abbrev=0", fmt.Sprintf("tags/%s^", current)))
|
||||
}
|
||||
|
||||
func getURL() (string, error) {
|
||||
return git.Clean(git.Run("ls-remote", "--get-url"))
|
||||
}
|
||||
|
@ -201,6 +201,7 @@ func TestSnapshotNoTags(t *testing.T) {
|
||||
ctx.Snapshot = true
|
||||
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
|
||||
require.Equal(t, fakeInfo.CurrentTag, ctx.Git.CurrentTag)
|
||||
require.Empty(t, ctx.Git.PreviousTag)
|
||||
}
|
||||
|
||||
func TestSnapshotNoCommits(t *testing.T) {
|
||||
@ -277,6 +278,57 @@ func TestTagFromCI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoPreviousTag(t *testing.T) {
|
||||
testlib.Mktmp(t)
|
||||
testlib.GitInit(t)
|
||||
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
|
||||
testlib.GitCommit(t, "commit1")
|
||||
testlib.GitTag(t, "v0.0.1")
|
||||
ctx := &context.Context{
|
||||
Config: config.Project{},
|
||||
}
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.Equal(t, "v0.0.1", ctx.Git.CurrentTag)
|
||||
require.Empty(t, ctx.Git.PreviousTag, "should be empty")
|
||||
}
|
||||
|
||||
func TestPreviousTagFromCI(t *testing.T) {
|
||||
testlib.Mktmp(t)
|
||||
testlib.GitInit(t)
|
||||
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
|
||||
testlib.GitCommit(t, "commit1")
|
||||
testlib.GitTag(t, "v0.0.1")
|
||||
testlib.GitCommit(t, "commit2")
|
||||
testlib.GitTag(t, "v0.0.2")
|
||||
|
||||
for _, tc := range []struct {
|
||||
envs map[string]string
|
||||
expected string
|
||||
}{
|
||||
{expected: "v0.0.1"},
|
||||
{
|
||||
envs: map[string]string{"GORELEASER_PREVIOUS_TAG": "v0.0.2"},
|
||||
expected: "v0.0.2",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.expected, func(t *testing.T) {
|
||||
for name, value := range tc.envs {
|
||||
require.NoError(t, os.Setenv(name, value))
|
||||
}
|
||||
|
||||
ctx := &context.Context{
|
||||
Config: config.Project{},
|
||||
}
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.Equal(t, tc.expected, ctx.Git.PreviousTag)
|
||||
|
||||
for name := range tc.envs {
|
||||
require.NoError(t, os.Setenv(name, ""))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitDate(t *testing.T) {
|
||||
// round to seconds since this is expressed in a Unix timestamp
|
||||
commitDate := time.Now().AddDate(-1, 0, 0).Round(1 * time.Second)
|
||||
@ -291,5 +343,6 @@ func TestCommitDate(t *testing.T) {
|
||||
}
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.Equal(t, "v0.0.1", ctx.Git.CurrentTag)
|
||||
require.Empty(t, ctx.Git.PreviousTag)
|
||||
require.True(t, commitDate.Equal(ctx.Git.CommitDate), "commit date does not match expected")
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ const (
|
||||
version = "Version"
|
||||
rawVersion = "RawVersion"
|
||||
tag = "Tag"
|
||||
previousTag = "PreviousTag"
|
||||
branch = "Branch"
|
||||
commit = "Commit"
|
||||
shortCommit = "ShortCommit"
|
||||
@ -78,6 +79,7 @@ func New(ctx *context.Context) *Template {
|
||||
version: ctx.Version,
|
||||
rawVersion: rawVersionV,
|
||||
tag: ctx.Git.CurrentTag,
|
||||
previousTag: ctx.Git.PreviousTag,
|
||||
branch: ctx.Git.Branch,
|
||||
commit: ctx.Git.Commit,
|
||||
shortCommit: ctx.Git.ShortCommit,
|
||||
|
@ -22,6 +22,7 @@ func TestWithArtifact(t *testing.T) {
|
||||
"FOO": "bar",
|
||||
}
|
||||
ctx.Version = "1.2.3"
|
||||
ctx.Git.PreviousTag = "v1.2.2"
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
@ -56,6 +57,7 @@ func TestWithArtifact(t *testing.T) {
|
||||
"v1.2.4": "{{.Tag | incpatch }}",
|
||||
"1.2.4": "{{.Version | incpatch }}",
|
||||
"test release notes": "{{ .ReleaseNotes }}",
|
||||
"v1.2.2": "{{ .PreviousTag }}",
|
||||
} {
|
||||
tmpl := tmpl
|
||||
expect := expect
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
type GitInfo struct {
|
||||
Branch string
|
||||
CurrentTag string
|
||||
PreviousTag string
|
||||
Commit string
|
||||
ShortCommit string
|
||||
FullCommit string
|
||||
|
@ -17,6 +17,7 @@ On fields that support templating, these fields are always available:
|
||||
| `.Branch` | the current git branch |
|
||||
| `.PrefixedTag` | the current git tag prefixed with the monorepo config tag prefix (if any) |
|
||||
| `.Tag` | the current git tag |
|
||||
| `.PreviousTag` | the previous git tag, or empty if no previous tags |
|
||||
| `.ShortCommit` | the git commit short hash |
|
||||
| `.FullCommit` | the git commit full hash |
|
||||
| `.Commit` | the git commit hash (deprecated) |
|
||||
|
Loading…
x
Reference in New Issue
Block a user