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