1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-08 03:31:59 +02:00
goreleaser/internal/pipe/git/git_test.go
hackerman ca3a63a537
feat: use CI environment variables to figure out tag (#1327)
* fix(git): Use CI envronment variables to figure out tag

This patch detects CI environments and uses the available tag information when
collecting the git tag.

This resolves issues where one commit has multiple tags.

Closes #1163
Closes #1311

* Update www/content/release.md

Co-Authored-By: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* Update www/content/release.md

Co-Authored-By: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* Update www/content/build.md

Co-Authored-By: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* Update www/content/release.md

Co-Authored-By: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* feat(doc): Document git tag override in environment

Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
2020-01-31 15:38:56 -03:00

232 lines
6.5 KiB
Go

package git
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
func TestDescription(t *testing.T) {
assert.NotEmpty(t, Pipe{}.String())
}
func TestNotAGitFolder(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
var ctx = &context.Context{
Config: config.Project{},
}
assert.EqualError(t, Pipe{}.Run(ctx), ErrNotRepository.Error())
}
func TestSingleCommit(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
testlib.GitCommit(t, "commit1")
testlib.GitTag(t, "v0.0.1")
var ctx = &context.Context{
Config: config.Project{},
}
assert.NoError(t, Pipe{}.Run(ctx))
assert.Equal(t, "v0.0.1", ctx.Git.CurrentTag)
}
func TestNoRemote(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitCommit(t, "commit1")
testlib.GitTag(t, "v0.0.1")
var ctx = &context.Context{
Config: config.Project{},
}
assert.EqualError(t, Pipe{}.Run(ctx), "couldn't get remote URL: fatal: No remote configured to list refs from.")
}
func TestNewRepository(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
var ctx = &context.Context{
Config: config.Project{},
}
// TODO: improve this error handling
assert.Contains(t, Pipe{}.Run(ctx).Error(), `fatal: ambiguous argument 'HEAD'`)
}
// TestNoTagsNoSnapshot covers the situation where a repository
// only contains simple commits and no tags. In this case you have
// to set the --snapshot flag otherwise an error is returned.
func TestNoTagsNoSnapshot(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
testlib.GitCommit(t, "first")
var ctx = context.New(config.Project{})
ctx.Snapshot = false
assert.EqualError(t, Pipe{}.Run(ctx), `git doesn't contain any tags. Either add a tag or use --snapshot`)
}
func TestDirty(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
dummy, err := os.Create(filepath.Join(folder, "dummy"))
assert.NoError(t, err)
testlib.GitAdd(t)
testlib.GitCommit(t, "commit2")
testlib.GitTag(t, "v0.0.1")
assert.NoError(t, ioutil.WriteFile(dummy.Name(), []byte("lorem ipsum"), 0644))
t.Run("all checks up", func(t *testing.T) {
err = Pipe{}.Run(context.New(config.Project{}))
assert.Error(t, err)
assert.Contains(t, err.Error(), "git is currently in a dirty state")
})
t.Run("skip validate is set", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipValidate = true
err = Pipe{}.Run(ctx)
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
})
t.Run("snapshot", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Snapshot = true
err = Pipe{}.Run(ctx)
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
})
}
func TestTagIsNotLastCommit(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
testlib.GitCommit(t, "commit3")
testlib.GitTag(t, "v0.0.1")
testlib.GitCommit(t, "commit4")
err := Pipe{}.Run(context.New(config.Project{}))
assert.Error(t, err)
assert.Contains(t, err.Error(), "git tag v0.0.1 was not made against commit")
}
func TestValidState(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
testlib.GitCommit(t, "commit3")
testlib.GitTag(t, "v0.0.1")
testlib.GitCommit(t, "commit4")
testlib.GitTag(t, "v0.0.2")
var ctx = context.New(config.Project{})
assert.NoError(t, Pipe{}.Run(ctx))
assert.Equal(t, "v0.0.2", ctx.Git.CurrentTag)
assert.Equal(t, "git@github.com:foo/bar.git", ctx.Git.URL)
}
func TestSnapshotNoTags(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
testlib.GitAdd(t)
testlib.GitCommit(t, "whatever")
var ctx = context.New(config.Project{})
ctx.Snapshot = true
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
assert.Equal(t, fakeInfo.CurrentTag, ctx.Git.CurrentTag)
}
func TestSnapshotNoCommits(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
var ctx = context.New(config.Project{})
ctx.Snapshot = true
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
assert.Equal(t, fakeInfo, ctx.Git)
}
func TestSnapshotWithoutRepo(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
var ctx = context.New(config.Project{})
ctx.Snapshot = true
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
assert.Equal(t, fakeInfo, ctx.Git)
}
func TestSnapshotDirty(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git")
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
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
}
func TestGitNotInPath(t *testing.T) {
var path = os.Getenv("PATH")
defer func() {
assert.NoError(t, os.Setenv("PATH", path))
}()
assert.NoError(t, os.Setenv("PATH", ""))
assert.EqualError(t, Pipe{}.Run(context.New(config.Project{})), ErrNoGit.Error())
}
func TestTagFromCI(t *testing.T) {
_, back := testlib.Mktmp(t)
defer back()
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, "v0.0.2")
for _, tc := range []struct {
envs map[string]string
expected string
}{
// It is not possible to concisely figure out the tag if a commit has more than one tags. Git always
// returns the tags in lexicographical order (ASC), which implies that we expect v0.0.1 here.
// More details: https://github.com/goreleaser/goreleaser/issues/1163
{expected: "v0.0.1"},
{
envs: map[string]string{"GORELEASER_CURRENT_TAG": "v0.0.2"},
expected: "v0.0.2",
},
} {
for name, value := range tc.envs {
require.NoError(t, os.Setenv(name, value))
}
var ctx = &context.Context{
Config: config.Project{},
}
assert.NoError(t, Pipe{}.Run(ctx))
assert.Equal(t, tc.expected, ctx.Git.CurrentTag)
for name := range tc.envs {
require.NoError(t, os.Setenv(name, ""))
}
}
}