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