github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/internal/pipe/release/release_test.go (about) 1 package release 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "strings" 10 "sync" 11 "testing" 12 13 "github.com/goreleaser/goreleaser/internal/artifact" 14 "github.com/goreleaser/goreleaser/internal/client" 15 "github.com/goreleaser/goreleaser/internal/testlib" 16 "github.com/goreleaser/goreleaser/pkg/config" 17 "github.com/goreleaser/goreleaser/pkg/context" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func TestPipeDescription(t *testing.T) { 22 require.NotEmpty(t, Pipe{}.String()) 23 } 24 25 func TestRunPipeWithoutIDsThenDoesNotFilter(t *testing.T) { 26 folder := t.TempDir() 27 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 28 require.NoError(t, err) 29 require.NoError(t, tarfile.Close()) 30 srcfile, err := os.Create(filepath.Join(folder, "source.tar.gz")) 31 require.NoError(t, err) 32 require.NoError(t, srcfile.Close()) 33 debfile, err := os.Create(filepath.Join(folder, "bin.deb")) 34 require.NoError(t, err) 35 require.NoError(t, debfile.Close()) 36 filteredtarfile, err := os.Create(filepath.Join(folder, "filtered.tar.gz")) 37 require.NoError(t, err) 38 require.NoError(t, filteredtarfile.Close()) 39 filtereddebfile, err := os.Create(filepath.Join(folder, "filtered.deb")) 40 require.NoError(t, err) 41 require.NoError(t, filtereddebfile.Close()) 42 43 config := config.Project{ 44 Dist: folder, 45 Release: config.Release{ 46 GitHub: config.Repo{ 47 Owner: "test", 48 Name: "test", 49 }, 50 }, 51 } 52 ctx := context.New(config) 53 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 54 ctx.Artifacts.Add(&artifact.Artifact{ 55 Type: artifact.UploadableArchive, 56 Name: "bin.tar.gz", 57 Path: tarfile.Name(), 58 Extra: map[string]interface{}{ 59 "ID": "foo", 60 }, 61 }) 62 ctx.Artifacts.Add(&artifact.Artifact{ 63 Type: artifact.LinuxPackage, 64 Name: "bin.deb", 65 Path: debfile.Name(), 66 Extra: map[string]interface{}{ 67 "ID": "foo", 68 }, 69 }) 70 ctx.Artifacts.Add(&artifact.Artifact{ 71 Type: artifact.UploadableArchive, 72 Name: "filtered.tar.gz", 73 Path: filteredtarfile.Name(), 74 Extra: map[string]interface{}{ 75 "ID": "bar", 76 }, 77 }) 78 ctx.Artifacts.Add(&artifact.Artifact{ 79 Type: artifact.LinuxPackage, 80 Name: "filtered.deb", 81 Path: filtereddebfile.Name(), 82 Extra: map[string]interface{}{ 83 "ID": "bar", 84 }, 85 }) 86 ctx.Artifacts.Add(&artifact.Artifact{ 87 Type: artifact.UploadableSourceArchive, 88 Name: "source.tar.gz", 89 Path: srcfile.Name(), 90 Extra: map[string]interface{}{ 91 "Format": "tar.gz", 92 }, 93 }) 94 client := &DummyClient{} 95 require.NoError(t, doPublish(ctx, client)) 96 require.True(t, client.CreatedRelease) 97 require.True(t, client.UploadedFile) 98 require.Contains(t, client.UploadedFileNames, "source.tar.gz") 99 require.Contains(t, client.UploadedFileNames, "bin.deb") 100 require.Contains(t, client.UploadedFileNames, "bin.tar.gz") 101 require.Contains(t, client.UploadedFileNames, "filtered.deb") 102 require.Contains(t, client.UploadedFileNames, "filtered.tar.gz") 103 } 104 105 func TestRunPipeWithIDsThenFilters(t *testing.T) { 106 folder := t.TempDir() 107 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 108 require.NoError(t, err) 109 require.NoError(t, tarfile.Close()) 110 debfile, err := os.Create(filepath.Join(folder, "bin.deb")) 111 require.NoError(t, err) 112 require.NoError(t, debfile.Close()) 113 filteredtarfile, err := os.Create(filepath.Join(folder, "filtered.tar.gz")) 114 require.NoError(t, err) 115 require.NoError(t, filteredtarfile.Close()) 116 filtereddebfile, err := os.Create(filepath.Join(folder, "filtered.deb")) 117 require.NoError(t, err) 118 require.NoError(t, filtereddebfile.Close()) 119 120 config := config.Project{ 121 Dist: folder, 122 Release: config.Release{ 123 GitHub: config.Repo{ 124 Owner: "test", 125 Name: "test", 126 }, 127 IDs: []string{"foo"}, 128 ExtraFiles: []config.ExtraFile{ 129 {Glob: "./testdata/**/*"}, 130 }, 131 }, 132 } 133 ctx := context.New(config) 134 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 135 ctx.Artifacts.Add(&artifact.Artifact{ 136 Type: artifact.UploadableArchive, 137 Name: "bin.tar.gz", 138 Path: tarfile.Name(), 139 Extra: map[string]interface{}{ 140 "ID": "foo", 141 }, 142 }) 143 ctx.Artifacts.Add(&artifact.Artifact{ 144 Type: artifact.LinuxPackage, 145 Name: "bin.deb", 146 Path: debfile.Name(), 147 Extra: map[string]interface{}{ 148 "ID": "foo", 149 }, 150 }) 151 ctx.Artifacts.Add(&artifact.Artifact{ 152 Type: artifact.UploadableArchive, 153 Name: "filtered.tar.gz", 154 Path: filteredtarfile.Name(), 155 Extra: map[string]interface{}{ 156 "ID": "bar", 157 }, 158 }) 159 ctx.Artifacts.Add(&artifact.Artifact{ 160 Type: artifact.LinuxPackage, 161 Name: "filtered.deb", 162 Path: filtereddebfile.Name(), 163 Extra: map[string]interface{}{ 164 "ID": "bar", 165 }, 166 }) 167 client := &DummyClient{} 168 require.NoError(t, doPublish(ctx, client)) 169 require.True(t, client.CreatedRelease) 170 require.True(t, client.UploadedFile) 171 require.Contains(t, client.UploadedFileNames, "bin.deb") 172 require.Contains(t, client.UploadedFileNames, "bin.tar.gz") 173 require.Contains(t, client.UploadedFileNames, "f1") 174 require.NotContains(t, client.UploadedFileNames, "filtered.deb") 175 require.NotContains(t, client.UploadedFileNames, "filtered.tar.gz") 176 } 177 178 func TestRunPipeReleaseCreationFailed(t *testing.T) { 179 config := config.Project{ 180 Release: config.Release{ 181 GitHub: config.Repo{ 182 Owner: "test", 183 Name: "test", 184 }, 185 }, 186 } 187 ctx := context.New(config) 188 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 189 client := &DummyClient{ 190 FailToCreateRelease: true, 191 } 192 require.Error(t, doPublish(ctx, client)) 193 require.False(t, client.CreatedRelease) 194 require.False(t, client.UploadedFile) 195 } 196 197 func TestRunPipeWithFileThatDontExist(t *testing.T) { 198 config := config.Project{ 199 Release: config.Release{ 200 GitHub: config.Repo{ 201 Owner: "test", 202 Name: "test", 203 }, 204 }, 205 } 206 ctx := context.New(config) 207 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 208 ctx.Artifacts.Add(&artifact.Artifact{ 209 Type: artifact.UploadableArchive, 210 Name: "bin.tar.gz", 211 Path: "/nope/nope/nope", 212 }) 213 client := &DummyClient{} 214 require.Error(t, doPublish(ctx, client)) 215 require.True(t, client.CreatedRelease) 216 require.False(t, client.UploadedFile) 217 } 218 219 func TestRunPipeUploadFailure(t *testing.T) { 220 folder := t.TempDir() 221 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 222 require.NoError(t, err) 223 config := config.Project{ 224 Release: config.Release{ 225 GitHub: config.Repo{ 226 Owner: "test", 227 Name: "test", 228 }, 229 }, 230 } 231 ctx := context.New(config) 232 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 233 ctx.Artifacts.Add(&artifact.Artifact{ 234 Type: artifact.UploadableArchive, 235 Name: "bin.tar.gz", 236 Path: tarfile.Name(), 237 }) 238 client := &DummyClient{ 239 FailToUpload: true, 240 } 241 require.EqualError(t, doPublish(ctx, client), "failed to upload bin.tar.gz after 1 tries: upload failed") 242 require.True(t, client.CreatedRelease) 243 require.False(t, client.UploadedFile) 244 } 245 246 func TestRunPipeExtraFileNotFound(t *testing.T) { 247 config := config.Project{ 248 Release: config.Release{ 249 GitHub: config.Repo{ 250 Owner: "test", 251 Name: "test", 252 }, 253 ExtraFiles: []config.ExtraFile{ 254 {Glob: "./testdata/f1.txt"}, 255 {Glob: "./nope"}, 256 }, 257 }, 258 } 259 ctx := context.New(config) 260 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 261 client := &DummyClient{} 262 require.EqualError(t, doPublish(ctx, client), "globbing failed for pattern ./nope: matching \"./nope\": file does not exist") 263 require.True(t, client.CreatedRelease) 264 require.False(t, client.UploadedFile) 265 } 266 267 func TestRunPipeExtraOverride(t *testing.T) { 268 config := config.Project{ 269 Release: config.Release{ 270 GitHub: config.Repo{ 271 Owner: "test", 272 Name: "test", 273 }, 274 ExtraFiles: []config.ExtraFile{ 275 {Glob: "./testdata/**/*"}, 276 {Glob: "./testdata/upload_same_name/f1"}, 277 }, 278 }, 279 } 280 ctx := context.New(config) 281 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 282 client := &DummyClient{} 283 require.NoError(t, doPublish(ctx, client)) 284 require.True(t, client.CreatedRelease) 285 require.True(t, client.UploadedFile) 286 require.Contains(t, client.UploadedFileNames, "f1") 287 require.True(t, strings.HasSuffix(client.UploadedFilePaths["f1"], "testdata/upload_same_name/f1")) 288 } 289 290 func TestRunPipeUploadRetry(t *testing.T) { 291 folder := t.TempDir() 292 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 293 require.NoError(t, err) 294 config := config.Project{ 295 Release: config.Release{ 296 GitHub: config.Repo{ 297 Owner: "test", 298 Name: "test", 299 }, 300 }, 301 } 302 ctx := context.New(config) 303 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 304 ctx.Artifacts.Add(&artifact.Artifact{ 305 Type: artifact.UploadableArchive, 306 Name: "bin.tar.gz", 307 Path: tarfile.Name(), 308 }) 309 client := &DummyClient{ 310 FailFirstUpload: true, 311 } 312 require.NoError(t, doPublish(ctx, client)) 313 require.True(t, client.CreatedRelease) 314 require.True(t, client.UploadedFile) 315 } 316 317 func TestDefault(t *testing.T) { 318 testlib.Mktmp(t) 319 testlib.GitInit(t) 320 testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") 321 322 ctx := context.New(config.Project{}) 323 ctx.TokenType = context.TokenTypeGitHub 324 require.NoError(t, Pipe{}.Default(ctx)) 325 require.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Name) 326 require.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Owner) 327 } 328 329 func TestDefaultWithGitlab(t *testing.T) { 330 testlib.Mktmp(t) 331 testlib.GitInit(t) 332 testlib.GitRemoteAdd(t, "git@gitlab.com:gitlabowner/gitlabrepo.git") 333 334 ctx := context.New(config.Project{}) 335 ctx.TokenType = context.TokenTypeGitLab 336 require.NoError(t, Pipe{}.Default(ctx)) 337 require.Equal(t, "gitlabrepo", ctx.Config.Release.GitLab.Name) 338 require.Equal(t, "gitlabowner", ctx.Config.Release.GitLab.Owner) 339 } 340 341 func TestDefaultWithGitea(t *testing.T) { 342 testlib.Mktmp(t) 343 testlib.GitInit(t) 344 testlib.GitRemoteAdd(t, "git@gitea.example.com:giteaowner/gitearepo.git") 345 346 ctx := context.New(config.Project{}) 347 ctx.TokenType = context.TokenTypeGitea 348 require.NoError(t, Pipe{}.Default(ctx)) 349 require.Equal(t, "gitearepo", ctx.Config.Release.Gitea.Name) 350 require.Equal(t, "giteaowner", ctx.Config.Release.Gitea.Owner) 351 } 352 353 func TestDefaultPreReleaseAuto(t *testing.T) { 354 testlib.Mktmp(t) 355 testlib.GitInit(t) 356 testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") 357 358 t.Run("auto-release", func(t *testing.T) { 359 ctx := context.New(config.Project{ 360 Release: config.Release{ 361 Prerelease: "auto", 362 }, 363 }) 364 ctx.TokenType = context.TokenTypeGitHub 365 ctx.Semver = context.Semver{ 366 Major: 1, 367 Minor: 0, 368 Patch: 0, 369 } 370 require.NoError(t, Pipe{}.Default(ctx)) 371 require.Equal(t, false, ctx.PreRelease) 372 }) 373 374 t.Run("auto-rc", func(t *testing.T) { 375 ctx := context.New(config.Project{ 376 Release: config.Release{ 377 Prerelease: "auto", 378 }, 379 }) 380 ctx.TokenType = context.TokenTypeGitHub 381 ctx.Semver = context.Semver{ 382 Major: 1, 383 Minor: 0, 384 Patch: 0, 385 Prerelease: "rc1", 386 } 387 require.NoError(t, Pipe{}.Default(ctx)) 388 require.Equal(t, true, ctx.PreRelease) 389 }) 390 391 t.Run("auto-rc-github-setup", func(t *testing.T) { 392 ctx := context.New(config.Project{ 393 Release: config.Release{ 394 GitHub: config.Repo{ 395 Name: "foo", 396 Owner: "foo", 397 }, 398 Prerelease: "auto", 399 }, 400 }) 401 ctx.TokenType = context.TokenTypeGitHub 402 ctx.Semver = context.Semver{ 403 Major: 1, 404 Minor: 0, 405 Patch: 0, 406 Prerelease: "rc1", 407 } 408 require.NoError(t, Pipe{}.Default(ctx)) 409 require.Equal(t, true, ctx.PreRelease) 410 }) 411 } 412 413 func TestDefaultPipeDisabled(t *testing.T) { 414 testlib.Mktmp(t) 415 testlib.GitInit(t) 416 testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") 417 418 ctx := context.New(config.Project{ 419 Release: config.Release{ 420 Disable: true, 421 }, 422 }) 423 ctx.TokenType = context.TokenTypeGitHub 424 require.NoError(t, Pipe{}.Default(ctx)) 425 require.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Name) 426 require.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Owner) 427 } 428 429 func TestDefaultFilled(t *testing.T) { 430 testlib.Mktmp(t) 431 testlib.GitInit(t) 432 testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") 433 434 ctx := &context.Context{ 435 Config: config.Project{ 436 Release: config.Release{ 437 GitHub: config.Repo{ 438 Name: "foo", 439 Owner: "bar", 440 }, 441 }, 442 }, 443 } 444 ctx.TokenType = context.TokenTypeGitHub 445 require.NoError(t, Pipe{}.Default(ctx)) 446 require.Equal(t, "foo", ctx.Config.Release.GitHub.Name) 447 require.Equal(t, "bar", ctx.Config.Release.GitHub.Owner) 448 } 449 450 func TestDefaultNotAGitRepo(t *testing.T) { 451 testlib.Mktmp(t) 452 ctx := &context.Context{ 453 Config: config.Project{}, 454 } 455 ctx.TokenType = context.TokenTypeGitHub 456 require.EqualError(t, Pipe{}.Default(ctx), "current folder is not a git repository") 457 require.Empty(t, ctx.Config.Release.GitHub.String()) 458 } 459 460 func TestDefaultGitRepoWithoutOrigin(t *testing.T) { 461 testlib.Mktmp(t) 462 ctx := &context.Context{ 463 Config: config.Project{}, 464 } 465 ctx.TokenType = context.TokenTypeGitHub 466 testlib.GitInit(t) 467 require.EqualError(t, Pipe{}.Default(ctx), "no remote configured to list refs from") 468 require.Empty(t, ctx.Config.Release.GitHub.String()) 469 } 470 471 func TestDefaultNotAGitRepoSnapshot(t *testing.T) { 472 testlib.Mktmp(t) 473 ctx := &context.Context{ 474 Config: config.Project{}, 475 } 476 ctx.TokenType = context.TokenTypeGitHub 477 ctx.Snapshot = true 478 require.NoError(t, Pipe{}.Default(ctx)) 479 require.Empty(t, ctx.Config.Release.GitHub.String()) 480 } 481 482 func TestDefaultGitRepoWithoutRemote(t *testing.T) { 483 testlib.Mktmp(t) 484 ctx := &context.Context{ 485 Config: config.Project{}, 486 } 487 ctx.TokenType = context.TokenTypeGitHub 488 require.Error(t, Pipe{}.Default(ctx)) 489 require.Empty(t, ctx.Config.Release.GitHub.String()) 490 } 491 492 func TestDefaultMultipleReleasesDefined(t *testing.T) { 493 ctx := context.New(config.Project{ 494 Release: config.Release{ 495 GitHub: config.Repo{ 496 Owner: "githubName", 497 Name: "githubName", 498 }, 499 GitLab: config.Repo{ 500 Owner: "gitlabOwner", 501 Name: "gitlabName", 502 }, 503 Gitea: config.Repo{ 504 Owner: "giteaOwner", 505 Name: "giteaName", 506 }, 507 }, 508 }) 509 require.EqualError(t, Pipe{}.Default(ctx), ErrMultipleReleases.Error()) 510 } 511 512 func TestSkip(t *testing.T) { 513 t.Run("skip", func(t *testing.T) { 514 ctx := context.New(config.Project{ 515 Release: config.Release{ 516 Disable: true, 517 }, 518 }) 519 require.True(t, Pipe{}.Skip(ctx)) 520 }) 521 522 t.Run("dont skip", func(t *testing.T) { 523 require.False(t, Pipe{}.Skip(context.New(config.Project{}))) 524 }) 525 } 526 527 type DummyClient struct { 528 FailToCreateRelease bool 529 FailToUpload bool 530 CreatedRelease bool 531 UploadedFile bool 532 UploadedFileNames []string 533 UploadedFilePaths map[string]string 534 FailFirstUpload bool 535 Lock sync.Mutex 536 } 537 538 func (c *DummyClient) CloseMilestone(ctx *context.Context, repo client.Repo, title string) error { 539 return nil 540 } 541 542 func (c *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID string, err error) { 543 if c.FailToCreateRelease { 544 return "", errors.New("release failed") 545 } 546 c.CreatedRelease = true 547 return 548 } 549 550 func (c *DummyClient) ReleaseURLTemplate(ctx *context.Context) (string, error) { 551 return "", nil 552 } 553 554 func (c *DummyClient) CreateFile(ctx *context.Context, commitAuthor config.CommitAuthor, repo client.Repo, content []byte, path, msg string) (err error) { 555 return 556 } 557 558 func (c *DummyClient) Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) error { 559 c.Lock.Lock() 560 defer c.Lock.Unlock() 561 if c.UploadedFilePaths == nil { 562 c.UploadedFilePaths = map[string]string{} 563 } 564 // ensure file is read to better mimic real behavior 565 _, err := io.ReadAll(file) 566 if err != nil { 567 return fmt.Errorf("unexpected error: %w", err) 568 } 569 if c.FailToUpload { 570 return errors.New("upload failed") 571 } 572 if c.FailFirstUpload { 573 c.FailFirstUpload = false 574 return client.RetriableError{Err: errors.New("upload failed, should retry")} 575 } 576 c.UploadedFile = true 577 c.UploadedFileNames = append(c.UploadedFileNames, artifact.Name) 578 c.UploadedFilePaths[artifact.Name] = artifact.Path 579 return nil 580 }