1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2024-12-27 01:33:39 +02:00

feat: git.ignore_tags (#4255)

Allows to ignore tags that match the given regex expressions.
This commit is contained in:
Carlos Alexandro Becker 2023-08-27 15:57:03 -03:00 committed by GitHub
parent 51c19d4d39
commit ecdbf5877c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 145 additions and 9 deletions

View File

@ -17,6 +17,10 @@ gomod:
report_sizes: true
git:
ignore_tags:
- nightly
metadata:
mod_timestamp: "{{ .CommitTimestamp }}"

View File

@ -3,6 +3,9 @@ package git
import (
"errors"
"fmt"
"regexp/syntax"
"github.com/goreleaser/goreleaser/internal/tmpl"
)
// ErrDirty happens when the repo has uncommitted/unstashed changes.
@ -33,3 +36,12 @@ var ErrNotRepository = errors.New("current folder is not a git repository")
// ErrNoGit happens when git is not present in PATH.
var ErrNoGit = errors.New("git not present in PATH")
// shouldErr returns true if the errors are template or regex related.
func shouldErr(err error) bool {
if errors.As(err, &tmpl.Error{}) {
return true
}
se := &syntax.Error{}
return errors.As(err, &se)
}

View File

@ -5,6 +5,7 @@ import (
"net/url"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"time"
@ -12,6 +13,7 @@ import (
"github.com/caarlos0/log"
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@ -115,7 +117,10 @@ func getGitInfo(ctx *context.Context) (context.GitInfo, error) {
}
tag, err := getTag(ctx)
if err != nil {
if err != nil && shouldErr(err) {
return context.GitInfo{}, fmt.Errorf("could not get current tag: %w", err)
}
if tag == "" {
return context.GitInfo{
Branch: branch,
Commit: full,
@ -254,12 +259,16 @@ func getTag(ctx *context.Context) (string, error) {
},
} {
tags, err := fn()
if len(tags) > 0 {
return tags[0], err
}
if err != nil {
return "", err
}
tags, err = filterOutTags(ctx, tags)
if err != nil {
return "", err
}
if len(tags) > 0 {
return tags[0], err
}
}
return "", nil
@ -277,17 +286,47 @@ func getPreviousTag(ctx *context.Context, current string) (string, error) {
},
} {
tags, err := fn()
if len(tags) > 0 {
return tags[0], err
}
if err != nil {
return "", err
}
tags, err = filterOutTags(ctx, tags)
if err != nil {
return "", err
}
if len(tags) > 0 {
return tags[0], err
}
}
return "", nil
}
func filterOutTags(ctx *context.Context, tags []string) ([]string, error) {
regexes := []*regexp.Regexp{}
for _, s := range ctx.Config.Git.IgnoreTags {
applied, err := tmpl.New(ctx).Apply(s)
if err != nil {
return nil, err
}
re, err := regexp.Compile(applied)
if err != nil {
return nil, err
}
regexes = append(regexes, re)
}
var result []string
outer:
for _, tag := range tags {
for _, re := range regexes {
if re.MatchString(tag) {
continue outer
}
}
result = append(result, tag)
}
return result, nil
}
func gitTagsPointingAt(ctx *context.Context, ref string) ([]string, error) {
args := []string{}
if ctx.Config.Git.PrereleaseSuffix != "" {

View File

@ -358,3 +358,73 @@ func TestPreviousTagFromCI(t *testing.T) {
})
}
}
func TestFilterTags(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.GitTag(t, "nightly")
testlib.GitCommit(t, "commit2")
testlib.GitTag(t, "v0.0.2")
testlib.GitTag(t, "v0.1.0-dev")
t.Run("no filter", func(t *testing.T) {
ctx := testctx.New()
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "v0.0.1", ctx.Git.PreviousTag)
require.Equal(t, "v0.1.0-dev", ctx.Git.CurrentTag)
})
t.Run("regex", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Git: config.Git{
IgnoreTags: []string{
".*-dev",
},
},
})
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "v0.0.1", ctx.Git.PreviousTag)
require.Equal(t, "v0.0.2", ctx.Git.CurrentTag)
})
t.Run("template", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Git: config.Git{
IgnoreTags: []string{
"{{.Env.PREFIX}}.*",
"nightly",
},
},
}, testctx.WithEnv(map[string]string{
"PREFIX": `v0\.0\.`,
}))
require.NoError(t, Pipe{}.Run(ctx))
require.Empty(t, ctx.Git.PreviousTag)
require.Equal(t, "v0.1.0-dev", ctx.Git.CurrentTag)
})
t.Run("invalid regex", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Git: config.Git{
IgnoreTags: []string{
"[",
},
},
})
require.EqualError(t, Pipe{}.Run(ctx), "could not get current tag: error parsing regexp: missing closing ]: `[`")
})
t.Run("invalid template", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Git: config.Git{
IgnoreTags: []string{
"{{.Env.Nope}}",
},
},
})
testlib.RequireTemplateError(t, Pipe{}.Run(ctx))
})
}

View File

@ -18,8 +18,9 @@ import (
// Git configs.
type Git struct {
TagSort string `yaml:"tag_sort,omitempty" json:"tag_sort,omitempty"`
PrereleaseSuffix string `yaml:"prerelease_suffix,omitempty" json:"prerelease_suffix,omitempty"`
TagSort string `yaml:"tag_sort,omitempty" json:"tag_sort,omitempty"`
PrereleaseSuffix string `yaml:"prerelease_suffix,omitempty" json:"prerelease_suffix,omitempty"`
IgnoreTags []string `yaml:"ignore_tags,omitempty" json:"ignore_tags,omitempty"`
}
// GitHubURLs holds the URLs to be used when using github enterprise.

View File

@ -18,4 +18,14 @@ git:
#
# Since: v1.17
prerelease_suffix: "-"
# Regular expressions for tags to be ignored by GoReleaser.
# This means that GoReleaser will not pick up tags that match any of the
# provided ignores as either previous or current tags.
#
# Templates: allowed.
# Since: v1.21.
ignore_tags:
- nightly
- "{{.Env.FOO}}.*"
```