github.com/windmeup/goreleaser@v1.21.95/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/stretchr/testify/require" 10 "github.com/windmeup/goreleaser/internal/skips" 11 "github.com/windmeup/goreleaser/internal/testctx" 12 "github.com/windmeup/goreleaser/internal/testlib" 13 "github.com/windmeup/goreleaser/pkg/config" 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.Error(t, err) 113 require.Contains(t, err.Error(), "git is in a dirty state") 114 }) 115 t.Run("skip validate is set", func(t *testing.T) { 116 ctx := testctx.New(testctx.Skip(skips.Validate)) 117 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 118 require.True(t, ctx.Git.Dirty) 119 }) 120 t.Run("snapshot", func(t *testing.T) { 121 ctx := testctx.New(testctx.Snapshot) 122 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 123 require.True(t, ctx.Git.Dirty) 124 }) 125 } 126 127 func TestRemoteURLContainsWithUsernameAndToken(t *testing.T) { 128 testlib.Mktmp(t) 129 testlib.GitInit(t) 130 testlib.GitRemoteAdd(t, "https://gitlab-ci-token:SyYhsAghYFTvMoxw7GAg@gitlab.private.com/platform/base/poc/kink.git/releases/tag/v0.1.4") 131 testlib.GitAdd(t) 132 testlib.GitCommit(t, "commit2") 133 testlib.GitTag(t, "v0.0.1") 134 ctx := testctx.New() 135 require.NoError(t, Pipe{}.Run(ctx)) 136 } 137 138 func TestRemoteURLContainsWithUsernameAndTokenWithInvalidURL(t *testing.T) { 139 testlib.Mktmp(t) 140 testlib.GitInit(t) 141 testlib.GitRemoteAdd(t, "https://gitlab-ci-token:SyYhsAghYFTvMoxw7GAggitlab.com/platform/base/poc/kink.git/releases/tag/v0.1.4") 142 testlib.GitAdd(t) 143 testlib.GitCommit(t, "commit2") 144 testlib.GitTag(t, "v0.0.1") 145 ctx := testctx.New() 146 require.Error(t, Pipe{}.Run(ctx)) 147 } 148 149 func TestShallowClone(t *testing.T) { 150 folder := testlib.Mktmp(t) 151 require.NoError( 152 t, 153 exec.Command( 154 "git", "clone", 155 "--depth", "1", 156 "--branch", "v0.160.0", 157 "https://github.com/windmeup/goreleaser", 158 folder, 159 ).Run(), 160 ) 161 t.Run("all checks up", func(t *testing.T) { 162 // its just a warning now 163 require.NoError(t, Pipe{}.Run(testctx.New())) 164 }) 165 t.Run("skip validate is set", func(t *testing.T) { 166 ctx := testctx.New(testctx.Skip(skips.Validate)) 167 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 168 }) 169 t.Run("snapshot", func(t *testing.T) { 170 ctx := testctx.New(testctx.Snapshot) 171 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 172 }) 173 } 174 175 func TestTagSortOrder(t *testing.T) { 176 testlib.Mktmp(t) 177 testlib.GitInit(t) 178 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 179 testlib.GitCommit(t, "commit1") 180 testlib.GitCommit(t, "commit2") 181 testlib.GitCommit(t, "commit3") 182 testlib.GitTag(t, "v0.0.2") 183 testlib.GitTag(t, "v0.0.1") 184 ctx := testctx.NewWithCfg(config.Project{ 185 Git: config.Git{ 186 TagSort: "-version:refname", 187 }, 188 }) 189 require.NoError(t, Pipe{}.Run(ctx)) 190 require.Equal(t, "v0.0.2", ctx.Git.CurrentTag) 191 } 192 193 func TestTagSortOrderPrerelease(t *testing.T) { 194 testlib.Mktmp(t) 195 testlib.GitInit(t) 196 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 197 testlib.GitCommit(t, "commit1") 198 testlib.GitCommit(t, "commit2") 199 testlib.GitCommit(t, "commit3") 200 testlib.GitTag(t, "v0.0.1-rc.2") 201 testlib.GitTag(t, "v0.0.1") 202 ctx := testctx.NewWithCfg(config.Project{ 203 Git: config.Git{ 204 TagSort: "-version:refname", 205 PrereleaseSuffix: "-", 206 }, 207 }) 208 require.NoError(t, Pipe{}.Run(ctx)) 209 require.Equal(t, "v0.0.1", ctx.Git.CurrentTag) 210 } 211 212 func TestTagIsNotLastCommit(t *testing.T) { 213 testlib.Mktmp(t) 214 testlib.GitInit(t) 215 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 216 testlib.GitCommit(t, "commit3") 217 testlib.GitTag(t, "v0.0.1") 218 testlib.GitCommit(t, "commit4") 219 ctx := testctx.New() 220 err := Pipe{}.Run(ctx) 221 require.Error(t, err) 222 require.Contains(t, err.Error(), "git tag v0.0.1 was not made against commit") 223 require.Contains(t, ctx.Git.Summary, "v0.0.1-1-g") // commit not represented because it changes every test 224 } 225 226 func TestValidState(t *testing.T) { 227 testlib.Mktmp(t) 228 testlib.GitInit(t) 229 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 230 testlib.GitCommit(t, "commit3") 231 testlib.GitTag(t, "v0.0.1") 232 testlib.GitTag(t, "v0.0.2") 233 testlib.GitCommit(t, "commit4") 234 testlib.GitTag(t, "v0.0.3") 235 ctx := testctx.New() 236 require.NoError(t, Pipe{}.Run(ctx)) 237 require.Equal(t, "v0.0.2", ctx.Git.PreviousTag) 238 require.Equal(t, "v0.0.3", ctx.Git.CurrentTag) 239 require.Equal(t, "git@github.com:foo/bar.git", ctx.Git.URL) 240 require.NotEmpty(t, ctx.Git.FirstCommit) 241 require.False(t, ctx.Git.Dirty) 242 } 243 244 func TestSnapshotNoTags(t *testing.T) { 245 testlib.Mktmp(t) 246 testlib.GitInit(t) 247 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 248 testlib.GitAdd(t) 249 testlib.GitCommit(t, "whatever") 250 ctx := testctx.New(testctx.Snapshot) 251 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 252 require.Equal(t, fakeInfo.CurrentTag, ctx.Git.CurrentTag) 253 require.Empty(t, ctx.Git.PreviousTag) 254 require.NotEmpty(t, ctx.Git.FirstCommit) 255 } 256 257 func TestSnapshotNoCommits(t *testing.T) { 258 testlib.Mktmp(t) 259 testlib.GitInit(t) 260 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 261 ctx := testctx.New(testctx.Snapshot) 262 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 263 require.Equal(t, fakeInfo, ctx.Git) 264 } 265 266 func TestSnapshotWithoutRepo(t *testing.T) { 267 testlib.Mktmp(t) 268 ctx := testctx.New(testctx.Snapshot) 269 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 270 require.Equal(t, fakeInfo, ctx.Git) 271 } 272 273 func TestSnapshotDirty(t *testing.T) { 274 folder := testlib.Mktmp(t) 275 testlib.GitInit(t) 276 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 277 testlib.GitAdd(t) 278 testlib.GitCommit(t, "whatever") 279 testlib.GitTag(t, "v0.0.1") 280 require.NoError(t, os.WriteFile(filepath.Join(folder, "foo"), []byte("foobar"), 0o644)) 281 ctx := testctx.New(testctx.Snapshot) 282 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 283 require.Equal(t, "v0.0.1", ctx.Git.Summary) 284 } 285 286 func TestGitNotInPath(t *testing.T) { 287 t.Setenv("PATH", "") 288 require.EqualError(t, Pipe{}.Run(testctx.New()), ErrNoGit.Error()) 289 } 290 291 func TestTagFromCI(t *testing.T) { 292 testlib.Mktmp(t) 293 testlib.GitInit(t) 294 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 295 testlib.GitCommit(t, "commit1") 296 testlib.GitTag(t, "v0.0.1") 297 testlib.GitTag(t, "v0.0.2") 298 299 for _, tc := range []struct { 300 envs map[string]string 301 expected string 302 }{ 303 {expected: "v0.0.2"}, 304 { 305 envs: map[string]string{"GORELEASER_CURRENT_TAG": "v0.0.2"}, 306 expected: "v0.0.2", 307 }, 308 } { 309 for name, value := range tc.envs { 310 t.Setenv(name, value) 311 } 312 313 ctx := testctx.New() 314 require.NoError(t, Pipe{}.Run(ctx)) 315 require.Equal(t, tc.expected, ctx.Git.CurrentTag) 316 } 317 } 318 319 func TestNoPreviousTag(t *testing.T) { 320 testlib.Mktmp(t) 321 testlib.GitInit(t) 322 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 323 testlib.GitCommit(t, "commit1") 324 testlib.GitTag(t, "v0.0.1") 325 ctx := testctx.New() 326 require.NoError(t, Pipe{}.Run(ctx)) 327 require.Equal(t, "v0.0.1", ctx.Git.CurrentTag) 328 require.Empty(t, ctx.Git.PreviousTag, "should be empty") 329 require.NotEmpty(t, ctx.Git.FirstCommit, "should not be empty") 330 } 331 332 func TestPreviousTagFromCI(t *testing.T) { 333 testlib.Mktmp(t) 334 testlib.GitInit(t) 335 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 336 testlib.GitCommit(t, "commit1") 337 testlib.GitTag(t, "v0.0.1") 338 testlib.GitCommit(t, "commit2") 339 testlib.GitTag(t, "v0.0.2") 340 341 for _, tc := range []struct { 342 envs map[string]string 343 expected string 344 }{ 345 {expected: "v0.0.1"}, 346 { 347 envs: map[string]string{"GORELEASER_PREVIOUS_TAG": "v0.0.2"}, 348 expected: "v0.0.2", 349 }, 350 } { 351 t.Run(tc.expected, func(t *testing.T) { 352 for name, value := range tc.envs { 353 t.Setenv(name, value) 354 } 355 356 ctx := testctx.New() 357 require.NoError(t, Pipe{}.Run(ctx)) 358 require.Equal(t, tc.expected, ctx.Git.PreviousTag) 359 }) 360 } 361 } 362 363 func TestFilterTags(t *testing.T) { 364 testlib.Mktmp(t) 365 testlib.GitInit(t) 366 testlib.GitRemoteAdd(t, "git@github.com:foo/bar.git") 367 testlib.GitCommit(t, "commit1") 368 testlib.GitTag(t, "v0.0.1") 369 testlib.GitCommit(t, "middle commit") 370 testlib.GitTag(t, "nightly") 371 testlib.GitCommit(t, "commit2") 372 testlib.GitCommit(t, "commit3") 373 testlib.GitTag(t, "v0.0.2") 374 testlib.GitTag(t, "v0.1.0-dev") 375 376 t.Run("no filter", func(t *testing.T) { 377 ctx := testctx.New() 378 require.NoError(t, Pipe{}.Run(ctx)) 379 require.Equal(t, "nightly", ctx.Git.PreviousTag) 380 require.Equal(t, "v0.1.0-dev", ctx.Git.CurrentTag) 381 }) 382 383 t.Run("template", func(t *testing.T) { 384 ctx := testctx.NewWithCfg(config.Project{ 385 Git: config.Git{ 386 IgnoreTags: []string{ 387 "{{.Env.IGNORE}}", 388 "v0.0.2", 389 "nightly", 390 }, 391 }, 392 }, testctx.WithEnv(map[string]string{ 393 "IGNORE": `v0.0.1`, 394 })) 395 require.NoError(t, Pipe{}.Run(ctx)) 396 require.Empty(t, ctx.Git.PreviousTag) 397 require.Equal(t, "v0.1.0-dev", ctx.Git.CurrentTag) 398 }) 399 400 t.Run("invalid template", func(t *testing.T) { 401 ctx := testctx.NewWithCfg(config.Project{ 402 Git: config.Git{ 403 IgnoreTags: []string{ 404 "{{.Env.Nope}}", 405 }, 406 }, 407 }) 408 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 409 }) 410 }