github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/git/git_test.go (about) 1 package git 2 3 import ( 4 "os" 5 "os/exec" 6 "path/filepath" 7 "testing" 8 9 "github.com/goreleaser/goreleaser/internal/skips" 10 "github.com/goreleaser/goreleaser/internal/testctx" 11 "github.com/goreleaser/goreleaser/internal/testlib" 12 "github.com/goreleaser/goreleaser/pkg/config" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestDescription(t *testing.T) { 17 require.NotEmpty(t, Pipe{}.String()) 18 } 19 20 func TestNotAGitFolder(t *testing.T) { 21 testlib.Mktmp(t) 22 ctx := testctx.New() 23 require.EqualError(t, Pipe{}.Run(ctx), ErrNotRepository.Error()) 24 } 25 26 func TestSingleCommit(t *testing.T) { 27 testlib.Mktmp(t) 28 testlib.GitInit(t) 29 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 30 testlib.GitCommit(t, "commit1") 31 testlib.GitTag(t, "v0.0.1") 32 ctx := testctx.New() 33 require.NoError(t, Pipe{}.Run(ctx)) 34 require.Equal(t, "v0.0.1", ctx.Git.CurrentTag) 35 require.Equal(t, "v0.0.1", ctx.Git.Summary) 36 require.Equal(t, "commit1", ctx.Git.TagSubject) 37 require.Equal(t, "commit1", ctx.Git.TagContents) 38 require.NotEmpty(t, ctx.Git.FirstCommit) 39 } 40 41 func TestAnnotatedTags(t *testing.T) { 42 testlib.Mktmp(t) 43 testlib.GitInit(t) 44 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 45 testlib.GitCommit(t, "commit1") 46 testlib.GitAnnotatedTag(t, "v0.0.1", "first version\n\nlalalla\nlalal\nlah") 47 ctx := testctx.New() 48 require.NoError(t, Pipe{}.Run(ctx)) 49 require.Equal(t, "v0.0.1", ctx.Git.CurrentTag) 50 require.Equal(t, "first version", ctx.Git.TagSubject) 51 require.Equal(t, "first version\n\nlalalla\nlalal\nlah", ctx.Git.TagContents) 52 require.Equal(t, "lalalla\nlalal\nlah", ctx.Git.TagBody) 53 require.Equal(t, "v0.0.1", ctx.Git.Summary) 54 } 55 56 func TestBranch(t *testing.T) { 57 testlib.Mktmp(t) 58 testlib.GitInit(t) 59 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 60 testlib.GitCommit(t, "test-branch-commit") 61 testlib.GitTag(t, "test-branch-tag") 62 testlib.GitCheckoutBranch(t, "test-branch") 63 ctx := testctx.New() 64 require.NoError(t, Pipe{}.Run(ctx)) 65 require.Equal(t, "test-branch", ctx.Git.Branch) 66 require.Equal(t, "test-branch-tag", ctx.Git.Summary) 67 } 68 69 func TestNoRemote(t *testing.T) { 70 testlib.Mktmp(t) 71 testlib.GitInit(t) 72 testlib.GitCommit(t, "commit1") 73 testlib.GitTag(t, "v0.0.1") 74 ctx := testctx.New() 75 require.EqualError(t, Pipe{}.Run(ctx), "couldn't get remote URL: fatal: No remote configured to list refs from.") 76 } 77 78 func TestNewRepository(t *testing.T) { 79 testlib.Mktmp(t) 80 testlib.GitInit(t) 81 ctx := testctx.New() 82 // TODO: improve this error handling 83 require.Contains(t, Pipe{}.Run(ctx).Error(), `fatal: ambiguous argument 'HEAD'`) 84 } 85 86 // TestNoTagsNoSnapshot covers the situation where a repository 87 // only contains simple commits and no tags. In this case you have 88 // to set the --snapshot flag otherwise an error is returned. 89 func TestNoTagsNoSnapshot(t *testing.T) { 90 testlib.Mktmp(t) 91 testlib.GitInit(t) 92 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 93 testlib.GitCommit(t, "first") 94 ctx := testctx.New() 95 ctx.Snapshot = false 96 require.EqualError(t, Pipe{}.Run(ctx), `git doesn't contain any tags. Either add a tag or use --snapshot`) 97 } 98 99 func TestDirty(t *testing.T) { 100 folder := testlib.Mktmp(t) 101 testlib.GitInit(t) 102 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 103 dummy, err := os.Create(filepath.Join(folder, "dummy")) 104 require.NoError(t, err) 105 require.NoError(t, dummy.Close()) 106 testlib.GitAdd(t) 107 testlib.GitCommit(t, "commit2") 108 testlib.GitTag(t, "v0.0.1") 109 require.NoError(t, os.WriteFile(dummy.Name(), []byte("lorem ipsum"), 0o644)) 110 t.Run("all checks up", func(t *testing.T) { 111 err := Pipe{}.Run(testctx.New()) 112 require.ErrorContains(t, err, "git is in a dirty state") 113 }) 114 t.Run("skip validate is set", func(t *testing.T) { 115 ctx := testctx.New(testctx.Skip(skips.Validate)) 116 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 117 require.True(t, ctx.Git.Dirty) 118 }) 119 t.Run("snapshot", func(t *testing.T) { 120 ctx := testctx.New(testctx.Snapshot) 121 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 122 require.True(t, ctx.Git.Dirty) 123 }) 124 } 125 126 func TestRemoteURLContainsWithUsernameAndToken(t *testing.T) { 127 testlib.Mktmp(t) 128 testlib.GitInit(t) 129 testlib.GitRemoteAdd(t, "https://gitlab-ci-token:SyYhsAghYFTvMoxw7GAg@gitlab.private.com/platform/base/poc/kink.git/releases/tag/v0.1.4") 130 testlib.GitAdd(t) 131 testlib.GitCommit(t, "commit2") 132 testlib.GitTag(t, "v0.0.1") 133 ctx := testctx.New() 134 require.NoError(t, Pipe{}.Run(ctx)) 135 } 136 137 func TestRemoteURLContainsWithUsernameAndTokenWithInvalidURL(t *testing.T) { 138 testlib.Mktmp(t) 139 testlib.GitInit(t) 140 testlib.GitRemoteAdd(t, "https://gitlab-ci-token:SyYhsAghYFTvMoxw7GAggitlab.com/platform/base/poc/kink.git/releases/tag/v0.1.4") 141 testlib.GitAdd(t) 142 testlib.GitCommit(t, "commit2") 143 testlib.GitTag(t, "v0.0.1") 144 ctx := testctx.New() 145 require.Error(t, Pipe{}.Run(ctx)) 146 } 147 148 func TestShallowClone(t *testing.T) { 149 folder := testlib.Mktmp(t) 150 require.NoError( 151 t, 152 exec.Command( 153 "git", "clone", 154 "--depth", "1", 155 "--branch", "v0.160.0", 156 "https://github.com/goreleaser/goreleaser", 157 folder, 158 ).Run(), 159 ) 160 t.Run("all checks up", func(t *testing.T) { 161 // its just a warning now 162 require.NoError(t, Pipe{}.Run(testctx.New())) 163 }) 164 t.Run("skip validate is set", func(t *testing.T) { 165 ctx := testctx.New(testctx.Skip(skips.Validate)) 166 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 167 }) 168 t.Run("snapshot", func(t *testing.T) { 169 ctx := testctx.New(testctx.Snapshot) 170 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 171 }) 172 } 173 174 func TestTagSortOrder(t *testing.T) { 175 testlib.Mktmp(t) 176 testlib.GitInit(t) 177 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 178 testlib.GitCommit(t, "commit1") 179 testlib.GitCommit(t, "commit2") 180 testlib.GitCommit(t, "commit3") 181 testlib.GitTag(t, "v0.0.2") 182 testlib.GitTag(t, "v0.0.1") 183 ctx := testctx.NewWithCfg(config.Project{ 184 Git: config.Git{ 185 TagSort: "-version:refname", 186 }, 187 }) 188 require.NoError(t, Pipe{}.Run(ctx)) 189 require.Equal(t, "v0.0.2", ctx.Git.CurrentTag) 190 } 191 192 func TestTagSortOrderPrerelease(t *testing.T) { 193 testlib.Mktmp(t) 194 testlib.GitInit(t) 195 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 196 testlib.GitCommit(t, "commit1") 197 testlib.GitCommit(t, "commit2") 198 testlib.GitCommit(t, "commit3") 199 testlib.GitTag(t, "v0.0.1-rc.2") 200 testlib.GitTag(t, "v0.0.1") 201 ctx := testctx.NewWithCfg(config.Project{ 202 Git: config.Git{ 203 TagSort: "-version:refname", 204 PrereleaseSuffix: "-", 205 }, 206 }) 207 require.NoError(t, Pipe{}.Run(ctx)) 208 require.Equal(t, "v0.0.1", ctx.Git.CurrentTag) 209 } 210 211 func TestTagIsNotLastCommit(t *testing.T) { 212 testlib.Mktmp(t) 213 testlib.GitInit(t) 214 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 215 testlib.GitCommit(t, "commit3") 216 testlib.GitTag(t, "v0.0.1") 217 testlib.GitCommit(t, "commit4") 218 ctx := testctx.New() 219 err := Pipe{}.Run(ctx) 220 require.ErrorContains(t, err, "git tag v0.0.1 was not made against commit") 221 require.Contains(t, ctx.Git.Summary, "v0.0.1-1-g") // commit not represented because it changes every test 222 } 223 224 func TestValidState(t *testing.T) { 225 testlib.Mktmp(t) 226 testlib.GitInit(t) 227 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 228 testlib.GitCommit(t, "commit3") 229 testlib.GitTag(t, "v0.0.1") 230 testlib.GitTag(t, "v0.0.2") 231 testlib.GitCommit(t, "commit4") 232 testlib.GitTag(t, "v0.0.3") 233 ctx := testctx.New() 234 require.NoError(t, Pipe{}.Run(ctx)) 235 require.Equal(t, "v0.0.2", ctx.Git.PreviousTag) 236 require.Equal(t, "v0.0.3", ctx.Git.CurrentTag) 237 require.Equal(t, "git@github.com:foo/bar.git", ctx.Git.URL) 238 require.NotEmpty(t, ctx.Git.FirstCommit) 239 require.False(t, ctx.Git.Dirty) 240 } 241 242 func TestSnapshotNoTags(t *testing.T) { 243 testlib.Mktmp(t) 244 testlib.GitInit(t) 245 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 246 testlib.GitAdd(t) 247 testlib.GitCommit(t, "whatever") 248 ctx := testctx.New(testctx.Snapshot) 249 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 250 require.Equal(t, fakeInfo.CurrentTag, ctx.Git.CurrentTag) 251 require.Empty(t, ctx.Git.PreviousTag) 252 require.NotEmpty(t, ctx.Git.FirstCommit) 253 } 254 255 func TestSnapshotNoCommits(t *testing.T) { 256 testlib.Mktmp(t) 257 testlib.GitInit(t) 258 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 259 ctx := testctx.New(testctx.Snapshot) 260 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 261 require.Equal(t, fakeInfo, ctx.Git) 262 } 263 264 func TestSnapshotWithoutRepo(t *testing.T) { 265 testlib.Mktmp(t) 266 ctx := testctx.New(testctx.Snapshot) 267 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 268 require.Equal(t, fakeInfo, ctx.Git) 269 } 270 271 func TestSnapshotDirty(t *testing.T) { 272 folder := testlib.Mktmp(t) 273 testlib.GitInit(t) 274 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 275 testlib.GitAdd(t) 276 testlib.GitCommit(t, "whatever") 277 testlib.GitTag(t, "v0.0.1") 278 require.NoError(t, os.WriteFile(filepath.Join(folder, "foo"), []byte("foobar"), 0o644)) 279 ctx := testctx.New(testctx.Snapshot) 280 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 281 require.Equal(t, "v0.0.1", ctx.Git.Summary) 282 } 283 284 func TestGitNotInPath(t *testing.T) { 285 t.Setenv("PATH", "") 286 require.EqualError(t, Pipe{}.Run(testctx.New()), ErrNoGit.Error()) 287 } 288 289 func TestTagFromCI(t *testing.T) { 290 testlib.Mktmp(t) 291 testlib.GitInit(t) 292 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 293 testlib.GitCommit(t, "commit1") 294 testlib.GitTag(t, "v0.0.1") 295 testlib.GitTag(t, "v0.0.2") 296 297 for _, tc := range []struct { 298 envs map[string]string 299 expected string 300 }{ 301 {expected: "v0.0.2"}, 302 { 303 envs: map[string]string{"GORELEASER_CURRENT_TAG": "v0.0.2"}, 304 expected: "v0.0.2", 305 }, 306 } { 307 for name, value := range tc.envs { 308 t.Setenv(name, value) 309 } 310 311 ctx := testctx.New() 312 require.NoError(t, Pipe{}.Run(ctx)) 313 require.Equal(t, tc.expected, ctx.Git.CurrentTag) 314 } 315 } 316 317 func TestNoPreviousTag(t *testing.T) { 318 testlib.Mktmp(t) 319 testlib.GitInit(t) 320 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 321 testlib.GitCommit(t, "commit1") 322 testlib.GitTag(t, "v0.0.1") 323 ctx := testctx.New() 324 require.NoError(t, Pipe{}.Run(ctx)) 325 require.Equal(t, "v0.0.1", ctx.Git.CurrentTag) 326 require.Empty(t, ctx.Git.PreviousTag, "should be empty") 327 require.NotEmpty(t, ctx.Git.FirstCommit, "should not be empty") 328 } 329 330 func TestPreviousTagFromCI(t *testing.T) { 331 testlib.Mktmp(t) 332 testlib.GitInit(t) 333 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 334 testlib.GitCommit(t, "commit1") 335 testlib.GitTag(t, "v0.0.1") 336 testlib.GitCommit(t, "commit2") 337 testlib.GitTag(t, "v0.0.2") 338 339 for _, tc := range []struct { 340 envs map[string]string 341 expected string 342 }{ 343 {expected: "v0.0.1"}, 344 { 345 envs: map[string]string{"GORELEASER_PREVIOUS_TAG": "v0.0.2"}, 346 expected: "v0.0.2", 347 }, 348 } { 349 t.Run(tc.expected, func(t *testing.T) { 350 for name, value := range tc.envs { 351 t.Setenv(name, value) 352 } 353 354 ctx := testctx.New() 355 require.NoError(t, Pipe{}.Run(ctx)) 356 require.Equal(t, tc.expected, ctx.Git.PreviousTag) 357 }) 358 } 359 } 360 361 func TestFilterTags(t *testing.T) { 362 testlib.Mktmp(t) 363 testlib.GitInit(t) 364 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 365 testlib.GitCommit(t, "commit1") 366 testlib.GitTag(t, "v0.0.1") 367 testlib.GitCommit(t, "middle commit") 368 testlib.GitTag(t, "nightly") 369 testlib.GitCommit(t, "commit2") 370 testlib.GitCommit(t, "commit3") 371 testlib.GitTag(t, "v0.0.2") 372 testlib.GitTag(t, "v0.1.0-dev") 373 374 t.Run("no filter", func(t *testing.T) { 375 ctx := testctx.New() 376 require.NoError(t, Pipe{}.Run(ctx)) 377 require.Equal(t, "nightly", ctx.Git.PreviousTag) 378 require.Equal(t, "v0.1.0-dev", ctx.Git.CurrentTag) 379 }) 380 381 t.Run("template", func(t *testing.T) { 382 ctx := testctx.NewWithCfg(config.Project{ 383 Git: config.Git{ 384 IgnoreTags: []string{ 385 "{{.Env.IGNORE}}", 386 "v0.0.2", 387 "nightly", 388 }, 389 }, 390 }, testctx.WithEnv(map[string]string{ 391 "IGNORE": `v0.0.1`, 392 })) 393 require.NoError(t, Pipe{}.Run(ctx)) 394 require.Empty(t, ctx.Git.PreviousTag) 395 require.Equal(t, "v0.1.0-dev", ctx.Git.CurrentTag) 396 }) 397 398 t.Run("invalid template", func(t *testing.T) { 399 ctx := testctx.NewWithCfg(config.Project{ 400 Git: config.Git{ 401 IgnoreTags: []string{ 402 "{{.Env.Nope}}", 403 }, 404 }, 405 }) 406 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 407 }) 408 }