github.com/goreleaser/goreleaser@v1.25.1/internal/client/gitea_test.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/http/httptest" 7 "os" 8 "strings" 9 "testing" 10 11 "code.gitea.io/sdk/gitea" 12 "github.com/goreleaser/goreleaser/internal/artifact" 13 "github.com/goreleaser/goreleaser/internal/testctx" 14 "github.com/goreleaser/goreleaser/internal/tmpl" 15 "github.com/goreleaser/goreleaser/pkg/config" 16 "github.com/goreleaser/goreleaser/pkg/context" 17 "github.com/jarcoal/httpmock" 18 "github.com/stretchr/testify/require" 19 "github.com/stretchr/testify/suite" 20 ) 21 22 type GetInstanceURLSuite struct { 23 suite.Suite 24 } 25 26 func (s *GetInstanceURLSuite) TestWithScheme() { 27 t := s.T() 28 rootURL := "https://gitea.com" 29 ctx := testctx.NewWithCfg(config.Project{ 30 GiteaURLs: config.GiteaURLs{ 31 API: rootURL + "/api/v1", 32 }, 33 }) 34 35 result, err := getInstanceURL(ctx) 36 require.NoError(t, err) 37 require.Equal(t, rootURL, result) 38 } 39 40 func (s *GetInstanceURLSuite) TestParseError() { 41 t := s.T() 42 ctx := testctx.NewWithCfg(config.Project{ 43 GiteaURLs: config.GiteaURLs{ 44 API: "://wrong.gitea.com", 45 }, 46 }) 47 48 result, err := getInstanceURL(ctx) 49 require.Error(t, err) 50 require.Empty(t, result) 51 } 52 53 func (s *GetInstanceURLSuite) TestNoScheme() { 54 t := s.T() 55 ctx := testctx.NewWithCfg(config.Project{ 56 GiteaURLs: config.GiteaURLs{ 57 API: "gitea.com", 58 }, 59 }) 60 61 result, err := getInstanceURL(ctx) 62 require.Error(t, err) 63 require.Empty(t, result) 64 } 65 66 func (s *GetInstanceURLSuite) TestEmpty() { 67 t := s.T() 68 ctx := testctx.NewWithCfg(config.Project{ 69 GiteaURLs: config.GiteaURLs{ 70 API: "", 71 }, 72 }) 73 74 result, err := getInstanceURL(ctx) 75 require.Error(t, err) 76 require.Empty(t, result) 77 } 78 79 func (s *GetInstanceURLSuite) TestTemplate() { 80 t := s.T() 81 rootURL := "https://gitea.mycompany.com" 82 ctx := testctx.NewWithCfg(config.Project{ 83 Env: []string{ 84 fmt.Sprintf("GORELEASER_TEST_GITAEA_URLS_API=%s", rootURL), 85 }, 86 GiteaURLs: config.GiteaURLs{ 87 API: "{{ .Env.GORELEASER_TEST_GITAEA_URLS_API }}", 88 }, 89 }) 90 91 result, err := getInstanceURL(ctx) 92 require.NoError(t, err) 93 require.Equal(t, rootURL, result) 94 } 95 96 func (s *GetInstanceURLSuite) TestTemplateMissingValue() { 97 t := s.T() 98 ctx := testctx.NewWithCfg(config.Project{ 99 GiteaURLs: config.GiteaURLs{ 100 API: "{{ .Env.GORELEASER_NOT_EXISTS }}", 101 }, 102 }) 103 104 result, err := getInstanceURL(ctx) 105 require.ErrorAs(t, err, &tmpl.Error{}) 106 require.Empty(t, result) 107 } 108 109 func (s *GetInstanceURLSuite) TestTemplateInvalid() { 110 t := s.T() 111 ctx := testctx.NewWithCfg(config.Project{ 112 GiteaURLs: config.GiteaURLs{ 113 API: "{{.dddddddddd", 114 }, 115 }) 116 117 result, err := getInstanceURL(ctx) 118 require.Error(t, err) 119 require.Empty(t, result) 120 } 121 122 func TestGetInstanceURLSuite(t *testing.T) { 123 suite.Run(t, new(GetInstanceURLSuite)) 124 } 125 126 type GiteaReleasesTestSuite struct { 127 suite.Suite 128 url string 129 owner string 130 repoName string 131 tag string 132 client *giteaClient 133 releasesURL string 134 title string 135 description string 136 ctx *context.Context 137 commit string 138 isDraft bool 139 isPrerelease bool 140 releaseURL string 141 releaseID int64 142 } 143 144 func (s *GiteaReleasesTestSuite) SetupTest() { 145 httpmock.Activate() 146 s.url = "https://gitea.example.com" 147 s.owner = "owner" 148 s.repoName = "repoName" 149 s.releasesURL = fmt.Sprintf( 150 "%v/api/v1/repos/%v/%v/releases", 151 s.url, 152 s.owner, 153 s.repoName, 154 ) 155 s.tag = "tag" 156 s.title = "gitea_release_title" 157 s.description = "gitea release description" 158 s.commit = "some commit hash" 159 s.isDraft = false 160 s.isPrerelease = true 161 s.ctx = testctx.NewWithCfg( 162 config.Project{ 163 ProjectName: "project", 164 Release: config.Release{ 165 NameTemplate: "{{ .ProjectName }}_{{ .Version }}", 166 Gitea: config.Repo{ 167 Owner: s.owner, 168 Name: s.repoName, 169 }, 170 Draft: s.isDraft, 171 }, 172 }, 173 testctx.WithVersion("6.6.6"), 174 testctx.WithGitInfo(context.GitInfo{ 175 CurrentTag: s.tag, 176 Commit: s.commit, 177 ShortCommit: s.commit[0:2], 178 URL: "https://gitea.com/goreleaser/goreleaser.git", 179 }), 180 func(ctx *context.Context) { 181 ctx.PreRelease = s.isPrerelease 182 }, 183 testctx.WithSemver(6, 6, 6, ""), 184 ) 185 s.releaseID = 666 186 s.releaseURL = fmt.Sprintf("%v/%v", s.releasesURL, s.releaseID) 187 httpmock.RegisterResponder("GET", fmt.Sprintf("%s/api/v1/version", s.url), httpmock.NewStringResponder(200, "{\"version\":\"1.12.0\"}")) 188 newClient, err := gitea.NewClient(s.url) 189 s.Require().NoError(err) 190 s.client = &giteaClient{client: newClient} 191 } 192 193 func (s *GiteaReleasesTestSuite) TearDownTest() { 194 httpmock.DeactivateAndReset() 195 } 196 197 type GetExistingReleaseSuite struct { 198 GiteaReleasesTestSuite 199 } 200 201 func (s *GetExistingReleaseSuite) TestNoReleases() { 202 t := s.T() 203 httpmock.RegisterResponder("GET", s.releasesURL, httpmock.NewStringResponder(200, "[]")) 204 205 release, err := s.client.getExistingRelease(s.owner, s.repoName, s.tag) 206 require.Nil(t, release) 207 require.NoError(t, err) 208 } 209 210 func (s *GetExistingReleaseSuite) TestNoRepo() { 211 t := s.T() 212 httpmock.RegisterResponder("GET", s.releasesURL, httpmock.NewStringResponder(404, "")) 213 214 release, err := s.client.getExistingRelease(s.owner, s.repoName, s.tag) 215 require.Nil(t, release) 216 require.Error(t, err) 217 } 218 219 func (s *GetExistingReleaseSuite) TestReleaseExists() { 220 t := s.T() 221 release := gitea.Release{TagName: s.tag} 222 resp, err := httpmock.NewJsonResponder(200, []gitea.Release{release}) 223 require.NoError(t, err) 224 httpmock.RegisterResponder("GET", s.releasesURL, resp) 225 226 result, err := s.client.getExistingRelease(s.owner, s.repoName, s.tag) 227 require.NotNil(t, result) 228 require.Equal(t, *result, release) 229 require.NoError(t, err) 230 } 231 232 func TestGiteaGetExistingReleaseSuite(t *testing.T) { 233 suite.Run(t, new(GetExistingReleaseSuite)) 234 } 235 236 type GiteacreateReleaseSuite struct { 237 GiteaReleasesTestSuite 238 } 239 240 func (s *GiteacreateReleaseSuite) TestSuccess() { 241 t := s.T() 242 expectedRelease := gitea.Release{ 243 TagName: s.tag, 244 Target: s.commit, 245 Note: s.description, 246 IsDraft: s.isDraft, 247 IsPrerelease: s.isPrerelease, 248 } 249 resp, err := httpmock.NewJsonResponder(200, &expectedRelease) 250 require.NoError(t, err) 251 httpmock.RegisterResponder("POST", s.releasesURL, resp) 252 253 release, err := s.client.createRelease(s.ctx, s.title, s.description) 254 require.NoError(t, err) 255 require.NotNil(t, release) 256 require.Equal(t, expectedRelease, *release) 257 } 258 259 func (s *GiteacreateReleaseSuite) TestError() { 260 t := s.T() 261 httpmock.RegisterResponder("POST", s.releasesURL, httpmock.NewStringResponder(400, "")) 262 263 release, err := s.client.createRelease(s.ctx, s.title, s.description) 264 require.Error(t, err) 265 require.Nil(t, release) 266 } 267 268 func TestGiteacreateReleaseSuite(t *testing.T) { 269 suite.Run(t, new(GiteacreateReleaseSuite)) 270 } 271 272 type GiteaupdateReleaseSuite struct { 273 GiteaReleasesTestSuite 274 } 275 276 func (s *GiteaupdateReleaseSuite) SetupTest() { 277 s.GiteaReleasesTestSuite.SetupTest() 278 } 279 280 func (s *GiteaupdateReleaseSuite) TestSuccess() { 281 t := s.T() 282 expectedRelease := gitea.Release{ 283 TagName: s.tag, 284 Target: s.commit, 285 Note: s.description, 286 IsDraft: s.isDraft, 287 IsPrerelease: s.isPrerelease, 288 } 289 resp, err := httpmock.NewJsonResponder(200, &expectedRelease) 290 require.NoError(t, err) 291 httpmock.RegisterResponder("PATCH", s.releaseURL, resp) 292 293 release, err := s.client.updateRelease(s.ctx, s.title, s.description, s.releaseID) 294 require.NoError(t, err) 295 require.NotNil(t, release) 296 } 297 298 func (s *GiteaupdateReleaseSuite) TestError() { 299 t := s.T() 300 httpmock.RegisterResponder("PATCH", s.releaseURL, httpmock.NewStringResponder(400, "")) 301 302 release, err := s.client.updateRelease(s.ctx, s.title, s.description, s.releaseID) 303 require.Error(t, err) 304 require.Nil(t, release) 305 } 306 307 func (s *GiteaupdateReleaseSuite) TestGiteaCreateFile() { 308 t := s.T() 309 fileEndpoint := fmt.Sprintf("%s/api/v1/repos/%s/%s/contents/%s", s.url, s.owner, s.repoName, "file.txt") 310 projectEndpoint := fmt.Sprintf("%s/api/v1/repos/%s/%s", s.url, s.owner, s.repoName) 311 312 httpmock.RegisterResponder("GET", fmt.Sprintf("%s/api/v1/version", s.url), httpmock.NewStringResponder(200, "{\"version\":\"1.12.0\"}")) 313 httpmock.RegisterResponder("GET", fileEndpoint, httpmock.NewStringResponder(404, "")) 314 httpmock.RegisterResponder("GET", projectEndpoint, httpmock.NewStringResponder(200, "")) 315 httpmock.RegisterResponder("POST", fileEndpoint, httpmock.NewStringResponder(201, "{\n \"content\": {\n \"name\": \"test.file\",\n \"path\": \"test.file\",\n \"sha\": \"3b18e512dba79e4c8300dd08aeb37f8e728b8dad\",\n \"type\": \"file\",\n \"size\": 12,\n \"encoding\": \"base64\",\n \"content\": \"aGVsbG8gd29ybGQK\"\n }\n}")) 316 317 author := config.CommitAuthor{Name: s.owner} 318 repo := Repo{Owner: s.owner, Name: s.repoName} 319 content := []byte("hello world") 320 path := "file.txt" 321 message := "add hello world" 322 err := s.client.CreateFile(s.ctx, author, repo, content, path, message) 323 require.NoError(t, err) 324 } 325 326 func TestGiteaupdateReleaseSuite(t *testing.T) { 327 suite.Run(t, new(GiteaupdateReleaseSuite)) 328 } 329 330 type GiteaCreateReleaseSuite struct { 331 GiteaReleasesTestSuite 332 } 333 334 func (s *GiteaCreateReleaseSuite) TestTemplateError() { 335 t := s.T() 336 s.ctx.Config.Release.NameTemplate = "{{ .NoKeyLikeThat }}" 337 338 releaseID, err := s.client.CreateRelease(s.ctx, s.description) 339 require.Empty(t, releaseID) 340 require.Error(t, err) 341 } 342 343 func (s *GiteaCreateReleaseSuite) TestErrorGettingExistingRelease() { 344 t := s.T() 345 httpmock.RegisterResponder("GET", s.releasesURL, httpmock.NewStringResponder(404, "")) 346 347 releaseID, err := s.client.CreateRelease(s.ctx, s.description) 348 require.Empty(t, releaseID) 349 require.Error(t, err) 350 } 351 352 func (s *GiteaCreateReleaseSuite) TestErrorUpdatingRelease() { 353 t := s.T() 354 expectedRelease := gitea.Release{TagName: s.tag} 355 resp, err := httpmock.NewJsonResponder(200, []gitea.Release{expectedRelease}) 356 require.NoError(t, err) 357 httpmock.RegisterResponder("GET", s.releasesURL, resp) 358 httpmock.RegisterResponder("PATCH", s.releaseURL, httpmock.NewStringResponder(400, "")) 359 360 releaseID, err := s.client.CreateRelease(s.ctx, s.description) 361 require.Empty(t, releaseID) 362 require.Error(t, err) 363 } 364 365 func (s *GiteaCreateReleaseSuite) TestSuccessUpdatingRelease() { 366 t := s.T() 367 expectedRelease := gitea.Release{ 368 ID: 666, 369 TagName: s.tag, 370 Target: s.commit, 371 Note: s.description, 372 IsDraft: s.isDraft, 373 IsPrerelease: s.isPrerelease, 374 } 375 resp, err := httpmock.NewJsonResponder(200, []gitea.Release{expectedRelease}) 376 require.NoError(t, err) 377 httpmock.RegisterResponder("GET", s.releasesURL, resp) 378 resp, err = httpmock.NewJsonResponder(200, &expectedRelease) 379 require.NoError(t, err) 380 httpmock.RegisterResponder("PATCH", s.releaseURL, resp) 381 382 newDescription := "NewDescription" 383 releaseID, err := s.client.CreateRelease(s.ctx, newDescription) 384 require.Equal(t, fmt.Sprint(expectedRelease.ID), releaseID) 385 require.NoError(t, err) 386 } 387 388 func (s *GiteaCreateReleaseSuite) TestErrorCreatingRelease() { 389 t := s.T() 390 httpmock.RegisterResponder("GET", s.releasesURL, httpmock.NewStringResponder(200, "[]")) 391 httpmock.RegisterResponder("POST", s.releasesURL, httpmock.NewStringResponder(400, "")) 392 393 releaseID, err := s.client.CreateRelease(s.ctx, s.description) 394 require.Empty(t, releaseID) 395 require.Error(t, err) 396 } 397 398 func (s *GiteaCreateReleaseSuite) TestSuccessCreatingRelease() { 399 t := s.T() 400 httpmock.RegisterResponder("GET", s.releasesURL, httpmock.NewStringResponder(200, "[]")) 401 expectedRelease := gitea.Release{ 402 ID: 666, 403 TagName: s.tag, 404 Target: s.commit, 405 Note: s.description, 406 IsDraft: s.isDraft, 407 IsPrerelease: s.isPrerelease, 408 } 409 resp, err := httpmock.NewJsonResponder(200, &expectedRelease) 410 require.NoError(t, err) 411 httpmock.RegisterResponder("POST", s.releasesURL, resp) 412 413 releaseID, err := s.client.CreateRelease(s.ctx, s.description) 414 require.Equal(t, fmt.Sprint(expectedRelease.ID), releaseID) 415 require.NoError(t, err) 416 } 417 418 func TestGiteaCreateReleaseSuite(t *testing.T) { 419 suite.Run(t, new(GiteaCreateReleaseSuite)) 420 } 421 422 type GiteaUploadSuite struct { 423 GiteaReleasesTestSuite 424 artifact *artifact.Artifact 425 file *os.File 426 releaseAttachmentsURL string 427 } 428 429 func (s *GiteaUploadSuite) SetupTest() { 430 t := s.T() 431 s.GiteaReleasesTestSuite.SetupTest() 432 s.artifact = &artifact.Artifact{Name: "ArtifactName"} 433 file, err := os.CreateTemp(t.TempDir(), "gitea_test_tempfile") 434 require.NoError(t, err) 435 require.NotNil(t, file) 436 t.Cleanup(func() { 437 _ = file.Close() 438 }) 439 s.file = file 440 s.releaseAttachmentsURL = fmt.Sprintf("%v/assets", s.releaseURL) 441 } 442 443 func (s *GiteaUploadSuite) TearDownTest() { 444 s.GiteaReleasesTestSuite.TearDownTest() 445 s.Require().NoError(s.file.Close()) 446 } 447 448 func (s *GiteaUploadSuite) TestErrorParsingReleaseID() { 449 t := s.T() 450 err := s.client.Upload(s.ctx, "notint", s.artifact, s.file) 451 require.EqualError(t, err, "strconv.ParseInt: parsing \"notint\": invalid syntax") 452 } 453 454 func (s *GiteaUploadSuite) TestErrorCreatingReleaseAttachment() { 455 t := s.T() 456 httpmock.RegisterResponder("POST", s.releaseAttachmentsURL, httpmock.NewStringResponder(400, "")) 457 458 err := s.client.Upload(s.ctx, fmt.Sprint(s.releaseID), s.artifact, s.file) 459 require.True(t, strings.HasPrefix(err.Error(), "Unknown API Error: 400")) 460 } 461 462 func (s *GiteaUploadSuite) TestSuccess() { 463 t := s.T() 464 attachment := gitea.Attachment{} 465 resp, err := httpmock.NewJsonResponder(200, &attachment) 466 require.NoError(t, err) 467 httpmock.RegisterResponder("POST", s.releaseAttachmentsURL, resp) 468 469 err = s.client.Upload(s.ctx, fmt.Sprint(s.releaseID), s.artifact, s.file) 470 require.NoError(t, err) 471 } 472 473 func TestGiteaUploadSuite(t *testing.T) { 474 suite.Run(t, new(GiteaUploadSuite)) 475 } 476 477 func TestGiteaReleaseURLTemplate(t *testing.T) { 478 tests := []struct { 479 name string 480 downloadURL string 481 wantDownloadURL string 482 wantErr bool 483 }{ 484 { 485 name: "string_url", 486 downloadURL: "https://gitea.com", 487 wantDownloadURL: "https://gitea.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}", 488 }, 489 { 490 name: "download_url_template", 491 downloadURL: "{{ .Env.GORELEASER_TEST_GITEA_URLS_DOWNLOAD }}", 492 wantDownloadURL: "https://gitea.mycompany.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}", 493 }, 494 { 495 name: "download_url_template_invalid_value", 496 downloadURL: "{{ .Env.GORELEASER_NOT_EXISTS }}", 497 wantErr: true, 498 }, 499 { 500 name: "download_url_template_invalid", 501 downloadURL: "{{.dddddddddd", 502 wantErr: true, 503 }, 504 } 505 506 for _, tt := range tests { 507 t.Run(tt.name, func(t *testing.T) { 508 ctx := testctx.NewWithCfg(config.Project{ 509 Env: []string{ 510 "GORELEASER_TEST_GITEA_URLS_DOWNLOAD=https://gitea.mycompany.com", 511 }, 512 GiteaURLs: config.GiteaURLs{ 513 API: "https://gitea.com/api/v1", 514 Download: tt.downloadURL, 515 }, 516 Release: config.Release{ 517 Gitea: config.Repo{ 518 Owner: "owner", 519 Name: "name", 520 }, 521 }, 522 }) 523 client, err := newGitea(ctx, ctx.Token) 524 require.NoError(t, err) 525 526 urlTpl, err := client.ReleaseURLTemplate(ctx) 527 if tt.wantErr { 528 require.Error(t, err) 529 return 530 } 531 532 require.NoError(t, err) 533 require.Equal(t, tt.wantDownloadURL, urlTpl) 534 }) 535 } 536 } 537 538 func TestGiteaGetDefaultBranch(t *testing.T) { 539 totalRequests := 0 540 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 541 totalRequests++ 542 defer r.Body.Close() 543 544 if strings.HasSuffix(r.URL.Path, "api/v1/version") { 545 w.WriteHeader(http.StatusOK) 546 fmt.Fprint(w, "{\"version\":\"1.12.0\"}") 547 } else { 548 w.WriteHeader(http.StatusOK) 549 fmt.Fprint(w, "{}") 550 } 551 })) 552 defer srv.Close() 553 554 ctx := testctx.NewWithCfg(config.Project{ 555 GiteaURLs: config.GiteaURLs{ 556 API: srv.URL, 557 }, 558 }) 559 client, err := newGitea(ctx, "test-token") 560 require.NoError(t, err) 561 repo := Repo{ 562 Owner: "someone", 563 Name: "something", 564 Branch: "somebranch", 565 } 566 567 _, err = client.getDefaultBranch(ctx, repo) 568 require.NoError(t, err) 569 require.Equal(t, 2, totalRequests) 570 } 571 572 func TestGiteaGetDefaultBranchErr(t *testing.T) { 573 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 574 defer r.Body.Close() 575 if strings.HasSuffix(r.URL.Path, "api/v1/version") { 576 w.WriteHeader(http.StatusOK) 577 fmt.Fprint(w, "{\"version\":\"1.12.0\"}") 578 } else { 579 w.WriteHeader(http.StatusNotFound) 580 fmt.Fprint(w, "{}") 581 } 582 })) 583 defer srv.Close() 584 585 ctx := testctx.NewWithCfg(config.Project{ 586 GiteaURLs: config.GiteaURLs{ 587 API: srv.URL, 588 }, 589 }) 590 client, err := newGitea(ctx, "test-token") 591 require.NoError(t, err) 592 repo := Repo{ 593 Owner: "someone", 594 Name: "something", 595 Branch: "somebranch", 596 } 597 598 _, err = client.getDefaultBranch(ctx, repo) 599 require.Error(t, err) 600 } 601 602 func TestGiteaChangelog(t *testing.T) { 603 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 604 defer r.Body.Close() 605 if strings.HasSuffix(r.URL.Path, "api/v1/version") { 606 w.WriteHeader(http.StatusOK) 607 fmt.Fprint(w, "{\"version\":\"1.12.0\"}") 608 } 609 })) 610 defer srv.Close() 611 612 ctx := testctx.NewWithCfg(config.Project{ 613 GiteaURLs: config.GiteaURLs{ 614 API: srv.URL, 615 }, 616 }) 617 client, err := newGitea(ctx, "test-token") 618 require.NoError(t, err) 619 repo := Repo{ 620 Owner: "someone", 621 Name: "something", 622 Branch: "somebranch", 623 } 624 625 _, err = client.Changelog(ctx, repo, "v1.0.0", "v1.1.0") 626 require.EqualError(t, err, ErrNotImplemented.Error()) 627 } 628 629 func TestGiteatGetInstanceURL(t *testing.T) { 630 ctx := testctx.NewWithCfg(config.Project{ 631 GiteaURLs: config.GiteaURLs{ 632 API: "http://our.internal.gitea.media/api/v1", 633 }, 634 }) 635 url, err := getInstanceURL(ctx) 636 require.NoError(t, err) 637 require.Equal(t, "http://our.internal.gitea.media", url) 638 }