1
0
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:
Carlos Alexandro Becker 2021-11-24 09:12:24 -03:00 committed by GitHub
parent df0c31dea1
commit cd261a527a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 90 additions and 42 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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`")
}

View File

@ -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"))
}

View File

@ -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")
}

View File

@ -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,

View File

@ -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

View File

@ -20,6 +20,7 @@ import (
type GitInfo struct {
Branch string
CurrentTag string
PreviousTag string
Commit string
ShortCommit string
FullCommit string

View File

@ -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) |