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