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