github.com/windmeup/goreleaser@v1.21.95/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/stretchr/testify/require" 14 "github.com/windmeup/goreleaser/internal/artifact" 15 "github.com/windmeup/goreleaser/internal/pipe" 16 "github.com/windmeup/goreleaser/internal/testctx" 17 "github.com/windmeup/goreleaser/internal/testlib" 18 "github.com/windmeup/goreleaser/pkg/config" 19 "github.com/windmeup/goreleaser/pkg/context" 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.Error(t, err) 446 require.Contains(t, err.Error(), "Unauthorized") 447 } 448 449 func TestRunPipe_FileNotFound(t *testing.T) { 450 ctx := context.New(config.Project{ 451 ProjectName: "mybin", 452 Dist: "archivetest/dist", 453 Uploads: []config.Upload{ 454 { 455 Method: http.MethodPut, 456 Name: "production", 457 Mode: "binary", 458 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 459 Username: "deployuser", 460 }, 461 }, 462 Archives: []config.Archive{{}}, 463 Env: []string{"UPLOAD_PRODUCTION_SECRET=deployuser-secret"}, 464 }) 465 ctx.Artifacts.Add(&artifact.Artifact{ 466 Name: "mybin", 467 Path: "archivetest/dist/mybin/mybin", 468 Goarch: "amd64", 469 Goos: "darwin", 470 Type: artifact.UploadableBinary, 471 }) 472 473 require.ErrorIs(t, Pipe{}.Publish(ctx), os.ErrNotExist) 474 } 475 476 func TestRunPipe_UnparsableTarget(t *testing.T) { 477 folder := t.TempDir() 478 dist := filepath.Join(folder, "dist") 479 require.NoError(t, os.Mkdir(dist, 0o755)) 480 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 481 binPath := filepath.Join(dist, "mybin", "mybin") 482 d1 := []byte("hello\ngo\n") 483 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 484 485 ctx := testctx.NewWithCfg(config.Project{ 486 ProjectName: "mybin", 487 Dist: dist, 488 Uploads: []config.Upload{ 489 { 490 Method: http.MethodPut, 491 Name: "production", 492 Mode: "binary", 493 Target: "://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 494 Username: "deployuser", 495 }, 496 }, 497 Archives: []config.Archive{ 498 {}, 499 }, 500 Env: []string{"UPLOAD_PRODUCTION_SECRET=deployuser-secret"}, 501 }) 502 ctx.Env = map[string]string{ 503 "UPLOAD_PRODUCTION_SECRET": "deployuser-secret", 504 } 505 ctx.Artifacts.Add(&artifact.Artifact{ 506 Name: "mybin", 507 Path: binPath, 508 Goarch: "amd64", 509 Goos: "darwin", 510 Type: artifact.UploadableBinary, 511 }) 512 513 require.EqualError(t, Pipe{}.Publish(ctx), `production: upload: upload failed: parse "://artifacts.company.com/example-repo-local/mybin/darwin/amd64/mybin": missing protocol scheme`) 514 } 515 516 func TestRunPipe_DirUpload(t *testing.T) { 517 folder := t.TempDir() 518 dist := filepath.Join(folder, "dist") 519 require.NoError(t, os.Mkdir(dist, 0o755)) 520 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 521 binPath := filepath.Join(dist, "mybin") 522 523 ctx := testctx.NewWithCfg(config.Project{ 524 ProjectName: "mybin", 525 Dist: dist, 526 Uploads: []config.Upload{ 527 { 528 Method: http.MethodPut, 529 Name: "production", 530 Mode: "binary", 531 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 532 Username: "deployuser", 533 }, 534 }, 535 Archives: []config.Archive{{}}, 536 Env: []string{"UPLOAD_PRODUCTION_SECRET=deployuser-secret"}, 537 }) 538 ctx.Artifacts.Add(&artifact.Artifact{ 539 Name: "mybin", 540 Path: filepath.Dir(binPath), 541 Goarch: "amd64", 542 Goos: "darwin", 543 Type: artifact.UploadableBinary, 544 }) 545 546 require.EqualError(t, Pipe{}.Publish(ctx), `upload: upload failed: the asset to upload can't be a directory`) 547 } 548 549 func TestDescription(t *testing.T) { 550 require.NotEmpty(t, Pipe{}.String()) 551 } 552 553 func TestPutsWithoutTarget(t *testing.T) { 554 ctx := testctx.NewWithCfg(config.Project{ 555 Uploads: []config.Upload{ 556 { 557 Method: http.MethodPut, 558 Name: "production", 559 Username: "deployuser", 560 }, 561 }, 562 Env: []string{"UPLOAD_PRODUCTION_SECRET=deployuser-secret"}, 563 }) 564 565 require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx))) 566 } 567 568 func TestPutsWithoutUsername(t *testing.T) { 569 ctx := testctx.NewWithCfg(config.Project{ 570 Uploads: []config.Upload{ 571 { 572 Method: http.MethodPut, 573 Name: "production", 574 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 575 }, 576 }, 577 Env: []string{"UPLOAD_PRODUCTION_SECRET=deployuser-secret"}, 578 }) 579 580 require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx))) 581 } 582 583 func TestPutsWithoutName(t *testing.T) { 584 require.True(t, pipe.IsSkip(Pipe{}.Publish(testctx.NewWithCfg(config.Project{ 585 Uploads: []config.Upload{ 586 { 587 Method: http.MethodPut, 588 Username: "deployuser", 589 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 590 }, 591 }, 592 })))) 593 } 594 595 func TestPutsWithoutSecret(t *testing.T) { 596 require.True(t, pipe.IsSkip(Pipe{}.Publish(testctx.NewWithCfg(config.Project{ 597 Uploads: []config.Upload{ 598 { 599 Method: http.MethodPut, 600 Name: "production", 601 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 602 Username: "deployuser", 603 }, 604 }, 605 })))) 606 } 607 608 func TestPutsWithInvalidMode(t *testing.T) { 609 ctx := testctx.NewWithCfg(config.Project{ 610 Uploads: []config.Upload{ 611 { 612 Method: http.MethodPut, 613 Name: "production", 614 Mode: "does-not-exists", 615 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 616 Username: "deployuser", 617 }, 618 }, 619 Env: []string{"UPLOAD_PRODUCTION_SECRET=deployuser-secret"}, 620 }) 621 require.Error(t, Pipe{}.Publish(ctx)) 622 } 623 624 func TestDefault(t *testing.T) { 625 ctx := testctx.NewWithCfg(config.Project{ 626 Uploads: []config.Upload{ 627 { 628 Name: "production", 629 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 630 Username: "deployuser", 631 }, 632 }, 633 }) 634 require.NoError(t, Pipe{}.Default(ctx)) 635 require.Len(t, ctx.Config.Uploads, 1) 636 upload := ctx.Config.Uploads[0] 637 require.Equal(t, "archive", upload.Mode) 638 require.Equal(t, http.MethodPut, upload.Method) 639 } 640 641 func TestDefaultNoPuts(t *testing.T) { 642 ctx := testctx.NewWithCfg(config.Project{ 643 Uploads: []config.Upload{}, 644 }) 645 require.NoError(t, Pipe{}.Default(ctx)) 646 require.Empty(t, ctx.Config.Uploads) 647 } 648 649 func TestDefaultSet(t *testing.T) { 650 ctx := testctx.NewWithCfg(config.Project{ 651 Uploads: []config.Upload{ 652 { 653 Method: http.MethodPost, 654 Mode: "custom", 655 }, 656 }, 657 }) 658 require.NoError(t, Pipe{}.Default(ctx)) 659 require.Len(t, ctx.Config.Uploads, 1) 660 upload := ctx.Config.Uploads[0] 661 require.Equal(t, "custom", upload.Mode) 662 require.Equal(t, http.MethodPost, upload.Method) 663 } 664 665 func TestSkip(t *testing.T) { 666 t.Run("skip", func(t *testing.T) { 667 require.True(t, Pipe{}.Skip(testctx.New())) 668 }) 669 670 t.Run("dont skip", func(t *testing.T) { 671 ctx := testctx.NewWithCfg(config.Project{ 672 Uploads: []config.Upload{ 673 {}, 674 }, 675 }) 676 require.False(t, Pipe{}.Skip(ctx)) 677 }) 678 }