github.com/goreleaser/goreleaser@v1.25.1/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/goreleaser/goreleaser/internal/artifact" 14 "github.com/goreleaser/goreleaser/internal/testctx" 15 "github.com/goreleaser/goreleaser/internal/testlib" 16 "github.com/goreleaser/goreleaser/pkg/config" 17 "github.com/stretchr/testify/require" 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.ErrorContains(t, err, "Bad credentials") 422 } 423 424 func TestRunPipe_UnparsableErrorResponse(t *testing.T) { 425 setup() 426 defer teardown() 427 428 folder := t.TempDir() 429 dist := filepath.Join(folder, "dist") 430 require.NoError(t, os.Mkdir(dist, 0o755)) 431 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 432 binPath := filepath.Join(dist, "mybin", "mybin") 433 d1 := []byte("hello\ngo\n") 434 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 435 436 // Dummy artifactories 437 mux.HandleFunc("/example-repo-local/mybin/darwin/amd64/mybin", func(w http.ResponseWriter, r *http.Request) { 438 requireMethodPut(t, r) 439 requireHeader(t, r, "Content-Length", "9") 440 // Basic auth of user "deployuser" with secret "deployuser-secret" 441 requireHeader(t, r, "Authorization", "Basic ZGVwbG95dXNlcjpkZXBsb3l1c2VyLXNlY3JldA==") 442 443 w.WriteHeader(http.StatusUnauthorized) 444 fmt.Fprint(w, `<body><h1>error</h1></body>`) 445 }) 446 447 ctx := testctx.NewWithCfg(config.Project{ 448 ProjectName: "mybin", 449 Dist: dist, 450 Artifactories: []config.Upload{ 451 { 452 Name: "production", 453 Mode: "binary", 454 Target: fmt.Sprintf("%s/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", server.URL), 455 Username: "deployuser", 456 }, 457 }, 458 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 459 Archives: []config.Archive{{}}, 460 }) 461 ctx.Artifacts.Add(&artifact.Artifact{ 462 Name: "mybin", 463 Path: binPath, 464 Goarch: "amd64", 465 Goos: "darwin", 466 Type: artifact.UploadableBinary, 467 }) 468 469 require.NoError(t, Pipe{}.Default(ctx)) 470 require.EqualError(t, Pipe{}.Publish(ctx), `production: artifactory: upload failed: unexpected error: invalid character '<' looking for beginning of value: <body><h1>error</h1></body>`) 471 } 472 473 func TestRunPipe_FileNotFound(t *testing.T) { 474 ctx := testctx.NewWithCfg(config.Project{ 475 ProjectName: "mybin", 476 Dist: "archivetest/dist", 477 Artifactories: []config.Upload{ 478 { 479 Name: "production", 480 Mode: "binary", 481 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 482 Username: "deployuser", 483 }, 484 }, 485 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 486 Archives: []config.Archive{{}}, 487 }) 488 ctx.Artifacts.Add(&artifact.Artifact{ 489 Name: "mybin", 490 Path: "archivetest/dist/mybin/mybin", 491 Goarch: "amd64", 492 Goos: "darwin", 493 Type: artifact.UploadableBinary, 494 }) 495 496 require.NoError(t, Pipe{}.Default(ctx)) 497 require.ErrorIs(t, Pipe{}.Publish(ctx), os.ErrNotExist) 498 } 499 500 func TestRunPipe_UnparsableTarget(t *testing.T) { 501 folder := t.TempDir() 502 dist := filepath.Join(folder, "dist") 503 require.NoError(t, os.Mkdir(dist, 0o755)) 504 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 505 binPath := filepath.Join(dist, "mybin", "mybin") 506 d1 := []byte("hello\ngo\n") 507 require.NoError(t, os.WriteFile(binPath, d1, 0o666)) 508 509 ctx := testctx.NewWithCfg(config.Project{ 510 ProjectName: "mybin", 511 Dist: dist, 512 Artifactories: []config.Upload{ 513 { 514 Name: "production", 515 Mode: "binary", 516 Target: "://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 517 Username: "deployuser", 518 }, 519 }, 520 Archives: []config.Archive{{}}, 521 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 522 }) 523 ctx.Artifacts.Add(&artifact.Artifact{ 524 Name: "mybin", 525 Path: binPath, 526 Goarch: "amd64", 527 Goos: "darwin", 528 Type: artifact.UploadableBinary, 529 }) 530 531 require.NoError(t, Pipe{}.Default(ctx)) 532 require.EqualError(t, Pipe{}.Publish(ctx), `production: artifactory: upload failed: parse "://artifacts.company.com/example-repo-local/mybin/darwin/amd64/mybin": missing protocol scheme`) 533 } 534 535 func TestRunPipe_DirUpload(t *testing.T) { 536 folder := t.TempDir() 537 dist := filepath.Join(folder, "dist") 538 require.NoError(t, os.Mkdir(dist, 0o755)) 539 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 540 binPath := filepath.Join(dist, "mybin") 541 542 ctx := testctx.NewWithCfg(config.Project{ 543 ProjectName: "mybin", 544 Dist: dist, 545 Artifactories: []config.Upload{ 546 { 547 Name: "production", 548 Mode: "binary", 549 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 550 Username: "deployuser", 551 }, 552 }, 553 Archives: []config.Archive{{}}, 554 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 555 }) 556 ctx.Artifacts.Add(&artifact.Artifact{ 557 Name: "mybin", 558 Path: filepath.Dir(binPath), 559 Goarch: "amd64", 560 Goos: "darwin", 561 Type: artifact.UploadableBinary, 562 }) 563 564 require.NoError(t, Pipe{}.Default(ctx)) 565 require.EqualError(t, Pipe{}.Publish(ctx), `artifactory: upload failed: the asset to upload can't be a directory`) 566 } 567 568 func TestDescription(t *testing.T) { 569 require.NotEmpty(t, Pipe{}.String()) 570 } 571 572 func TestArtifactoriesWithoutTarget(t *testing.T) { 573 ctx := testctx.NewWithCfg(config.Project{ 574 Artifactories: []config.Upload{ 575 { 576 Name: "production", 577 Username: "deployuser", 578 }, 579 }, 580 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 581 }) 582 require.NoError(t, Pipe{}.Default(ctx)) 583 testlib.AssertSkipped(t, Pipe{}.Publish(ctx)) 584 } 585 586 func TestArtifactoriesWithoutUsername(t *testing.T) { 587 ctx := testctx.NewWithCfg(config.Project{ 588 Artifactories: []config.Upload{ 589 { 590 Name: "production", 591 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 592 }, 593 }, 594 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 595 }) 596 require.NoError(t, Pipe{}.Default(ctx)) 597 testlib.AssertSkipped(t, Pipe{}.Publish(ctx)) 598 } 599 600 func TestArtifactoriesWithoutName(t *testing.T) { 601 ctx := testctx.NewWithCfg(config.Project{ 602 Artifactories: []config.Upload{ 603 { 604 Username: "deployuser", 605 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 606 }, 607 }, 608 }) 609 require.NoError(t, Pipe{}.Default(ctx)) 610 testlib.AssertSkipped(t, Pipe{}.Publish(ctx)) 611 } 612 613 func TestArtifactoriesWithoutSecret(t *testing.T) { 614 ctx := testctx.NewWithCfg(config.Project{ 615 Artifactories: []config.Upload{ 616 { 617 Name: "production", 618 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 619 Username: "deployuser", 620 }, 621 }, 622 }) 623 require.NoError(t, Pipe{}.Default(ctx)) 624 testlib.AssertSkipped(t, Pipe{}.Publish(ctx)) 625 } 626 627 func TestArtifactoriesWithInvalidMode(t *testing.T) { 628 ctx := testctx.NewWithCfg(config.Project{ 629 Artifactories: []config.Upload{ 630 { 631 Name: "production", 632 Mode: "does-not-exists", 633 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 634 Username: "deployuser", 635 }, 636 }, 637 Env: []string{"ARTIFACTORY_PRODUCTION_SECRET=deployuser-secret"}, 638 }) 639 require.NoError(t, Pipe{}.Default(ctx)) 640 require.Error(t, Pipe{}.Publish(ctx)) 641 } 642 643 func TestDefault(t *testing.T) { 644 ctx := testctx.NewWithCfg(config.Project{ 645 Artifactories: []config.Upload{ 646 { 647 Name: "production", 648 Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}", 649 Username: "deployuser", 650 }, 651 }, 652 }) 653 654 require.NoError(t, Pipe{}.Default(ctx)) 655 require.Len(t, ctx.Config.Artifactories, 1) 656 artifactory := ctx.Config.Artifactories[0] 657 require.Equal(t, "archive", artifactory.Mode) 658 } 659 660 func TestDefaultNoArtifactories(t *testing.T) { 661 ctx := testctx.NewWithCfg(config.Project{ 662 Artifactories: []config.Upload{}, 663 }) 664 require.NoError(t, Pipe{}.Default(ctx)) 665 require.Empty(t, ctx.Config.Artifactories) 666 } 667 668 func TestDefaultSet(t *testing.T) { 669 ctx := testctx.NewWithCfg(config.Project{ 670 Artifactories: []config.Upload{ 671 { 672 Mode: "custom", 673 ChecksumHeader: "foo", 674 }, 675 }, 676 }) 677 require.NoError(t, Pipe{}.Default(ctx)) 678 require.Len(t, ctx.Config.Artifactories, 1) 679 artifactory := ctx.Config.Artifactories[0] 680 require.Equal(t, "custom", artifactory.Mode) 681 require.Equal(t, "foo", artifactory.ChecksumHeader) 682 } 683 684 func TestSkip(t *testing.T) { 685 t.Run("skip", func(t *testing.T) { 686 require.True(t, Pipe{}.Skip(testctx.New())) 687 }) 688 689 t.Run("dont skip", func(t *testing.T) { 690 ctx := testctx.NewWithCfg(config.Project{ 691 Artifactories: []config.Upload{{}}, 692 }) 693 require.False(t, Pipe{}.Skip(ctx)) 694 }) 695 }