mirror of
https://github.com/goreleaser/goreleaser.git
synced 2026-06-19 23:24:39 +02:00
* feat: allow snapshots on a folder that is not a git repo (#579)
* feat: allow running against a folder that is not a git repo * test: cover clean err * test: release: increase coverage * test: fix race condition
This commit is contained in:
+5
-1
@@ -34,5 +34,9 @@ func Run(args ...string) (string, error) {
|
||||
|
||||
// Clean the output
|
||||
func Clean(output string, err error) (string, error) {
|
||||
return strings.Replace(strings.Split(output, "\n")[0], "'", "", -1), err
|
||||
output = strings.Replace(strings.Split(output, "\n")[0], "'", "", -1)
|
||||
if err != nil {
|
||||
err = errors.New(strings.TrimSuffix(err.Error(), "\n"))
|
||||
}
|
||||
return output, err
|
||||
}
|
||||
|
||||
@@ -33,4 +33,13 @@ func TestClean(t *testing.T) {
|
||||
out, err := Clean("asdasd 'ssadas'\nadasd", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "asdasd ssadas", out)
|
||||
|
||||
out, err = Clean(Run("command-that-dont-exist"))
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, out)
|
||||
assert.Equal(
|
||||
t,
|
||||
"git: 'command-that-dont-exist' is not a git command. See 'git --help'.",
|
||||
err.Error(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
@@ -243,7 +244,7 @@ func TestRunPipe_ModeArchive(t *testing.T) {
|
||||
Path: debfile.Name(),
|
||||
})
|
||||
|
||||
var uploads = map[string]bool{}
|
||||
var uploads sync.Map
|
||||
|
||||
// Dummy artifactories
|
||||
mux.HandleFunc("/example-repo-local/goreleaser/1.0.0/bin.tar.gz", func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -270,7 +271,7 @@ func TestRunPipe_ModeArchive(t *testing.T) {
|
||||
},
|
||||
"uri" : "http://127.0.0.1:56563/example-repo-local/goreleaser/bin.tar.gz"
|
||||
}`)
|
||||
uploads["targz"] = true
|
||||
uploads.Store("targz", true)
|
||||
})
|
||||
mux.HandleFunc("/example-repo-local/goreleaser/1.0.0/bin.deb", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "PUT")
|
||||
@@ -296,12 +297,14 @@ func TestRunPipe_ModeArchive(t *testing.T) {
|
||||
},
|
||||
"uri" : "http://127.0.0.1:56563/example-repo-local/goreleaser/bin.deb"
|
||||
}`)
|
||||
uploads["deb"] = true
|
||||
uploads.Store("deb", true)
|
||||
})
|
||||
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
assert.True(t, uploads["targz"], "tar.gz file was not uploaded")
|
||||
assert.True(t, uploads["deb"], "deb file was not uploaded")
|
||||
_, ok := uploads.Load("targz")
|
||||
assert.True(t, ok, "tar.gz file was not uploaded")
|
||||
_, ok = uploads.Load("deb")
|
||||
assert.True(t, ok, "deb file was not uploaded")
|
||||
}
|
||||
|
||||
func TestRunPipe_ArtifactoryDown(t *testing.T) {
|
||||
|
||||
@@ -32,3 +32,7 @@ func (e ErrWrongRef) Error() string {
|
||||
// ErrNoTag happens if the underlying git repository doesn't contain any tags
|
||||
// but no snapshot-release was requested.
|
||||
var ErrNoTag = fmt.Errorf("git doesn't contain any tags. Either add a tag or use --snapshot")
|
||||
|
||||
// ErrNotRepository happens if you try to run goreleaser against a folder
|
||||
// which is not a git repository.
|
||||
var ErrNotRepository = fmt.Errorf("current folder is not a git repository")
|
||||
|
||||
+59
-31
@@ -21,28 +21,57 @@ func (Pipe) String() string {
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
func (Pipe) Run(ctx *context.Context) (err error) {
|
||||
tag, commit, err := getInfo()
|
||||
func (Pipe) Run(ctx *context.Context) error {
|
||||
info, err := getInfo(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
if tag == "" && !ctx.Snapshot {
|
||||
return ErrNoTag
|
||||
ctx.Git = info
|
||||
log.Infof("releasing %s, commit %s", info.CurrentTag, info.Commit)
|
||||
if err := setVersion(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Git = context.GitInfo{
|
||||
CurrentTag: tag,
|
||||
Commit: commit,
|
||||
}
|
||||
log.Infof("releasing %s, commit %s", tag, commit)
|
||||
if err = setVersion(ctx, tag, commit); err != nil {
|
||||
return
|
||||
}
|
||||
return validate(ctx, commit, tag)
|
||||
return validate(ctx)
|
||||
}
|
||||
|
||||
func setVersion(ctx *context.Context, tag, commit string) (err error) {
|
||||
func getInfo(ctx *context.Context) (context.GitInfo, error) {
|
||||
if !git.IsRepo() && ctx.Snapshot {
|
||||
log.Warn("running against a folder that is not a git repo")
|
||||
return context.GitInfo{
|
||||
CurrentTag: "v0.0.0",
|
||||
Commit: "none",
|
||||
}, nil
|
||||
}
|
||||
if !git.IsRepo() {
|
||||
return context.GitInfo{}, ErrNotRepository
|
||||
}
|
||||
info, err := getGitInfo(ctx)
|
||||
if err != nil && ctx.Snapshot {
|
||||
return info, nil
|
||||
}
|
||||
return info, err
|
||||
}
|
||||
|
||||
func getGitInfo(ctx *context.Context) (context.GitInfo, error) {
|
||||
commit, err := getCommit()
|
||||
if err != nil {
|
||||
return context.GitInfo{}, errors.Wrap(err, "couldn't get current commit")
|
||||
}
|
||||
tag, err := getTag()
|
||||
if err != nil {
|
||||
return context.GitInfo{
|
||||
Commit: commit,
|
||||
}, ErrNoTag
|
||||
}
|
||||
return context.GitInfo{
|
||||
CurrentTag: tag,
|
||||
Commit: commit,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func setVersion(ctx *context.Context) error {
|
||||
if ctx.Snapshot {
|
||||
snapshotName, err := getSnapshotName(ctx, tag, commit)
|
||||
snapshotName, err := getSnapshotName(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to generate snapshot name")
|
||||
}
|
||||
@@ -50,8 +79,8 @@ func setVersion(ctx *context.Context, tag, commit string) (err error) {
|
||||
return nil
|
||||
}
|
||||
// removes usual `v` prefix
|
||||
ctx.Version = strings.TrimPrefix(tag, "v")
|
||||
return
|
||||
ctx.Version = strings.TrimPrefix(ctx.Git.CurrentTag, "v")
|
||||
return nil
|
||||
}
|
||||
|
||||
type snapshotNameData struct {
|
||||
@@ -60,22 +89,22 @@ type snapshotNameData struct {
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
func getSnapshotName(ctx *context.Context, tag, commit string) (string, error) {
|
||||
func getSnapshotName(ctx *context.Context) (string, error) {
|
||||
tmpl, err := template.New("snapshot").Parse(ctx.Config.Snapshot.NameTemplate)
|
||||
var out bytes.Buffer
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var data = snapshotNameData{
|
||||
Commit: commit,
|
||||
Tag: tag,
|
||||
Commit: ctx.Git.Commit,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Timestamp: time.Now().Unix(),
|
||||
}
|
||||
err = tmpl.Execute(&out, data)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func validate(ctx *context.Context, commit, tag string) error {
|
||||
func validate(ctx *context.Context) error {
|
||||
if ctx.Snapshot {
|
||||
return nil
|
||||
}
|
||||
@@ -86,18 +115,17 @@ func validate(ctx *context.Context, commit, tag string) error {
|
||||
if !regexp.MustCompile("^[0-9.]+").MatchString(ctx.Version) {
|
||||
return ErrInvalidVersionFormat{ctx.Version}
|
||||
}
|
||||
_, err = git.Clean(git.Run("describe", "--exact-match", "--tags", "--match", tag))
|
||||
_, err = git.Clean(git.Run("describe", "--exact-match", "--tags", "--match", ctx.Git.CurrentTag))
|
||||
if err != nil {
|
||||
return ErrWrongRef{commit, tag}
|
||||
return ErrWrongRef{ctx.Git.Commit, ctx.Git.CurrentTag}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInfo() (tag, commit string, err error) {
|
||||
tag, err = git.Clean(git.Run("describe", "--tags", "--abbrev=0"))
|
||||
if err != nil {
|
||||
log.WithError(err).Info("failed to retrieve current tag")
|
||||
}
|
||||
commit, err = git.Clean(git.Run("show", "--format='%H'", "HEAD"))
|
||||
return
|
||||
func getCommit() (string, error) {
|
||||
return git.Clean(git.Run("show", "--format='%H'", "HEAD"))
|
||||
}
|
||||
|
||||
func getTag() (string, error) {
|
||||
return git.Clean(git.Run("describe", "--tags", "--abbrev=0"))
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func TestNotAGitFolder(t *testing.T) {
|
||||
var ctx = &context.Context{
|
||||
Config: config.Project{},
|
||||
}
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), "fatal: Not a git repository (or any of the parent directories): .git\n")
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), ErrNotRepository.Error())
|
||||
}
|
||||
|
||||
func TestSingleCommit(t *testing.T) {
|
||||
@@ -142,7 +142,7 @@ func TestValidState(t *testing.T) {
|
||||
assert.Equal(t, "v0.0.2", ctx.Git.CurrentTag)
|
||||
}
|
||||
|
||||
func TestSnapshot(t *testing.T) {
|
||||
func TestSnapshotNoTags(t *testing.T) {
|
||||
_, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
testlib.GitInit(t)
|
||||
@@ -153,4 +153,23 @@ func TestSnapshot(t *testing.T) {
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
}
|
||||
|
||||
// TODO: missing a test case for a dirty git tree and snapshot
|
||||
func TestSnapshotWithoutRepo(t *testing.T) {
|
||||
_, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Snapshot = true
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
}
|
||||
|
||||
func TestSnapshotDirty(t *testing.T) {
|
||||
folder, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
testlib.GitInit(t)
|
||||
testlib.GitAdd(t)
|
||||
testlib.GitCommit(t, "whatever")
|
||||
testlib.GitTag(t, "v0.0.1")
|
||||
assert.NoError(t, ioutil.WriteFile(filepath.Join(folder, "foo"), []byte("foobar"), 0644))
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Snapshot = true
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func (Pipe) Default(ctx *context.Context) error {
|
||||
return nil
|
||||
}
|
||||
repo, err := remoteRepo()
|
||||
if err != nil {
|
||||
if err != nil && !ctx.Snapshot {
|
||||
return err
|
||||
}
|
||||
ctx.Config.Release.GitHub = repo
|
||||
|
||||
@@ -174,11 +174,32 @@ func TestDefaultFilled(t *testing.T) {
|
||||
func TestDefaultNotAGitRepo(t *testing.T) {
|
||||
_, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
testlib.GitInit(t)
|
||||
var ctx = &context.Context{
|
||||
Config: config.Project{},
|
||||
}
|
||||
assert.Error(t, Pipe{}.Default(ctx))
|
||||
assert.EqualError(t, Pipe{}.Default(ctx), "current folder is not a git repository")
|
||||
assert.Empty(t, ctx.Config.Release.GitHub.String())
|
||||
}
|
||||
|
||||
func TestDefaultGitRepoWithoutOrigin(t *testing.T) {
|
||||
_, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
var ctx = &context.Context{
|
||||
Config: config.Project{},
|
||||
}
|
||||
testlib.GitInit(t)
|
||||
assert.EqualError(t, Pipe{}.Default(ctx), "repository doesn't have an `origin` remote")
|
||||
assert.Empty(t, ctx.Config.Release.GitHub.String())
|
||||
}
|
||||
|
||||
func TestDefaultNotAGitRepoSnapshot(t *testing.T) {
|
||||
_, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
var ctx = &context.Context{
|
||||
Config: config.Project{},
|
||||
}
|
||||
ctx.Snapshot = true
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Empty(t, ctx.Config.Release.GitHub.String())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package release
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
@@ -15,7 +16,7 @@ func remoteRepo() (result config.Repo, err error) {
|
||||
}
|
||||
out, err := git.Run("config", "--get", "remote.origin.url")
|
||||
if err != nil {
|
||||
return result, errors.Wrap(err, "repository doesn't have an `origin` remote")
|
||||
return result, fmt.Errorf("repository doesn't have an `origin` remote")
|
||||
}
|
||||
return extractRepoFromURL(out), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user