You've already forked goreleaser
mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-11-06 09:09:29 +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:
committed by
GitHub
parent
df0c31dea1
commit
cd261a527a
@@ -48,6 +48,7 @@ changelog:
|
|||||||
- '^test:'
|
- '^test:'
|
||||||
- '^chore'
|
- '^chore'
|
||||||
- Merge pull request
|
- Merge pull request
|
||||||
|
- Merge remote-tracking branch
|
||||||
- Merge branch
|
- Merge branch
|
||||||
- go mod tidy
|
- go mod tidy
|
||||||
groups:
|
groups:
|
||||||
@@ -60,7 +61,6 @@ changelog:
|
|||||||
- title: Other work
|
- title: Other work
|
||||||
order: 999
|
order: 999
|
||||||
|
|
||||||
|
|
||||||
dockers:
|
dockers:
|
||||||
- image_templates:
|
- image_templates:
|
||||||
- 'goreleaser/goreleaser:{{ .Tag }}-amd64'
|
- 'goreleaser/goreleaser:{{ .Tag }}-amd64'
|
||||||
@@ -226,6 +226,8 @@ release:
|
|||||||
extra_files:
|
extra_files:
|
||||||
- glob: ./cosign.pub
|
- glob: ./cosign.pub
|
||||||
footer: |
|
footer: |
|
||||||
|
**Full Changelog**: https://github.com/goreleaser/goreleaser/{{ .PreviousTag }}...{{ .Tag }}
|
||||||
|
|
||||||
## What to do next?
|
## What to do next?
|
||||||
|
|
||||||
- Check out the [GoReleaser Pro](https://goreleaser.com/pro) distribution;
|
- 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) {
|
func getChangelog(ctx *context.Context, tag string) (string, error) {
|
||||||
prev, err := previous(tag)
|
prev := ctx.Git.PreviousTag
|
||||||
if err != nil {
|
if prev == "" {
|
||||||
return "", err
|
// 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)
|
return doGetChangelog(ctx, prev, tag)
|
||||||
}
|
}
|
||||||
@@ -282,18 +287,6 @@ func newSCMChangeloger(ctx *context.Context) (changeloger, error) {
|
|||||||
}, nil
|
}, 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) {
|
func loadContent(ctx *context.Context, fileName, tmplName string) (string, error) {
|
||||||
if tmplName != "" {
|
if tmplName != "" {
|
||||||
log.Debugf("loading template %s", 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"
|
ctx.Git.CurrentTag = "v0.0.2"
|
||||||
require.NoError(t, Pipe{}.Run(ctx))
|
require.NoError(t, Pipe{}.Run(ctx))
|
||||||
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
||||||
@@ -102,32 +103,6 @@ func TestChangelog(t *testing.T) {
|
|||||||
require.NotEmpty(t, string(bts))
|
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) {
|
func TestChangelogForGitlab(t *testing.T) {
|
||||||
folder := testlib.Mktmp(t)
|
folder := testlib.Mktmp(t)
|
||||||
testlib.GitInit(t)
|
testlib.GitInit(t)
|
||||||
@@ -156,6 +131,7 @@ func TestChangelogForGitlab(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
ctx.TokenType = context.TokenTypeGitLab
|
ctx.TokenType = context.TokenTypeGitLab
|
||||||
|
ctx.Git.PreviousTag = "v0.0.1"
|
||||||
ctx.Git.CurrentTag = "v0.0.2"
|
ctx.Git.CurrentTag = "v0.0.2"
|
||||||
require.NoError(t, Pipe{}.Run(ctx))
|
require.NoError(t, Pipe{}.Run(ctx))
|
||||||
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
|
||||||
@@ -184,6 +160,7 @@ func TestChangelogSort(t *testing.T) {
|
|||||||
ctx := context.New(config.Project{
|
ctx := context.New(config.Project{
|
||||||
Changelog: config.Changelog{},
|
Changelog: config.Changelog{},
|
||||||
})
|
})
|
||||||
|
ctx.Git.PreviousTag = "v0.9.9"
|
||||||
ctx.Git.CurrentTag = "v1.0.0"
|
ctx.Git.CurrentTag = "v1.0.0"
|
||||||
|
|
||||||
for _, cfg := range []struct {
|
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"
|
ctx.Git.CurrentTag = "v0.0.4"
|
||||||
require.EqualError(t, Pipe{}.Run(ctx), "error parsing regexp: invalid or unsupported Perl syntax: `(?ia`")
|
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",
|
CurrentTag: "v0.0.0",
|
||||||
}, ErrNoTag
|
}, 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{
|
return context.GitInfo{
|
||||||
Branch: branch,
|
Branch: branch,
|
||||||
CurrentTag: tag,
|
CurrentTag: tag,
|
||||||
|
PreviousTag: previous,
|
||||||
Commit: full,
|
Commit: full,
|
||||||
FullCommit: full,
|
FullCommit: full,
|
||||||
ShortCommit: short,
|
ShortCommit: short,
|
||||||
@@ -203,6 +211,14 @@ func getTag() (string, error) {
|
|||||||
return tag, err
|
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) {
|
func getURL() (string, error) {
|
||||||
return git.Clean(git.Run("ls-remote", "--get-url"))
|
return git.Clean(git.Run("ls-remote", "--get-url"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ func TestSnapshotNoTags(t *testing.T) {
|
|||||||
ctx.Snapshot = true
|
ctx.Snapshot = true
|
||||||
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
|
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
|
||||||
require.Equal(t, fakeInfo.CurrentTag, ctx.Git.CurrentTag)
|
require.Equal(t, fakeInfo.CurrentTag, ctx.Git.CurrentTag)
|
||||||
|
require.Empty(t, ctx.Git.PreviousTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSnapshotNoCommits(t *testing.T) {
|
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) {
|
func TestCommitDate(t *testing.T) {
|
||||||
// round to seconds since this is expressed in a Unix timestamp
|
// round to seconds since this is expressed in a Unix timestamp
|
||||||
commitDate := time.Now().AddDate(-1, 0, 0).Round(1 * time.Second)
|
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.NoError(t, Pipe{}.Run(ctx))
|
||||||
require.Equal(t, "v0.0.1", ctx.Git.CurrentTag)
|
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")
|
require.True(t, commitDate.Equal(ctx.Git.CommitDate), "commit date does not match expected")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const (
|
|||||||
version = "Version"
|
version = "Version"
|
||||||
rawVersion = "RawVersion"
|
rawVersion = "RawVersion"
|
||||||
tag = "Tag"
|
tag = "Tag"
|
||||||
|
previousTag = "PreviousTag"
|
||||||
branch = "Branch"
|
branch = "Branch"
|
||||||
commit = "Commit"
|
commit = "Commit"
|
||||||
shortCommit = "ShortCommit"
|
shortCommit = "ShortCommit"
|
||||||
@@ -78,6 +79,7 @@ func New(ctx *context.Context) *Template {
|
|||||||
version: ctx.Version,
|
version: ctx.Version,
|
||||||
rawVersion: rawVersionV,
|
rawVersion: rawVersionV,
|
||||||
tag: ctx.Git.CurrentTag,
|
tag: ctx.Git.CurrentTag,
|
||||||
|
previousTag: ctx.Git.PreviousTag,
|
||||||
branch: ctx.Git.Branch,
|
branch: ctx.Git.Branch,
|
||||||
commit: ctx.Git.Commit,
|
commit: ctx.Git.Commit,
|
||||||
shortCommit: ctx.Git.ShortCommit,
|
shortCommit: ctx.Git.ShortCommit,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ func TestWithArtifact(t *testing.T) {
|
|||||||
"FOO": "bar",
|
"FOO": "bar",
|
||||||
}
|
}
|
||||||
ctx.Version = "1.2.3"
|
ctx.Version = "1.2.3"
|
||||||
|
ctx.Git.PreviousTag = "v1.2.2"
|
||||||
ctx.Git.CurrentTag = "v1.2.3"
|
ctx.Git.CurrentTag = "v1.2.3"
|
||||||
ctx.Semver = context.Semver{
|
ctx.Semver = context.Semver{
|
||||||
Major: 1,
|
Major: 1,
|
||||||
@@ -56,6 +57,7 @@ func TestWithArtifact(t *testing.T) {
|
|||||||
"v1.2.4": "{{.Tag | incpatch }}",
|
"v1.2.4": "{{.Tag | incpatch }}",
|
||||||
"1.2.4": "{{.Version | incpatch }}",
|
"1.2.4": "{{.Version | incpatch }}",
|
||||||
"test release notes": "{{ .ReleaseNotes }}",
|
"test release notes": "{{ .ReleaseNotes }}",
|
||||||
|
"v1.2.2": "{{ .PreviousTag }}",
|
||||||
} {
|
} {
|
||||||
tmpl := tmpl
|
tmpl := tmpl
|
||||||
expect := expect
|
expect := expect
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
type GitInfo struct {
|
type GitInfo struct {
|
||||||
Branch string
|
Branch string
|
||||||
CurrentTag string
|
CurrentTag string
|
||||||
|
PreviousTag string
|
||||||
Commit string
|
Commit string
|
||||||
ShortCommit string
|
ShortCommit string
|
||||||
FullCommit string
|
FullCommit string
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ On fields that support templating, these fields are always available:
|
|||||||
| `.Branch` | the current git branch |
|
| `.Branch` | the current git branch |
|
||||||
| `.PrefixedTag` | the current git tag prefixed with the monorepo config tag prefix (if any) |
|
| `.PrefixedTag` | the current git tag prefixed with the monorepo config tag prefix (if any) |
|
||||||
| `.Tag` | the current git tag |
|
| `.Tag` | the current git tag |
|
||||||
|
| `.PreviousTag` | the previous git tag, or empty if no previous tags |
|
||||||
| `.ShortCommit` | the git commit short hash |
|
| `.ShortCommit` | the git commit short hash |
|
||||||
| `.FullCommit` | the git commit full hash |
|
| `.FullCommit` | the git commit full hash |
|
||||||
| `.Commit` | the git commit hash (deprecated) |
|
| `.Commit` | the git commit hash (deprecated) |
|
||||||
|
|||||||
Reference in New Issue
Block a user