mirror of
https://github.com/goreleaser/goreleaser.git
synced 2024-12-31 01:53:50 +02:00
fix: improved semver parsing
This commit is contained in:
parent
a43c653254
commit
df831077e5
@ -580,6 +580,11 @@ func TestRunPipe(t *testing.T) {
|
||||
CurrentTag: "v1.0.0",
|
||||
Commit: "a1b2c3d4",
|
||||
}
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
}
|
||||
for _, os := range []string{"linux", "darwin"} {
|
||||
for _, arch := range []string{"amd64", "386"} {
|
||||
for _, bin := range []string{"mybin", "anotherbin"} {
|
||||
@ -818,6 +823,11 @@ func Test_processImageTemplates(t *testing.T) {
|
||||
CurrentTag: "v1.0.0",
|
||||
Commit: "a1b2c3d4",
|
||||
}
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
}
|
||||
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Len(t, ctx.Config.Dockers, 1)
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/apex/log"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/client"
|
||||
@ -40,12 +39,7 @@ func (Pipe) Default(ctx *context.Context) error {
|
||||
// Check if we have to check the git tag for an indicator to mark as pre release
|
||||
switch ctx.Config.Release.Prerelease {
|
||||
case "auto":
|
||||
sv, err := semver.NewVersion(ctx.Git.CurrentTag)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse tag %s as semver", ctx.Git.CurrentTag)
|
||||
}
|
||||
|
||||
if sv.Prerelease() != "" {
|
||||
if ctx.Semver.Prerelease != "" {
|
||||
ctx.PreRelease = true
|
||||
}
|
||||
log.Debugf("pre-release was detected for tag %s: %v", ctx.Git.CurrentTag, ctx.PreRelease)
|
||||
|
@ -189,7 +189,11 @@ func TestDefaultPreReleaseAuto(t *testing.T) {
|
||||
Prerelease: "auto",
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
}
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Equal(t, false, ctx.PreRelease)
|
||||
})
|
||||
@ -200,12 +204,17 @@ func TestDefaultPreReleaseAuto(t *testing.T) {
|
||||
Prerelease: "auto",
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.0.1-rc1"
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
Prerelease: "rc1",
|
||||
}
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Equal(t, true, ctx.PreRelease)
|
||||
})
|
||||
|
||||
t.Run("auto-rc", func(t *testing.T) {
|
||||
t.Run("auto-rc-github-setup", func(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
Release: config.Release{
|
||||
GitHub: config.Repo{
|
||||
@ -215,7 +224,12 @@ func TestDefaultPreReleaseAuto(t *testing.T) {
|
||||
Prerelease: "auto",
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.0.1-rc1"
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
Prerelease: "rc1",
|
||||
}
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Equal(t, true, ctx.PreRelease)
|
||||
})
|
||||
|
41
internal/pipe/semver/semver.go
Normal file
41
internal/pipe/semver/semver.go
Normal file
@ -0,0 +1,41 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/apex/log"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Pipe is a global hook pipe
|
||||
type Pipe struct{}
|
||||
|
||||
// String is the name of this pipe
|
||||
func (Pipe) String() string {
|
||||
return "Parsing tag"
|
||||
}
|
||||
|
||||
// Run executes the hooks
|
||||
func (Pipe) Run(ctx *context.Context) error {
|
||||
sv, err := semver.NewVersion(ctx.Git.CurrentTag)
|
||||
if err != nil {
|
||||
if ctx.Snapshot {
|
||||
return pipe.ErrSnapshotEnabled
|
||||
}
|
||||
if ctx.SkipValidate {
|
||||
log.WithError(err).
|
||||
WithField("tag", ctx.Git.CurrentTag).
|
||||
Warn("current tag is not a semantic tag")
|
||||
return pipe.ErrSkipValidateEnabled
|
||||
}
|
||||
return errors.Wrapf(err, "failed to parse tag %s as semver", ctx.Git.CurrentTag)
|
||||
}
|
||||
ctx.Semver = context.Semver{
|
||||
Major: sv.Major(),
|
||||
Minor: sv.Minor(),
|
||||
Patch: sv.Patch(),
|
||||
Prerelease: sv.Prerelease(),
|
||||
}
|
||||
return nil
|
||||
}
|
62
internal/pipe/semver/semver_test.go
Normal file
62
internal/pipe/semver/semver_test.go
Normal file
@ -0,0 +1,62 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/pipe"
|
||||
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDescription(t *testing.T) {
|
||||
assert.NotEmpty(t, Pipe{}.String())
|
||||
}
|
||||
|
||||
func TestValidSemver(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "v1.5.2-rc1"
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
require.Equal(t, context.Semver{
|
||||
Major: 1,
|
||||
Minor: 5,
|
||||
Patch: 2,
|
||||
Prerelease: "rc1",
|
||||
}, ctx.Semver)
|
||||
}
|
||||
|
||||
func TestInvalidSemver(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "aaaav1.5.2-rc1"
|
||||
var err = Pipe{}.Run(ctx)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "failed to parse tag aaaav1.5.2-rc1 as semver")
|
||||
}
|
||||
|
||||
func TestInvalidSemverOnSnapshots(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "aaaav1.5.2-rc1"
|
||||
ctx.Snapshot = true
|
||||
require.EqualError(t, Pipe{}.Run(ctx), pipe.ErrSnapshotEnabled.Error())
|
||||
require.Equal(t, context.Semver{
|
||||
Major: 0,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
Prerelease: "",
|
||||
}, ctx.Semver)
|
||||
}
|
||||
|
||||
func TestInvalidSemverSkipValidate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "aaaav1.5.2-rc1"
|
||||
ctx.SkipValidate = true
|
||||
require.EqualError(t, Pipe{}.Run(ctx), pipe.ErrSkipValidateEnabled.Error())
|
||||
require.Equal(t, context.Semver{
|
||||
Major: 0,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
Prerelease: "",
|
||||
}, ctx.Semver)
|
||||
}
|
@ -4,6 +4,8 @@ package pipeline
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/semver"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/archive"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/before"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/build"
|
||||
@ -36,6 +38,7 @@ type Piper interface {
|
||||
var Pipeline = []Piper{
|
||||
before.Pipe{}, // run global hooks before build
|
||||
git.Pipe{}, // get and validate git repo state
|
||||
semver.Pipe{}, // parse current tag to a semver
|
||||
defaults.Pipe{}, // load default configs
|
||||
snapshot.Pipe{}, // snapshot version handling
|
||||
dist.Pipe{}, // ensure ./dist is clean
|
||||
|
@ -6,10 +6,8 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Template holds data that can be applied to a template string
|
||||
@ -57,6 +55,10 @@ func New(ctx *context.Context) *Template {
|
||||
env: ctx.Env,
|
||||
date: time.Now().UTC().Format(time.RFC3339),
|
||||
timestamp: time.Now().UTC().Unix(),
|
||||
major: ctx.Semver.Major,
|
||||
minor: ctx.Semver.Minor,
|
||||
patch: ctx.Semver.Patch,
|
||||
// TODO: no reason not to add prerelease here too I guess
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -90,14 +92,6 @@ func (t *Template) Apply(s string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sv, err := semver.NewVersion(t.fields[tag].(string))
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "tmpl")
|
||||
}
|
||||
t.fields[major] = sv.Major()
|
||||
t.fields[minor] = sv.Minor()
|
||||
t.fields[patch] = sv.Patch()
|
||||
|
||||
err = tmpl.Execute(&out, t.fields)
|
||||
return out.String(), err
|
||||
}
|
||||
|
@ -16,8 +16,13 @@ func TestWithArtifact(t *testing.T) {
|
||||
ctx.Env = map[string]string{
|
||||
"FOO": "bar",
|
||||
}
|
||||
ctx.Version = "1.0.0"
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
ctx.Version = "1.2.3"
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Semver = context.Semver{
|
||||
Major: 1,
|
||||
Minor: 2,
|
||||
Patch: 3,
|
||||
}
|
||||
ctx.Git.Commit = "commit"
|
||||
ctx.Git.FullCommit = "fullcommit"
|
||||
ctx.Git.ShortCommit = "shortcommit"
|
||||
@ -26,8 +31,9 @@ func TestWithArtifact(t *testing.T) {
|
||||
"Linux": "{{.Os}}",
|
||||
"amd64": "{{.Arch}}",
|
||||
"6": "{{.Arm}}",
|
||||
"1.0.0": "{{.Version}}",
|
||||
"v1.0.0": "{{.Tag}}",
|
||||
"1.2.3": "{{.Version}}",
|
||||
"v1.2.3": "{{.Tag}}",
|
||||
"1-2-3": "{{.Major}}-{{.Minor}}-{{.Patch}}",
|
||||
"commit": "{{.Commit}}",
|
||||
"fullcommit": "{{.FullCommit}}",
|
||||
"shortcommit": "{{.ShortCommit}}",
|
||||
@ -136,7 +142,9 @@ func TestFuncMap(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidTemplate(t *testing.T) {
|
||||
_, err := New(context.New(config.Project{})).Apply("{{{.Foo}")
|
||||
ctx := context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "v1.1.1"
|
||||
_, err := New(ctx).Apply("{{{.Foo}")
|
||||
assert.EqualError(t, err, "template: tmpl:1: unexpected \"{\" in command")
|
||||
}
|
||||
|
||||
@ -147,12 +155,3 @@ func TestEnvNotFound(t *testing.T) {
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `template: tmpl:1:6: executing "tmpl" at <.Env.FOO>: map has no entry for key "FOO"`)
|
||||
}
|
||||
|
||||
// This should actually never happen...
|
||||
func TestInvalidSemver(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "v1_2_3"
|
||||
result, err := New(ctx).Apply("{{.Major}}")
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `tmpl: Invalid Semantic Version`)
|
||||
}
|
||||
|
@ -43,6 +43,15 @@ type Context struct {
|
||||
Debug bool
|
||||
PreRelease bool
|
||||
Parallelism int
|
||||
Semver Semver
|
||||
}
|
||||
|
||||
// Semver represents a semantic version
|
||||
type Semver struct {
|
||||
Major int64
|
||||
Minor int64
|
||||
Patch int64
|
||||
Prerelease string
|
||||
}
|
||||
|
||||
// New context
|
||||
|
Loading…
Reference in New Issue
Block a user