github.com/triarius/goreleaser@v1.12.5/internal/pipe/upload/upload_test.go (about) 1 package upload 2 3 import ( 4 "fmt" 5 "net/http" 6 h "net/http" 7 "net/http/httptest" 8 "os" 9 "path/filepath" 10 "sync" 11 "testing" 12 13 "github.com/triarius/goreleaser/internal/artifact" 14 "github.com/triarius/goreleaser/internal/pipe" 15 "github.com/triarius/goreleaser/internal/testlib" 16 "github.com/triarius/goreleaser/pkg/config" 17 "github.com/triarius/goreleaser/pkg/context" 18 "github.com/stretchr/testify/require" 19 ) 20 21 var ( 22 // mux is the HTTP request multiplexer used with the test server. 23 mux *http.ServeMux 24 25 // server is a test HTTP server used to provide mock API responses. 26 server *httptest.Server 27 ) 28 29 func setup() { 30 // test server 31 mux = http.NewServeMux() 32 server = httptest.NewServer(mux) 33 } 34 35 // teardown closes the test HTTP server. 36 func teardown() { 37 server.Close() 38 } 39 40 func requireMethodPut(t *testing.T, r *http.Request) { 41 t.Helper() 42 require.Equal(t, http.MethodPut, r.Method) 43 } 44 45 func requireHeader(t *testing.T, r *http.Request, header, want string) { 46 t.Helper() 47 require.Equal(t, want, r.Header.Get(header)) 48 } 49 50 // TODO: improve all tests below by checking whether the mocked handlers 51 // were called or not. 52 53 func TestRunPipe_ModeBinary(t *testing.T) { 54 setup() 55 defer teardown() 56 57 folder := t.TempDir() 58 dist := filepath.Join(folder, "dist") 59 require.NoError(t, os.Mkdir(dist, 0o755)) 60 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 61 binPath := filepath.Join(dist, "mybin", "mybin") 62 d1 := []byte("hello\ngo\n") 63 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 64 65 // Dummy http server 66 mux.HandleFunc("/example-repo-local/mybin/darwin/amd64/mybin", func(w http.ResponseWriter, r *http.Request) { 67 requireMethodPut(t, r) 68 requireHeader(t, r, "Content-Length", "9") 69 // Basic auth of user "deployuser" with secret "deployuser-secret" 70 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 71 72 w.Header().Set("Location", "/production-repo-remote/mybin/linux/amd64/mybin") 73 w.WriteHeader(http.StatusCreated) 74 }) 75 mux.HandleFunc("/example-repo-local/mybin/linux/amd64/mybin", func(w http.ResponseWriter, r *http.Request) { 76 requireMethodPut(t, r) 77 requireHeader(t, r, "Content-Length", "9") 78 // Basic auth of user "deployuser" with secret "deployuser-secret" 79 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 80 81 w.Header().Set("Location", "/production-repo-remote/mybin/linux/amd64/mybin") 82 w.WriteHeader(http.StatusCreated) 83 }) 84 mux.HandleFunc("/production-repo-remote/mybin/darwin/amd64/mybin", func(w http.ResponseWriter, r *http.Request) { 85 requireMethodPut(t, r) 86 requireHeader(t, r, "Content-Length", "9") 87 // Basic auth of user "productionuser" with secret "productionuser-apikey" 88 requireHeader(t, r, "Authorization", "Basic cHJvZHVjdGlvbnVzZXI6cHJvZHVjdGlvbnVzZXItYXBpa2V5") 89 90 w.Header().Set("Location", "/production-repo-remote/mybin/linux/amd64/mybin") 91 w.WriteHeader(http.StatusCreated) 92 }) 93 mux.HandleFunc("/production-repo-remote/mybin/linux/amd64/mybin", func(w http.ResponseWriter, r *http.Request) { 94 requireMethodPut(t, r) 95 requireHeader(t, r, "Content-Length", "9") 96 // Basic auth of user "productionuser" with secret "productionuser-apikey" 97 requireHeader(t, r, "Authorization", "Basic cHJvZHVjdGlvbnVzZXI6cHJvZHVjdGlvbnVzZXItYXBpa2V5") 98 99 w.Header().Set("Location", "/production-repo-remote/mybin/linux/amd64/mybin") 100 w.WriteHeader(http.StatusCreated) 101 }) 102 103 ctx := context.New(config.Project{ 104 ProjectName: "mybin", 105 Dist: dist, 106 Uploads: []config.Upload{ 107 { 108 Method: h.MethodPut, 109 Name: "production-us", 110 Mode: "binary", 111 Target: fmt.Sprintf("%s/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", server.URL), 112 Username: "deployuser", 113 }, 114 { 115 Method: h.MethodPut, 116 Name: "production-eu", 117 Mode: "binary", 118 Target: fmt.Sprintf("%s/production-repo-remote/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", server.URL), 119 Username: "productionuser", 120 }, 121 }, 122 Archives: []config.Archive{ 123 {}, 124 }, 125 }) 126 ctx.Env = map[string]string{ 127 "UPLOAD_PRODUCTION-US_SECRET": "deployuser-secret", 128 "UPLOAD_PRODUCTION-EU_SECRET": "productionuser-apikey", 129 } 130 for _, goos := range []string{"linux", "darwin"} { 131 ctx.Artifacts.Add(&artifact.Artifact{ 132 Name: "mybin", 133 Path: binPath, 134 Goarch: "amd64", 135 Goos: goos, 136 Type: artifact.UploadableBinary, 137 }) 138 } 139 140 require.NoError(t, Pipe{}.Publish(ctx)) 141 } 142 143 func TestRunPipe_ModeArchive(t *testing.T) { 144 setup() 145 defer teardown() 146 147 folder := t.TempDir() 148 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 149 require.NoError(t, err) 150 require.NoError(t, tarfile.Close()) 151 debfile, err := os.Create(filepath.Join(folder, "bin.deb")) 152 require.NoError(t, err) 153 require.NoError(t, debfile.Close()) 154 155 ctx := context.New(config.Project{ 156 ProjectName: "goreleaser", 157 Dist: folder, 158 Uploads: []config.Upload{ 159 { 160 Method: h.MethodPut, 161 Name: "production", 162 Mode: "archive", 163 Target: fmt.Sprintf("%s/example-repo-local/{{ .ProjectName }}/{{ .Version }}/", server.URL), 164 Username: "deployuser", 165 }, 166 }, 167 Archives: []config.Archive{ 168 {}, 169 }, 170 }) 171 ctx.Env = map[string]string{ 172 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 173 } 174 ctx.Version = "1.0.0" 175 ctx.Artifacts.Add(&artifact.Artifact{ 176 Type: artifact.UploadableArchive, 177 Name: "bin.tar.gz", 178 Path: tarfile.Name(), 179 }) 180 ctx.Artifacts.Add(&artifact.Artifact{ 181 Type: artifact.LinuxPackage, 182 Name: "bin.deb", 183 Path: debfile.Name(), 184 }) 185 186 var uploads sync.Map 187 188 // Dummy http server 189 mux.HandleFunc("/example-repo-local/goreleaser/1.0.0/bin.tar.gz", func(w http.ResponseWriter, r *http.Request) { 190 requireMethodPut(t, r) 191 // Basic auth of user "deployuser" with secret "deployuser-secret" 192 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 193 194 w.Header().Set("Location", "/example-repo-local/goreleaser/1.0.0/bin.tar.gz") 195 w.WriteHeader(http.StatusCreated) 196 uploads.Store("targz", true) 197 }) 198 mux.HandleFunc("/example-repo-local/goreleaser/1.0.0/bin.deb", func(w http.ResponseWriter, r *http.Request) { 199 requireMethodPut(t, r) 200 // Basic auth of user "deployuser" with secret "deployuser-secret" 201 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 202 203 w.Header().Set("Location", "/example-repo-local/goreleaser/1.0.0/bin.deb") 204 w.WriteHeader(http.StatusCreated) 205 uploads.Store("deb", true) 206 }) 207 208 require.NoError(t, Pipe{}.Publish(ctx)) 209 _, ok := uploads.Load("targz") 210 require.True(t, ok, "tar.gz file was not uploaded") 211 _, ok = uploads.Load("deb") 212 require.True(t, ok, "deb file was not uploaded") 213 } 214 215 func TestRunPipe_ModeBinary_CustomArtifactName(t *testing.T) { 216 setup() 217 defer teardown() 218 219 folder := t.TempDir() 220 dist := filepath.Join(folder, "dist") 221 require.NoError(t, os.Mkdir(dist, 0o755)) 222 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 223 binPath := filepath.Join(dist, "mybin", "mybin") 224 d1 := []byte("hello\ngo\n") 225 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 226 227 // Dummy http server 228 mux.HandleFunc("/example-repo-local/mybin/darwin/amd64/mybin;deb.distribution=xenial", func(w http.ResponseWriter, r *http.Request) { 229 requireMethodPut(t, r) 230 requireHeader(t, r, "Content-Length", "9") 231 // Basic auth of user "deployuser" with secret "deployuser-secret" 232 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 233 234 w.Header().Set("Location", "/production-repo-remote/mybin/linux/amd64/mybin;deb.distribution=xenial") 235 w.WriteHeader(http.StatusCreated) 236 }) 237 mux.HandleFunc("/example-repo-local/mybin/linux/amd64/mybin;deb.distribution=xenial", func(w http.ResponseWriter, r *http.Request) { 238 requireMethodPut(t, r) 239 requireHeader(t, r, "Content-Length", "9") 240 // Basic auth of user "deployuser" with secret "deployuser-secret" 241 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 242 243 w.Header().Set("Location", "/example-repo-local/mybin/linux/amd64/mybin;deb.distribution=xenial") 244 w.WriteHeader(http.StatusCreated) 245 }) 246 247 ctx := context.New(config.Project{ 248 ProjectName: "mybin", 249 Dist: dist, 250 Uploads: []config.Upload{ 251 { 252 Method: h.MethodPut, 253 Name: "production-us", 254 Mode: "binary", 255 Target: fmt.Sprintf("%s/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}/{{ .ArtifactName }};deb.distribution=xenial", server.URL), 256 Username: "deployuser", 257 CustomArtifactName: true, 258 }, 259 }, 260 Archives: []config.Archive{ 261 {}, 262 }, 263 }) 264 ctx.Env = map[string]string{ 265 "UPLOAD_PRODUCTION-US_SECRET": "deployuser-secret", 266 } 267 for _, goos := range []string{"linux", "darwin"} { 268 ctx.Artifacts.Add(&artifact.Artifact{ 269 Name: "mybin", 270 Path: binPath, 271 Goarch: "amd64", 272 Goos: goos, 273 Type: artifact.UploadableBinary, 274 }) 275 } 276 277 require.NoError(t, Pipe{}.Publish(ctx)) 278 } 279 280 func TestRunPipe_ModeArchive_CustomArtifactName(t *testing.T) { 281 setup() 282 defer teardown() 283 284 folder := t.TempDir() 285 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 286 require.NoError(t, err) 287 require.NoError(t, tarfile.Close()) 288 debfile, err := os.Create(filepath.Join(folder, "bin.deb")) 289 require.NoError(t, err) 290 require.NoError(t, debfile.Close()) 291 292 ctx := context.New(config.Project{ 293 ProjectName: "goreleaser", 294 Dist: folder, 295 Uploads: []config.Upload{ 296 { 297 Method: h.MethodPut, 298 Name: "production", 299 Mode: "archive", 300 Target: fmt.Sprintf("%s/example-repo-local/{{ .ProjectName }}/{{ .Version }}/{{ .ArtifactName }};deb.distribution=xenial", server.URL), 301 Username: "deployuser", 302 CustomArtifactName: true, 303 }, 304 }, 305 Archives: []config.Archive{ 306 {}, 307 }, 308 }) 309 ctx.Env = map[string]string{ 310 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 311 } 312 ctx.Version = "1.0.0" 313 ctx.Artifacts.Add(&artifact.Artifact{ 314 Type: artifact.UploadableArchive, 315 Name: "bin.tar.gz", 316 Path: tarfile.Name(), 317 }) 318 ctx.Artifacts.Add(&artifact.Artifact{ 319 Type: artifact.LinuxPackage, 320 Name: "bin.deb", 321 Path: debfile.Name(), 322 }) 323 324 var uploads sync.Map 325 326 // Dummy http server 327 mux.HandleFunc("/example-repo-local/goreleaser/1.0.0/bin.tar.gz;deb.distribution=xenial", func(w http.ResponseWriter, r *http.Request) { 328 requireMethodPut(t, r) 329 // Basic auth of user "deployuser" with secret "deployuser-secret" 330 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 331 332 w.Header().Set("Location", "/example-repo-local/goreleaser/1.0.0/bin.tar.gz;deb.distribution=xenial") 333 w.WriteHeader(http.StatusCreated) 334 uploads.Store("targz", true) 335 }) 336 mux.HandleFunc("/example-repo-local/goreleaser/1.0.0/bin.deb;deb.distribution=xenial", func(w http.ResponseWriter, r *http.Request) { 337 requireMethodPut(t, r) 338 // Basic auth of user "deployuser" with secret "deployuser-secret" 339 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 340 341 w.Header().Set("Location", "/example-repo-local/goreleaser/1.0.0/bin.deb;deb.distribution=xenial") 342 w.WriteHeader(http.StatusCreated) 343 uploads.Store("deb", true) 344 }) 345 346 require.NoError(t, Pipe{}.Publish(ctx)) 347 _, ok := uploads.Load("targz") 348 require.True(t, ok, "tar.gz file was not uploaded") 349 _, ok = uploads.Load("deb") 350 require.True(t, ok, "deb file was not uploaded") 351 } 352 353 func TestRunPipe_ArtifactoryDown(t *testing.T) { 354 folder := t.TempDir() 355 tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) 356 require.NoError(t, err) 357 require.NoError(t, tarfile.Close()) 358 359 ctx := context.New(config.Project{ 360 ProjectName: "goreleaser", 361 Dist: folder, 362 Uploads: []config.Upload{ 363 { 364 Method: h.MethodPut, 365 Name: "production", 366 Mode: "archive", 367 Target: "http://localhost:1234/example-repo-local/{{ .ProjectName }}/{{ .Version }}/", 368 Username: "deployuser", 369 }, 370 }, 371 }) 372 ctx.Version = "2.0.0" 373 ctx.Env = map[string]string{ 374 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 375 } 376 ctx.Artifacts.Add(&artifact.Artifact{ 377 Type: artifact.UploadableArchive, 378 Name: "bin.tar.gz", 379 Path: tarfile.Name(), 380 }) 381 err = Pipe{}.Publish(ctx) 382 require.Error(t, err) 383 require.Contains(t, err.Error(), "connection refused") 384 } 385 386 func TestRunPipe_TargetTemplateError(t *testing.T) { 387 folder := t.TempDir() 388 dist := filepath.Join(folder, "dist") 389 binPath := filepath.Join(dist, "mybin", "mybin") 390 391 ctx := context.New(config.Project{ 392 ProjectName: "mybin", 393 Dist: dist, 394 Uploads: []config.Upload{ 395 { 396 Method: h.MethodPut, 397 Name: "production", 398 Mode: "binary", 399 // This template is not correct and should fail 400 Target: "http://storage.company.com/example-repo-local/{{ .ProjectName}", 401 Username: "deployuser", 402 }, 403 }, 404 Archives: []config.Archive{ 405 {}, 406 }, 407 }) 408 ctx.Env = map[string]string{ 409 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 410 } 411 ctx.Artifacts.Add(&artifact.Artifact{ 412 Name: "mybin", 413 Path: binPath, 414 Goarch: "amd64", 415 Goos: "darwin", 416 Type: artifact.UploadableBinary, 417 }) 418 testlib.RequireTemplateError(t, Pipe{}.Publish(ctx)) 419 } 420 421 func TestRunPipe_BadCredentials(t *testing.T) { 422 setup() 423 defer teardown() 424 425 folder := t.TempDir() 426 dist := filepath.Join(folder, "dist") 427 require.NoError(t, os.Mkdir(dist, 0o755)) 428 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 429 binPath := filepath.Join(dist, "mybin", "mybin") 430 d1 := []byte("hello\ngo\n") 431 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 432 433 // Dummy http server 434 mux.HandleFunc("/example-repo-local/mybin/darwin/amd64/mybin", func(w http.ResponseWriter, r *http.Request) { 435 requireMethodPut(t, r) 436 requireHeader(t, r, "Content-Length", "9") 437 // Basic auth of user "deployuser" with secret "deployuser-secret" 438 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 439 440 w.WriteHeader(http.StatusUnauthorized) 441 }) 442 443 ctx := context.New(config.Project{ 444 ProjectName: "mybin", 445 Dist: dist, 446 Uploads: []config.Upload{ 447 { 448 Method: h.MethodPut, 449 Name: "production", 450 Mode: "binary", 451 Target: fmt.Sprintf("%s/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", server.URL), 452 Username: "deployuser", 453 }, 454 }, 455 Archives: []config.Archive{ 456 {}, 457 }, 458 }) 459 ctx.Env = map[string]string{ 460 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 461 } 462 ctx.Artifacts.Add(&artifact.Artifact{ 463 Name: "mybin", 464 Path: binPath, 465 Goarch: "amd64", 466 Goos: "darwin", 467 Type: artifact.UploadableBinary, 468 }) 469 470 err := Pipe{}.Publish(ctx) 471 require.Error(t, err) 472 require.Contains(t, err.Error(), "Unauthorized") 473 } 474 475 func TestRunPipe_FileNotFound(t *testing.T) { 476 ctx := context.New(config.Project{ 477 ProjectName: "mybin", 478 Dist: "archivetest/dist", 479 Uploads: []config.Upload{ 480 { 481 Method: h.MethodPut, 482 Name: "production", 483 Mode: "binary", 484 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 485 Username: "deployuser", 486 }, 487 }, 488 Archives: []config.Archive{ 489 {}, 490 }, 491 }) 492 ctx.Env = map[string]string{ 493 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 494 } 495 ctx.Artifacts.Add(&artifact.Artifact{ 496 Name: "mybin", 497 Path: "archivetest/dist/mybin/mybin", 498 Goarch: "amd64", 499 Goos: "darwin", 500 Type: artifact.UploadableBinary, 501 }) 502 503 require.EqualError(t, Pipe{}.Publish(ctx), `open archivetest/dist/mybin/mybin: no such file or directory`) 504 } 505 506 func TestRunPipe_UnparsableTarget(t *testing.T) { 507 folder := t.TempDir() 508 dist := filepath.Join(folder, "dist") 509 require.NoError(t, os.Mkdir(dist, 0o755)) 510 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 511 binPath := filepath.Join(dist, "mybin", "mybin") 512 d1 := []byte("hello\ngo\n") 513 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 514 515 ctx := context.New(config.Project{ 516 ProjectName: "mybin", 517 Dist: dist, 518 Uploads: []config.Upload{ 519 { 520 Method: h.MethodPut, 521 Name: "production", 522 Mode: "binary", 523 Target: "://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 524 Username: "deployuser", 525 }, 526 }, 527 Archives: []config.Archive{ 528 {}, 529 }, 530 }) 531 ctx.Env = map[string]string{ 532 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 533 } 534 ctx.Artifacts.Add(&artifact.Artifact{ 535 Name: "mybin", 536 Path: binPath, 537 Goarch: "amd64", 538 Goos: "darwin", 539 Type: artifact.UploadableBinary, 540 }) 541 542 require.EqualError(t, Pipe{}.Publish(ctx), `upload: upload failed: parse "://artifacts.company.com/example-repo-local/mybin/darwin/amd64/mybin": missing protocol scheme`) 543 } 544 545 func TestRunPipe_DirUpload(t *testing.T) { 546 folder := t.TempDir() 547 dist := filepath.Join(folder, "dist") 548 require.NoError(t, os.Mkdir(dist, 0o755)) 549 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 550 binPath := filepath.Join(dist, "mybin") 551 552 ctx := context.New(config.Project{ 553 ProjectName: "mybin", 554 Dist: dist, 555 Uploads: []config.Upload{ 556 { 557 Method: h.MethodPut, 558 Name: "production", 559 Mode: "binary", 560 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 561 Username: "deployuser", 562 }, 563 }, 564 Archives: []config.Archive{ 565 {}, 566 }, 567 }) 568 ctx.Env = map[string]string{ 569 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 570 } 571 ctx.Artifacts.Add(&artifact.Artifact{ 572 Name: "mybin", 573 Path: filepath.Dir(binPath), 574 Goarch: "amd64", 575 Goos: "darwin", 576 Type: artifact.UploadableBinary, 577 }) 578 579 require.EqualError(t, Pipe{}.Publish(ctx), `upload: upload failed: the asset to upload can't be a directory`) 580 } 581 582 func TestDescription(t *testing.T) { 583 require.NotEmpty(t, Pipe{}.String()) 584 } 585 586 func TestPutsWithoutTarget(t *testing.T) { 587 ctx := &context.Context{ 588 Env: map[string]string{ 589 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 590 }, 591 Config: config.Project{ 592 Uploads: []config.Upload{ 593 { 594 Method: h.MethodPut, 595 Name: "production", 596 Username: "deployuser", 597 }, 598 }, 599 }, 600 } 601 602 require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx))) 603 } 604 605 func TestPutsWithoutUsername(t *testing.T) { 606 ctx := &context.Context{ 607 Env: map[string]string{ 608 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 609 }, 610 Config: config.Project{ 611 Uploads: []config.Upload{ 612 { 613 Method: h.MethodPut, 614 Name: "production", 615 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 616 }, 617 }, 618 }, 619 } 620 621 require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx))) 622 } 623 624 func TestPutsWithoutName(t *testing.T) { 625 require.True(t, pipe.IsSkip(Pipe{}.Publish(context.New(config.Project{ 626 Uploads: []config.Upload{ 627 { 628 Method: h.MethodPut, 629 Username: "deployuser", 630 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 631 }, 632 }, 633 })))) 634 } 635 636 func TestPutsWithoutSecret(t *testing.T) { 637 require.True(t, pipe.IsSkip(Pipe{}.Publish(context.New(config.Project{ 638 Uploads: []config.Upload{ 639 { 640 Method: h.MethodPut, 641 Name: "production", 642 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 643 Username: "deployuser", 644 }, 645 }, 646 })))) 647 } 648 649 func TestPutsWithInvalidMode(t *testing.T) { 650 ctx := &context.Context{ 651 Env: map[string]string{ 652 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 653 }, 654 Config: config.Project{ 655 Uploads: []config.Upload{ 656 { 657 Method: h.MethodPut, 658 Name: "production", 659 Mode: "does-not-exists", 660 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 661 Username: "deployuser", 662 }, 663 }, 664 }, 665 } 666 require.Error(t, Pipe{}.Publish(ctx)) 667 } 668 669 func TestDefault(t *testing.T) { 670 ctx := &context.Context{ 671 Config: config.Project{ 672 Uploads: []config.Upload{ 673 { 674 Name: "production", 675 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 676 Username: "deployuser", 677 }, 678 }, 679 }, 680 } 681 require.NoError(t, Pipe{}.Default(ctx)) 682 require.Len(t, ctx.Config.Uploads, 1) 683 upload := ctx.Config.Uploads[0] 684 require.Equal(t, "archive", upload.Mode) 685 require.Equal(t, h.MethodPut, upload.Method) 686 } 687 688 func TestDefaultNoPuts(t *testing.T) { 689 ctx := &context.Context{ 690 Config: config.Project{ 691 Uploads: []config.Upload{}, 692 }, 693 } 694 require.NoError(t, Pipe{}.Default(ctx)) 695 require.Empty(t, ctx.Config.Uploads) 696 } 697 698 func TestDefaultSet(t *testing.T) { 699 ctx := &context.Context{ 700 Config: config.Project{ 701 Uploads: []config.Upload{ 702 { 703 Method: h.MethodPost, 704 Mode: "custom", 705 }, 706 }, 707 }, 708 } 709 require.NoError(t, Pipe{}.Default(ctx)) 710 require.Len(t, ctx.Config.Uploads, 1) 711 upload := ctx.Config.Uploads[0] 712 require.Equal(t, "custom", upload.Mode) 713 require.Equal(t, h.MethodPost, upload.Method) 714 } 715 716 func TestSkip(t *testing.T) { 717 t.Run("skip", func(t *testing.T) { 718 require.True(t, Pipe{}.Skip(context.New(config.Project{}))) 719 }) 720 721 t.Run("dont skip", func(t *testing.T) { 722 ctx := context.New(config.Project{ 723 Uploads: []config.Upload{ 724 {}, 725 }, 726 }) 727 require.False(t, Pipe{}.Skip(ctx)) 728 }) 729 }