github.com/google/go-github/v42@v42.0.0/github/repos.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "encoding/json" 11 "errors" 12 "fmt" 13 "net/http" 14 "strings" 15 ) 16 17 const githubBranchNotProtected string = "Branch not protected" 18 19 var ErrBranchNotProtected = errors.New("branch is not protected") 20 21 // RepositoriesService handles communication with the repository related 22 // methods of the GitHub API. 23 // 24 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/ 25 type RepositoriesService service 26 27 // Repository represents a GitHub repository. 28 type Repository struct { 29 ID *int64 `json:"id,omitempty"` 30 NodeID *string `json:"node_id,omitempty"` 31 Owner *User `json:"owner,omitempty"` 32 Name *string `json:"name,omitempty"` 33 FullName *string `json:"full_name,omitempty"` 34 Description *string `json:"description,omitempty"` 35 Homepage *string `json:"homepage,omitempty"` 36 CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"` 37 DefaultBranch *string `json:"default_branch,omitempty"` 38 MasterBranch *string `json:"master_branch,omitempty"` 39 CreatedAt *Timestamp `json:"created_at,omitempty"` 40 PushedAt *Timestamp `json:"pushed_at,omitempty"` 41 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 42 HTMLURL *string `json:"html_url,omitempty"` 43 CloneURL *string `json:"clone_url,omitempty"` 44 GitURL *string `json:"git_url,omitempty"` 45 MirrorURL *string `json:"mirror_url,omitempty"` 46 SSHURL *string `json:"ssh_url,omitempty"` 47 SVNURL *string `json:"svn_url,omitempty"` 48 Language *string `json:"language,omitempty"` 49 Fork *bool `json:"fork,omitempty"` 50 ForksCount *int `json:"forks_count,omitempty"` 51 NetworkCount *int `json:"network_count,omitempty"` 52 OpenIssuesCount *int `json:"open_issues_count,omitempty"` 53 OpenIssues *int `json:"open_issues,omitempty"` // Deprecated: Replaced by OpenIssuesCount. For backward compatibility OpenIssues is still populated. 54 StargazersCount *int `json:"stargazers_count,omitempty"` 55 SubscribersCount *int `json:"subscribers_count,omitempty"` 56 WatchersCount *int `json:"watchers_count,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility WatchersCount is still populated. 57 Watchers *int `json:"watchers,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility Watchers is still populated. 58 Size *int `json:"size,omitempty"` 59 AutoInit *bool `json:"auto_init,omitempty"` 60 Parent *Repository `json:"parent,omitempty"` 61 Source *Repository `json:"source,omitempty"` 62 TemplateRepository *Repository `json:"template_repository,omitempty"` 63 Organization *Organization `json:"organization,omitempty"` 64 Permissions map[string]bool `json:"permissions,omitempty"` 65 AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` 66 AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` 67 AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` 68 AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"` 69 DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"` 70 Topics []string `json:"topics,omitempty"` 71 Archived *bool `json:"archived,omitempty"` 72 Disabled *bool `json:"disabled,omitempty"` 73 74 // Only provided when using RepositoriesService.Get while in preview 75 License *License `json:"license,omitempty"` 76 77 // Additional mutable fields when creating and editing a repository 78 Private *bool `json:"private,omitempty"` 79 HasIssues *bool `json:"has_issues,omitempty"` 80 HasWiki *bool `json:"has_wiki,omitempty"` 81 HasPages *bool `json:"has_pages,omitempty"` 82 HasProjects *bool `json:"has_projects,omitempty"` 83 HasDownloads *bool `json:"has_downloads,omitempty"` 84 IsTemplate *bool `json:"is_template,omitempty"` 85 LicenseTemplate *string `json:"license_template,omitempty"` 86 GitignoreTemplate *string `json:"gitignore_template,omitempty"` 87 88 // Options for configuring Advanced Security and Secret Scanning 89 SecurityAndAnalysis *SecurityAndAnalysis `json:"security_and_analysis,omitempty"` 90 91 // Creating an organization repository. Required for non-owners. 92 TeamID *int64 `json:"team_id,omitempty"` 93 94 // API URLs 95 URL *string `json:"url,omitempty"` 96 ArchiveURL *string `json:"archive_url,omitempty"` 97 AssigneesURL *string `json:"assignees_url,omitempty"` 98 BlobsURL *string `json:"blobs_url,omitempty"` 99 BranchesURL *string `json:"branches_url,omitempty"` 100 CollaboratorsURL *string `json:"collaborators_url,omitempty"` 101 CommentsURL *string `json:"comments_url,omitempty"` 102 CommitsURL *string `json:"commits_url,omitempty"` 103 CompareURL *string `json:"compare_url,omitempty"` 104 ContentsURL *string `json:"contents_url,omitempty"` 105 ContributorsURL *string `json:"contributors_url,omitempty"` 106 DeploymentsURL *string `json:"deployments_url,omitempty"` 107 DownloadsURL *string `json:"downloads_url,omitempty"` 108 EventsURL *string `json:"events_url,omitempty"` 109 ForksURL *string `json:"forks_url,omitempty"` 110 GitCommitsURL *string `json:"git_commits_url,omitempty"` 111 GitRefsURL *string `json:"git_refs_url,omitempty"` 112 GitTagsURL *string `json:"git_tags_url,omitempty"` 113 HooksURL *string `json:"hooks_url,omitempty"` 114 IssueCommentURL *string `json:"issue_comment_url,omitempty"` 115 IssueEventsURL *string `json:"issue_events_url,omitempty"` 116 IssuesURL *string `json:"issues_url,omitempty"` 117 KeysURL *string `json:"keys_url,omitempty"` 118 LabelsURL *string `json:"labels_url,omitempty"` 119 LanguagesURL *string `json:"languages_url,omitempty"` 120 MergesURL *string `json:"merges_url,omitempty"` 121 MilestonesURL *string `json:"milestones_url,omitempty"` 122 NotificationsURL *string `json:"notifications_url,omitempty"` 123 PullsURL *string `json:"pulls_url,omitempty"` 124 ReleasesURL *string `json:"releases_url,omitempty"` 125 StargazersURL *string `json:"stargazers_url,omitempty"` 126 StatusesURL *string `json:"statuses_url,omitempty"` 127 SubscribersURL *string `json:"subscribers_url,omitempty"` 128 SubscriptionURL *string `json:"subscription_url,omitempty"` 129 TagsURL *string `json:"tags_url,omitempty"` 130 TreesURL *string `json:"trees_url,omitempty"` 131 TeamsURL *string `json:"teams_url,omitempty"` 132 133 // TextMatches is only populated from search results that request text matches 134 // See: search.go and https://docs.github.com/en/free-pro-team@latest/rest/reference/search/#text-match-metadata 135 TextMatches []*TextMatch `json:"text_matches,omitempty"` 136 137 // Visibility is only used for Create and Edit endpoints. The visibility field 138 // overrides the field parameter when both are used. 139 // Can be one of public, private or internal. 140 Visibility *string `json:"visibility,omitempty"` 141 } 142 143 func (r Repository) String() string { 144 return Stringify(r) 145 } 146 147 // BranchListOptions specifies the optional parameters to the 148 // RepositoriesService.ListBranches method. 149 type BranchListOptions struct { 150 // Setting to true returns only protected branches. 151 // When set to false, only unprotected branches are returned. 152 // Omitting this parameter returns all branches. 153 // Default: nil 154 Protected *bool `url:"protected,omitempty"` 155 156 ListOptions 157 } 158 159 // RepositoryListOptions specifies the optional parameters to the 160 // RepositoriesService.List method. 161 type RepositoryListOptions struct { 162 // Visibility of repositories to list. Can be one of all, public, or private. 163 // Default: all 164 Visibility string `url:"visibility,omitempty"` 165 166 // List repos of given affiliation[s]. 167 // Comma-separated list of values. Can include: 168 // * owner: Repositories that are owned by the authenticated user. 169 // * collaborator: Repositories that the user has been added to as a 170 // collaborator. 171 // * organization_member: Repositories that the user has access to through 172 // being a member of an organization. This includes every repository on 173 // every team that the user is on. 174 // Default: owner,collaborator,organization_member 175 Affiliation string `url:"affiliation,omitempty"` 176 177 // Type of repositories to list. 178 // Can be one of all, owner, public, private, member. Default: all 179 // Will cause a 422 error if used in the same request as visibility or 180 // affiliation. 181 Type string `url:"type,omitempty"` 182 183 // How to sort the repository list. Can be one of created, updated, pushed, 184 // full_name. Default: full_name 185 Sort string `url:"sort,omitempty"` 186 187 // Direction in which to sort repositories. Can be one of asc or desc. 188 // Default: when using full_name: asc; otherwise desc 189 Direction string `url:"direction,omitempty"` 190 191 ListOptions 192 } 193 194 // SecurityAndAnalysis specifies the optional advanced security features 195 // that are enabled on a given repository. 196 type SecurityAndAnalysis struct { 197 AdvancedSecurity *AdvancedSecurity `json:"advanced_security,omitempty"` 198 SecretScanning *SecretScanning `json:"secret_scanning,omitempty"` 199 } 200 201 func (s SecurityAndAnalysis) String() string { 202 return Stringify(s) 203 } 204 205 // AdvancedSecurity specifies the state of advanced security on a repository. 206 // 207 // GitHub API docs: https://docs.github.com/en/github/getting-started-with-github/learning-about-github/about-github-advanced-security 208 type AdvancedSecurity struct { 209 Status *string `json:"status,omitempty"` 210 } 211 212 func (a AdvancedSecurity) String() string { 213 return Stringify(a) 214 } 215 216 // SecretScanning specifies the state of secret scanning on a repository. 217 // 218 // GitHub API docs: https://docs.github.com/en/code-security/secret-security/about-secret-scanning 219 type SecretScanning struct { 220 Status *string `json:"status,omitempty"` 221 } 222 223 func (s SecretScanning) String() string { 224 return Stringify(s) 225 } 226 227 // List the repositories for a user. Passing the empty string will list 228 // repositories for the authenticated user. 229 // 230 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-repositories-for-the-authenticated-user 231 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-repositories-for-a-user 232 func (s *RepositoriesService) List(ctx context.Context, user string, opts *RepositoryListOptions) ([]*Repository, *Response, error) { 233 var u string 234 if user != "" { 235 u = fmt.Sprintf("users/%v/repos", user) 236 } else { 237 u = "user/repos" 238 } 239 u, err := addOptions(u, opts) 240 if err != nil { 241 return nil, nil, err 242 } 243 244 req, err := s.client.NewRequest("GET", u, nil) 245 if err != nil { 246 return nil, nil, err 247 } 248 249 // TODO: remove custom Accept headers when APIs fully launch. 250 acceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 251 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 252 253 var repos []*Repository 254 resp, err := s.client.Do(ctx, req, &repos) 255 if err != nil { 256 return nil, resp, err 257 } 258 259 return repos, resp, nil 260 } 261 262 // RepositoryListByOrgOptions specifies the optional parameters to the 263 // RepositoriesService.ListByOrg method. 264 type RepositoryListByOrgOptions struct { 265 // Type of repositories to list. Possible values are: all, public, private, 266 // forks, sources, member. Default is "all". 267 Type string `url:"type,omitempty"` 268 269 // How to sort the repository list. Can be one of created, updated, pushed, 270 // full_name. Default is "created". 271 Sort string `url:"sort,omitempty"` 272 273 // Direction in which to sort repositories. Can be one of asc or desc. 274 // Default when using full_name: asc; otherwise desc. 275 Direction string `url:"direction,omitempty"` 276 277 ListOptions 278 } 279 280 // ListByOrg lists the repositories for an organization. 281 // 282 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-organization-repositories 283 func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opts *RepositoryListByOrgOptions) ([]*Repository, *Response, error) { 284 u := fmt.Sprintf("orgs/%v/repos", org) 285 u, err := addOptions(u, opts) 286 if err != nil { 287 return nil, nil, err 288 } 289 290 req, err := s.client.NewRequest("GET", u, nil) 291 if err != nil { 292 return nil, nil, err 293 } 294 295 // TODO: remove custom Accept headers when APIs fully launch. 296 acceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 297 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 298 299 var repos []*Repository 300 resp, err := s.client.Do(ctx, req, &repos) 301 if err != nil { 302 return nil, resp, err 303 } 304 305 return repos, resp, nil 306 } 307 308 // RepositoryListAllOptions specifies the optional parameters to the 309 // RepositoriesService.ListAll method. 310 type RepositoryListAllOptions struct { 311 // ID of the last repository seen 312 Since int64 `url:"since,omitempty"` 313 } 314 315 // ListAll lists all GitHub repositories in the order that they were created. 316 // 317 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-public-repositories 318 func (s *RepositoriesService) ListAll(ctx context.Context, opts *RepositoryListAllOptions) ([]*Repository, *Response, error) { 319 u, err := addOptions("repositories", opts) 320 if err != nil { 321 return nil, nil, err 322 } 323 324 req, err := s.client.NewRequest("GET", u, nil) 325 if err != nil { 326 return nil, nil, err 327 } 328 329 var repos []*Repository 330 resp, err := s.client.Do(ctx, req, &repos) 331 if err != nil { 332 return nil, resp, err 333 } 334 335 return repos, resp, nil 336 } 337 338 // createRepoRequest is a subset of Repository and is used internally 339 // by Create to pass only the known fields for the endpoint. 340 // 341 // See https://github.com/google/go-github/issues/1014 for more 342 // information. 343 type createRepoRequest struct { 344 // Name is required when creating a repo. 345 Name *string `json:"name,omitempty"` 346 Description *string `json:"description,omitempty"` 347 Homepage *string `json:"homepage,omitempty"` 348 349 Private *bool `json:"private,omitempty"` 350 Visibility *string `json:"visibility,omitempty"` 351 HasIssues *bool `json:"has_issues,omitempty"` 352 HasProjects *bool `json:"has_projects,omitempty"` 353 HasWiki *bool `json:"has_wiki,omitempty"` 354 IsTemplate *bool `json:"is_template,omitempty"` 355 356 // Creating an organization repository. Required for non-owners. 357 TeamID *int64 `json:"team_id,omitempty"` 358 359 AutoInit *bool `json:"auto_init,omitempty"` 360 GitignoreTemplate *string `json:"gitignore_template,omitempty"` 361 LicenseTemplate *string `json:"license_template,omitempty"` 362 AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` 363 AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` 364 AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` 365 AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"` 366 DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"` 367 } 368 369 // Create a new repository. If an organization is specified, the new 370 // repository will be created under that org. If the empty string is 371 // specified, it will be created for the authenticated user. 372 // 373 // Note that only a subset of the repo fields are used and repo must 374 // not be nil. 375 // 376 // Also note that this method will return the response without actually 377 // waiting for GitHub to finish creating the repository and letting the 378 // changes propagate throughout its servers. You may set up a loop with 379 // exponential back-off to verify repository's creation. 380 // 381 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#create-a-repository-for-the-authenticated-user 382 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#create-an-organization-repository 383 func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) { 384 var u string 385 if org != "" { 386 u = fmt.Sprintf("orgs/%v/repos", org) 387 } else { 388 u = "user/repos" 389 } 390 391 repoReq := &createRepoRequest{ 392 Name: repo.Name, 393 Description: repo.Description, 394 Homepage: repo.Homepage, 395 Private: repo.Private, 396 Visibility: repo.Visibility, 397 HasIssues: repo.HasIssues, 398 HasProjects: repo.HasProjects, 399 HasWiki: repo.HasWiki, 400 IsTemplate: repo.IsTemplate, 401 TeamID: repo.TeamID, 402 AutoInit: repo.AutoInit, 403 GitignoreTemplate: repo.GitignoreTemplate, 404 LicenseTemplate: repo.LicenseTemplate, 405 AllowSquashMerge: repo.AllowSquashMerge, 406 AllowMergeCommit: repo.AllowMergeCommit, 407 AllowRebaseMerge: repo.AllowRebaseMerge, 408 AllowAutoMerge: repo.AllowAutoMerge, 409 DeleteBranchOnMerge: repo.DeleteBranchOnMerge, 410 } 411 412 req, err := s.client.NewRequest("POST", u, repoReq) 413 if err != nil { 414 return nil, nil, err 415 } 416 417 acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 418 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 419 r := new(Repository) 420 resp, err := s.client.Do(ctx, req, r) 421 if err != nil { 422 return nil, resp, err 423 } 424 425 return r, resp, nil 426 } 427 428 // TemplateRepoRequest represents a request to create a repository from a template. 429 type TemplateRepoRequest struct { 430 // Name is required when creating a repo. 431 Name *string `json:"name,omitempty"` 432 Owner *string `json:"owner,omitempty"` 433 Description *string `json:"description,omitempty"` 434 435 IncludeAllBranches *bool `json:"include_all_branches,omitempty"` 436 Private *bool `json:"private,omitempty"` 437 } 438 439 // CreateFromTemplate generates a repository from a template. 440 // 441 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#create-a-repository-using-a-template 442 func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) { 443 u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo) 444 445 req, err := s.client.NewRequest("POST", u, templateRepoReq) 446 if err != nil { 447 return nil, nil, err 448 } 449 450 req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) 451 r := new(Repository) 452 resp, err := s.client.Do(ctx, req, r) 453 if err != nil { 454 return nil, resp, err 455 } 456 457 return r, resp, nil 458 } 459 460 // Get fetches a repository. 461 // 462 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-repository 463 func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) { 464 u := fmt.Sprintf("repos/%v/%v", owner, repo) 465 req, err := s.client.NewRequest("GET", u, nil) 466 if err != nil { 467 return nil, nil, err 468 } 469 470 // TODO: remove custom Accept header when the license support fully launches 471 // https://docs.github.com/en/free-pro-team@latest/rest/reference/licenses/#get-a-repositorys-license 472 acceptHeaders := []string{ 473 mediaTypeCodesOfConductPreview, 474 mediaTypeTopicsPreview, 475 mediaTypeRepositoryTemplatePreview, 476 mediaTypeRepositoryVisibilityPreview, 477 } 478 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 479 480 repository := new(Repository) 481 resp, err := s.client.Do(ctx, req, repository) 482 if err != nil { 483 return nil, resp, err 484 } 485 486 return repository, resp, nil 487 } 488 489 // GetCodeOfConduct gets the contents of a repository's code of conduct. 490 // 491 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/codes-of-conduct/#get-the-code-of-conduct-for-a-repository 492 func (s *RepositoriesService) GetCodeOfConduct(ctx context.Context, owner, repo string) (*CodeOfConduct, *Response, error) { 493 u := fmt.Sprintf("repos/%v/%v/community/code_of_conduct", owner, repo) 494 req, err := s.client.NewRequest("GET", u, nil) 495 if err != nil { 496 return nil, nil, err 497 } 498 499 // TODO: remove custom Accept header when this API fully launches. 500 req.Header.Set("Accept", mediaTypeCodesOfConductPreview) 501 502 coc := new(CodeOfConduct) 503 resp, err := s.client.Do(ctx, req, coc) 504 if err != nil { 505 return nil, resp, err 506 } 507 508 return coc, resp, nil 509 } 510 511 // GetByID fetches a repository. 512 // 513 // Note: GetByID uses the undocumented GitHub API endpoint /repositories/:id. 514 func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repository, *Response, error) { 515 u := fmt.Sprintf("repositories/%d", id) 516 req, err := s.client.NewRequest("GET", u, nil) 517 if err != nil { 518 return nil, nil, err 519 } 520 521 repository := new(Repository) 522 resp, err := s.client.Do(ctx, req, repository) 523 if err != nil { 524 return nil, resp, err 525 } 526 527 return repository, resp, nil 528 } 529 530 // Edit updates a repository. 531 // 532 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#update-a-repository 533 func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repository *Repository) (*Repository, *Response, error) { 534 u := fmt.Sprintf("repos/%v/%v", owner, repo) 535 req, err := s.client.NewRequest("PATCH", u, repository) 536 if err != nil { 537 return nil, nil, err 538 } 539 540 acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 541 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 542 r := new(Repository) 543 resp, err := s.client.Do(ctx, req, r) 544 if err != nil { 545 return nil, resp, err 546 } 547 548 return r, resp, nil 549 } 550 551 // Delete a repository. 552 // 553 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#delete-a-repository 554 func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*Response, error) { 555 u := fmt.Sprintf("repos/%v/%v", owner, repo) 556 req, err := s.client.NewRequest("DELETE", u, nil) 557 if err != nil { 558 return nil, err 559 } 560 561 return s.client.Do(ctx, req, nil) 562 } 563 564 // Contributor represents a repository contributor 565 type Contributor struct { 566 Login *string `json:"login,omitempty"` 567 ID *int64 `json:"id,omitempty"` 568 NodeID *string `json:"node_id,omitempty"` 569 AvatarURL *string `json:"avatar_url,omitempty"` 570 GravatarID *string `json:"gravatar_id,omitempty"` 571 URL *string `json:"url,omitempty"` 572 HTMLURL *string `json:"html_url,omitempty"` 573 FollowersURL *string `json:"followers_url,omitempty"` 574 FollowingURL *string `json:"following_url,omitempty"` 575 GistsURL *string `json:"gists_url,omitempty"` 576 StarredURL *string `json:"starred_url,omitempty"` 577 SubscriptionsURL *string `json:"subscriptions_url,omitempty"` 578 OrganizationsURL *string `json:"organizations_url,omitempty"` 579 ReposURL *string `json:"repos_url,omitempty"` 580 EventsURL *string `json:"events_url,omitempty"` 581 ReceivedEventsURL *string `json:"received_events_url,omitempty"` 582 Type *string `json:"type,omitempty"` 583 SiteAdmin *bool `json:"site_admin,omitempty"` 584 Contributions *int `json:"contributions,omitempty"` 585 Name *string `json:"name,omitempty"` 586 Email *string `json:"email,omitempty"` 587 } 588 589 // ListContributorsOptions specifies the optional parameters to the 590 // RepositoriesService.ListContributors method. 591 type ListContributorsOptions struct { 592 // Include anonymous contributors in results or not 593 Anon string `url:"anon,omitempty"` 594 595 ListOptions 596 } 597 598 // GetVulnerabilityAlerts checks if vulnerability alerts are enabled for a repository. 599 // 600 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository 601 func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, repository string) (bool, *Response, error) { 602 u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) 603 604 req, err := s.client.NewRequest("GET", u, nil) 605 if err != nil { 606 return false, nil, err 607 } 608 609 // TODO: remove custom Accept header when this API fully launches 610 req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 611 612 resp, err := s.client.Do(ctx, req, nil) 613 vulnerabilityAlertsEnabled, err := parseBoolResponse(err) 614 615 return vulnerabilityAlertsEnabled, resp, err 616 } 617 618 // EnableVulnerabilityAlerts enables vulnerability alerts and the dependency graph for a repository. 619 // 620 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#enable-vulnerability-alerts 621 func (s *RepositoriesService) EnableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) { 622 u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) 623 624 req, err := s.client.NewRequest("PUT", u, nil) 625 if err != nil { 626 return nil, err 627 } 628 629 // TODO: remove custom Accept header when this API fully launches 630 req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 631 632 return s.client.Do(ctx, req, nil) 633 } 634 635 // DisableVulnerabilityAlerts disables vulnerability alerts and the dependency graph for a repository. 636 // 637 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#disable-vulnerability-alerts 638 func (s *RepositoriesService) DisableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) { 639 u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) 640 641 req, err := s.client.NewRequest("DELETE", u, nil) 642 if err != nil { 643 return nil, err 644 } 645 646 // TODO: remove custom Accept header when this API fully launches 647 req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 648 649 return s.client.Do(ctx, req, nil) 650 } 651 652 // EnableAutomatedSecurityFixes enables the automated security fixes for a repository. 653 // 654 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#enable-automated-security-fixes 655 func (s *RepositoriesService) EnableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { 656 u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) 657 658 req, err := s.client.NewRequest("PUT", u, nil) 659 if err != nil { 660 return nil, err 661 } 662 663 // TODO: remove custom Accept header when this API fully launches 664 req.Header.Set("Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 665 666 return s.client.Do(ctx, req, nil) 667 } 668 669 // DisableAutomatedSecurityFixes disables vulnerability alerts and the dependency graph for a repository. 670 // 671 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#disable-automated-security-fixes 672 func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { 673 u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) 674 675 req, err := s.client.NewRequest("DELETE", u, nil) 676 if err != nil { 677 return nil, err 678 } 679 680 // TODO: remove custom Accept header when this API fully launches 681 req.Header.Set("Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 682 683 return s.client.Do(ctx, req, nil) 684 } 685 686 // ListContributors lists contributors for a repository. 687 // 688 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-repository-contributors 689 func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opts *ListContributorsOptions) ([]*Contributor, *Response, error) { 690 u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository) 691 u, err := addOptions(u, opts) 692 if err != nil { 693 return nil, nil, err 694 } 695 696 req, err := s.client.NewRequest("GET", u, nil) 697 if err != nil { 698 return nil, nil, err 699 } 700 701 var contributor []*Contributor 702 resp, err := s.client.Do(ctx, req, &contributor) 703 if err != nil { 704 return nil, resp, err 705 } 706 707 return contributor, resp, nil 708 } 709 710 // ListLanguages lists languages for the specified repository. The returned map 711 // specifies the languages and the number of bytes of code written in that 712 // language. For example: 713 // 714 // { 715 // "C": 78769, 716 // "Python": 7769 717 // } 718 // 719 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-repository-languages 720 func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, repo string) (map[string]int, *Response, error) { 721 u := fmt.Sprintf("repos/%v/%v/languages", owner, repo) 722 req, err := s.client.NewRequest("GET", u, nil) 723 if err != nil { 724 return nil, nil, err 725 } 726 727 languages := make(map[string]int) 728 resp, err := s.client.Do(ctx, req, &languages) 729 if err != nil { 730 return nil, resp, err 731 } 732 733 return languages, resp, nil 734 } 735 736 // ListTeams lists the teams for the specified repository. 737 // 738 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-repository-teams 739 func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Team, *Response, error) { 740 u := fmt.Sprintf("repos/%v/%v/teams", owner, repo) 741 u, err := addOptions(u, opts) 742 if err != nil { 743 return nil, nil, err 744 } 745 746 req, err := s.client.NewRequest("GET", u, nil) 747 if err != nil { 748 return nil, nil, err 749 } 750 751 var teams []*Team 752 resp, err := s.client.Do(ctx, req, &teams) 753 if err != nil { 754 return nil, resp, err 755 } 756 757 return teams, resp, nil 758 } 759 760 // RepositoryTag represents a repository tag. 761 type RepositoryTag struct { 762 Name *string `json:"name,omitempty"` 763 Commit *Commit `json:"commit,omitempty"` 764 ZipballURL *string `json:"zipball_url,omitempty"` 765 TarballURL *string `json:"tarball_url,omitempty"` 766 } 767 768 // ListTags lists tags for the specified repository. 769 // 770 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-repository-tags 771 func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*RepositoryTag, *Response, error) { 772 u := fmt.Sprintf("repos/%v/%v/tags", owner, repo) 773 u, err := addOptions(u, opts) 774 if err != nil { 775 return nil, nil, err 776 } 777 778 req, err := s.client.NewRequest("GET", u, nil) 779 if err != nil { 780 return nil, nil, err 781 } 782 783 var tags []*RepositoryTag 784 resp, err := s.client.Do(ctx, req, &tags) 785 if err != nil { 786 return nil, resp, err 787 } 788 789 return tags, resp, nil 790 } 791 792 // Branch represents a repository branch 793 type Branch struct { 794 Name *string `json:"name,omitempty"` 795 Commit *RepositoryCommit `json:"commit,omitempty"` 796 Protected *bool `json:"protected,omitempty"` 797 } 798 799 // Protection represents a repository branch's protection. 800 type Protection struct { 801 RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` 802 RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"` 803 EnforceAdmins *AdminEnforcement `json:"enforce_admins"` 804 Restrictions *BranchRestrictions `json:"restrictions"` 805 RequireLinearHistory *RequireLinearHistory `json:"required_linear_history"` 806 AllowForcePushes *AllowForcePushes `json:"allow_force_pushes"` 807 AllowDeletions *AllowDeletions `json:"allow_deletions"` 808 RequiredConversationResolution *RequiredConversationResolution `json:"required_conversation_resolution"` 809 } 810 811 // BranchProtectionRule represents the rule applied to a repositories branch. 812 type BranchProtectionRule struct { 813 ID *int64 `json:"id,omitempty"` 814 RepositoryID *int64 `json:"repository_id,omitempty"` 815 Name *string `json:"name,omitempty"` 816 CreatedAt *Timestamp `json:"created_at,omitempty"` 817 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 818 PullRequestReviewsEnforcementLevel *string `json:"pull_request_reviews_enforcement_level,omitempty"` 819 RequiredApprovingReviewCount *int `json:"required_approving_review_count,omitempty"` 820 DismissStaleReviewsOnPush *bool `json:"dismiss_stale_reviews_on_push,omitempty"` 821 AuthorizedDismissalActorsOnly *bool `json:"authorized_dismissal_actors_only,omitempty"` 822 IgnoreApprovalsFromContributors *bool `json:"ignore_approvals_from_contributors,omitempty"` 823 RequireCodeOwnerReview *bool `json:"require_code_owner_review,omitempty"` 824 RequiredStatusChecks []string `json:"required_status_checks,omitempty"` 825 RequiredStatusChecksEnforcementLevel *string `json:"required_status_checks_enforcement_level,omitempty"` 826 StrictRequiredStatusChecksPolicy *bool `json:"strict_required_status_checks_policy,omitempty"` 827 SignatureRequirementEnforcementLevel *string `json:"signature_requirement_enforcement_level,omitempty"` 828 LinearHistoryRequirementEnforcementLevel *string `json:"linear_history_requirement_enforcement_level,omitempty"` 829 AdminEnforced *bool `json:"admin_enforced,omitempty"` 830 AllowForcePushesEnforcementLevel *string `json:"allow_force_pushes_enforcement_level,omitempty"` 831 AllowDeletionsEnforcementLevel *string `json:"allow_deletions_enforcement_level,omitempty"` 832 MergeQueueEnforcementLevel *string `json:"merge_queue_enforcement_level,omitempty"` 833 RequiredDeploymentsEnforcementLevel *string `json:"required_deployments_enforcement_level,omitempty"` 834 RequiredConversationResolutionLevel *string `json:"required_conversation_resolution_level,omitempty"` 835 AuthorizedActorsOnly *bool `json:"authorized_actors_only,omitempty"` 836 AuthorizedActorNames []string `json:"authorized_actor_names,omitempty"` 837 } 838 839 // ProtectionChanges represents the changes to the rule if the BranchProtection was edited. 840 type ProtectionChanges struct { 841 AuthorizedActorsOnly *AuthorizedActorsOnly `json:"authorized_actors_only,omitempty"` 842 AuthorizedActorNames *AuthorizedActorNames `json:"authorized_actor_names,omitempty"` 843 } 844 845 // AuthorizedActorNames represents who are authorized to edit the branch protection rules. 846 type AuthorizedActorNames struct { 847 From []string `json:"from,omitempty"` 848 } 849 850 // AuthorizedActorsOnly represents if the branche rule can be edited by authorized actors only. 851 type AuthorizedActorsOnly struct { 852 From *bool `json:"from,omitempty"` 853 } 854 855 // ProtectionRequest represents a request to create/edit a branch's protection. 856 type ProtectionRequest struct { 857 RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` 858 RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"` 859 EnforceAdmins bool `json:"enforce_admins"` 860 Restrictions *BranchRestrictionsRequest `json:"restrictions"` 861 // Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch. 862 RequireLinearHistory *bool `json:"required_linear_history,omitempty"` 863 // Permits force pushes to the protected branch by anyone with write access to the repository. 864 AllowForcePushes *bool `json:"allow_force_pushes,omitempty"` 865 // Allows deletion of the protected branch by anyone with write access to the repository. 866 AllowDeletions *bool `json:"allow_deletions,omitempty"` 867 // RequiredConversationResolution, if set to true, requires all comments 868 // on the pull request to be resolved before it can be merged to a protected branch. 869 RequiredConversationResolution *bool `json:"required_conversation_resolution,omitempty"` 870 } 871 872 // RequiredStatusChecks represents the protection status of a individual branch. 873 type RequiredStatusChecks struct { 874 // Require branches to be up to date before merging. (Required.) 875 Strict bool `json:"strict"` 876 // The list of status checks to require in order to merge into this 877 // branch. (Required; use []string{} instead of nil for empty list.) 878 Contexts []string `json:"contexts"` 879 } 880 881 // RequiredStatusChecksRequest represents a request to edit a protected branch's status checks. 882 type RequiredStatusChecksRequest struct { 883 Strict *bool `json:"strict,omitempty"` 884 Contexts []string `json:"contexts,omitempty"` 885 } 886 887 // PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch. 888 type PullRequestReviewsEnforcement struct { 889 // Specifies which users and teams can dismiss pull request reviews. 890 DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions,omitempty"` 891 // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. 892 DismissStaleReviews bool `json:"dismiss_stale_reviews"` 893 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 894 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` 895 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 896 // Valid values are 1-6. 897 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 898 } 899 900 // PullRequestReviewsEnforcementRequest represents request to set the pull request review 901 // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above 902 // because the request structure is different from the response structure. 903 type PullRequestReviewsEnforcementRequest struct { 904 // Specifies which users and teams should be allowed to dismiss pull request reviews. 905 // User and team dismissal restrictions are only available for 906 // organization-owned repositories. Must be nil for personal repositories. 907 DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` 908 // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required) 909 DismissStaleReviews bool `json:"dismiss_stale_reviews"` 910 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 911 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` 912 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 913 // Valid values are 1-6. 914 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 915 } 916 917 // PullRequestReviewsEnforcementUpdate represents request to patch the pull request review 918 // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementRequest above 919 // because the patch request does not require all fields to be initialized. 920 type PullRequestReviewsEnforcementUpdate struct { 921 // Specifies which users and teams can dismiss pull request reviews. Can be omitted. 922 DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` 923 // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted. 924 DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` 925 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 926 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews,omitempty"` 927 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 928 // Valid values are 1 - 6. 929 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 930 } 931 932 // RequireLinearHistory represents the configuration to enforce branches with no merge commit. 933 type RequireLinearHistory struct { 934 Enabled bool `json:"enabled"` 935 } 936 937 // AllowDeletions represents the configuration to accept deletion of protected branches. 938 type AllowDeletions struct { 939 Enabled bool `json:"enabled"` 940 } 941 942 // AllowForcePushes represents the configuration to accept forced pushes on protected branches. 943 type AllowForcePushes struct { 944 Enabled bool `json:"enabled"` 945 } 946 947 // RequiredConversationResolution, if enabled, requires all comments on the pull request to be resolved before it can be merged to a protected branch. 948 type RequiredConversationResolution struct { 949 Enabled bool `json:"enabled"` 950 } 951 952 // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. 953 type AdminEnforcement struct { 954 URL *string `json:"url,omitempty"` 955 Enabled bool `json:"enabled"` 956 } 957 958 // BranchRestrictions represents the restriction that only certain users or 959 // teams may push to a branch. 960 type BranchRestrictions struct { 961 // The list of user logins with push access. 962 Users []*User `json:"users"` 963 // The list of team slugs with push access. 964 Teams []*Team `json:"teams"` 965 // The list of app slugs with push access. 966 Apps []*App `json:"apps"` 967 } 968 969 // BranchRestrictionsRequest represents the request to create/edit the 970 // restriction that only certain users or teams may push to a branch. It is 971 // separate from BranchRestrictions above because the request structure is 972 // different from the response structure. 973 type BranchRestrictionsRequest struct { 974 // The list of user logins with push access. (Required; use []string{} instead of nil for empty list.) 975 Users []string `json:"users"` 976 // The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.) 977 Teams []string `json:"teams"` 978 // The list of app slugs with push access. 979 Apps []string `json:"apps,omitempty"` 980 } 981 982 // DismissalRestrictions specifies which users and teams can dismiss pull request reviews. 983 type DismissalRestrictions struct { 984 // The list of users who can dimiss pull request reviews. 985 Users []*User `json:"users"` 986 // The list of teams which can dismiss pull request reviews. 987 Teams []*Team `json:"teams"` 988 } 989 990 // DismissalRestrictionsRequest represents the request to create/edit the 991 // restriction to allows only specific users or teams to dimiss pull request reviews. It is 992 // separate from DismissalRestrictions above because the request structure is 993 // different from the response structure. 994 // Note: Both Users and Teams must be nil, or both must be non-nil. 995 type DismissalRestrictionsRequest struct { 996 // The list of user logins who can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 997 Users *[]string `json:"users,omitempty"` 998 // The list of team slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 999 Teams *[]string `json:"teams,omitempty"` 1000 } 1001 1002 // SignaturesProtectedBranch represents the protection status of an individual branch. 1003 type SignaturesProtectedBranch struct { 1004 URL *string `json:"url,omitempty"` 1005 // Commits pushed to matching branches must have verified signatures. 1006 Enabled *bool `json:"enabled,omitempty"` 1007 } 1008 1009 // ListBranches lists branches for the specified repository. 1010 // 1011 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-branches 1012 func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) { 1013 u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) 1014 u, err := addOptions(u, opts) 1015 if err != nil { 1016 return nil, nil, err 1017 } 1018 1019 req, err := s.client.NewRequest("GET", u, nil) 1020 if err != nil { 1021 return nil, nil, err 1022 } 1023 1024 var branches []*Branch 1025 resp, err := s.client.Do(ctx, req, &branches) 1026 if err != nil { 1027 return nil, resp, err 1028 } 1029 1030 return branches, resp, nil 1031 } 1032 1033 // GetBranch gets the specified branch for a repository. 1034 // 1035 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-branch 1036 func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string, followRedirects bool) (*Branch, *Response, error) { 1037 u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) 1038 1039 resp, err := s.getBranchFromURL(ctx, u, followRedirects) 1040 if err != nil { 1041 return nil, nil, err 1042 } 1043 defer resp.Body.Close() 1044 1045 if resp.StatusCode != http.StatusOK { 1046 return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) 1047 } 1048 1049 b := new(Branch) 1050 err = json.NewDecoder(resp.Body).Decode(b) 1051 return b, newResponse(resp), err 1052 } 1053 1054 func (s *RepositoriesService) getBranchFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { 1055 req, err := s.client.NewRequest("GET", u, nil) 1056 if err != nil { 1057 return nil, err 1058 } 1059 1060 var resp *http.Response 1061 // Use http.DefaultTransport if no custom Transport is configured 1062 req = withContext(ctx, req) 1063 if s.client.client.Transport == nil { 1064 resp, err = http.DefaultTransport.RoundTrip(req) 1065 } else { 1066 resp, err = s.client.client.Transport.RoundTrip(req) 1067 } 1068 if err != nil { 1069 return nil, err 1070 } 1071 1072 // If redirect response is returned, follow it 1073 if followRedirects && resp.StatusCode == http.StatusMovedPermanently { 1074 resp.Body.Close() 1075 u = resp.Header.Get("Location") 1076 resp, err = s.getBranchFromURL(ctx, u, false) 1077 } 1078 return resp, err 1079 } 1080 1081 // renameBranchRequest represents a request to rename a branch. 1082 type renameBranchRequest struct { 1083 NewName string `json:"new_name"` 1084 } 1085 1086 // RenameBranch renames a branch in a repository. 1087 // 1088 // To rename a non-default branch: Users must have push access. GitHub Apps must have the `contents:write` repository permission. 1089 // To rename the default branch: Users must have admin or owner permissions. GitHub Apps must have the `administration:write` repository permission. 1090 // 1091 // GitHub API docs: https://docs.github.com/en/rest/reference/repos#rename-a-branch 1092 func (s *RepositoriesService) RenameBranch(ctx context.Context, owner, repo, branch, newName string) (*Branch, *Response, error) { 1093 u := fmt.Sprintf("repos/%v/%v/branches/%v/rename", owner, repo, branch) 1094 r := &renameBranchRequest{NewName: newName} 1095 req, err := s.client.NewRequest("POST", u, r) 1096 if err != nil { 1097 return nil, nil, err 1098 } 1099 1100 b := new(Branch) 1101 resp, err := s.client.Do(ctx, req, b) 1102 if err != nil { 1103 return nil, resp, err 1104 } 1105 1106 return b, resp, nil 1107 } 1108 1109 // GetBranchProtection gets the protection of a given branch. 1110 // 1111 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-branch-protection 1112 func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*Protection, *Response, error) { 1113 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1114 req, err := s.client.NewRequest("GET", u, nil) 1115 if err != nil { 1116 return nil, nil, err 1117 } 1118 1119 // TODO: remove custom Accept header when this API fully launches 1120 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1121 1122 p := new(Protection) 1123 resp, err := s.client.Do(ctx, req, p) 1124 if err != nil { 1125 if isBranchNotProtected(err) { 1126 err = ErrBranchNotProtected 1127 } 1128 return nil, resp, err 1129 } 1130 1131 return p, resp, nil 1132 } 1133 1134 // GetRequiredStatusChecks gets the required status checks for a given protected branch. 1135 // 1136 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-status-checks-protection 1137 func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) { 1138 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1139 req, err := s.client.NewRequest("GET", u, nil) 1140 if err != nil { 1141 return nil, nil, err 1142 } 1143 1144 p := new(RequiredStatusChecks) 1145 resp, err := s.client.Do(ctx, req, p) 1146 if err != nil { 1147 if isBranchNotProtected(err) { 1148 err = ErrBranchNotProtected 1149 } 1150 return nil, resp, err 1151 } 1152 1153 return p, resp, nil 1154 } 1155 1156 // ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch. 1157 // 1158 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-all-status-check-contexts 1159 func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) { 1160 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch) 1161 req, err := s.client.NewRequest("GET", u, nil) 1162 if err != nil { 1163 return nil, nil, err 1164 } 1165 1166 resp, err = s.client.Do(ctx, req, &contexts) 1167 if err != nil { 1168 if isBranchNotProtected(err) { 1169 err = ErrBranchNotProtected 1170 } 1171 return nil, resp, err 1172 } 1173 1174 return contexts, resp, nil 1175 } 1176 1177 // UpdateBranchProtection updates the protection of a given branch. 1178 // 1179 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#update-branch-protection 1180 func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, repo, branch string, preq *ProtectionRequest) (*Protection, *Response, error) { 1181 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1182 req, err := s.client.NewRequest("PUT", u, preq) 1183 if err != nil { 1184 return nil, nil, err 1185 } 1186 1187 // TODO: remove custom Accept header when this API fully launches 1188 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1189 1190 p := new(Protection) 1191 resp, err := s.client.Do(ctx, req, p) 1192 if err != nil { 1193 return nil, resp, err 1194 } 1195 1196 return p, resp, nil 1197 } 1198 1199 // RemoveBranchProtection removes the protection of a given branch. 1200 // 1201 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#delete-branch-protection 1202 func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) { 1203 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1204 req, err := s.client.NewRequest("DELETE", u, nil) 1205 if err != nil { 1206 return nil, err 1207 } 1208 1209 return s.client.Do(ctx, req, nil) 1210 } 1211 1212 // GetSignaturesProtectedBranch gets required signatures of protected branch. 1213 // 1214 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-commit-signature-protection 1215 func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { 1216 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1217 req, err := s.client.NewRequest("GET", u, nil) 1218 if err != nil { 1219 return nil, nil, err 1220 } 1221 1222 // TODO: remove custom Accept header when this API fully launches 1223 req.Header.Set("Accept", mediaTypeSignaturePreview) 1224 1225 p := new(SignaturesProtectedBranch) 1226 resp, err := s.client.Do(ctx, req, p) 1227 if err != nil { 1228 return nil, resp, err 1229 } 1230 1231 return p, resp, nil 1232 } 1233 1234 // RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch. 1235 // It requires admin access and branch protection to be enabled. 1236 // 1237 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#create-commit-signature-protection 1238 func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { 1239 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1240 req, err := s.client.NewRequest("POST", u, nil) 1241 if err != nil { 1242 return nil, nil, err 1243 } 1244 1245 // TODO: remove custom Accept header when this API fully launches 1246 req.Header.Set("Accept", mediaTypeSignaturePreview) 1247 1248 r := new(SignaturesProtectedBranch) 1249 resp, err := s.client.Do(ctx, req, r) 1250 if err != nil { 1251 return nil, resp, err 1252 } 1253 1254 return r, resp, err 1255 } 1256 1257 // OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch. 1258 // 1259 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#delete-commit-signature-protection 1260 func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) { 1261 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1262 req, err := s.client.NewRequest("DELETE", u, nil) 1263 if err != nil { 1264 return nil, err 1265 } 1266 1267 // TODO: remove custom Accept header when this API fully launches 1268 req.Header.Set("Accept", mediaTypeSignaturePreview) 1269 1270 return s.client.Do(ctx, req, nil) 1271 } 1272 1273 // UpdateRequiredStatusChecks updates the required status checks for a given protected branch. 1274 // 1275 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#update-status-check-protection 1276 func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, owner, repo, branch string, sreq *RequiredStatusChecksRequest) (*RequiredStatusChecks, *Response, error) { 1277 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1278 req, err := s.client.NewRequest("PATCH", u, sreq) 1279 if err != nil { 1280 return nil, nil, err 1281 } 1282 1283 sc := new(RequiredStatusChecks) 1284 resp, err := s.client.Do(ctx, req, sc) 1285 if err != nil { 1286 return nil, resp, err 1287 } 1288 1289 return sc, resp, nil 1290 } 1291 1292 // RemoveRequiredStatusChecks removes the required status checks for a given protected branch. 1293 // 1294 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#remove-status-check-protection 1295 func (s *RepositoriesService) RemoveRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*Response, error) { 1296 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1297 req, err := s.client.NewRequest("DELETE", u, nil) 1298 if err != nil { 1299 return nil, err 1300 } 1301 1302 return s.client.Do(ctx, req, nil) 1303 } 1304 1305 // License gets the contents of a repository's license if one is detected. 1306 // 1307 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/licenses/#get-the-license-for-a-repository 1308 func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) { 1309 u := fmt.Sprintf("repos/%v/%v/license", owner, repo) 1310 req, err := s.client.NewRequest("GET", u, nil) 1311 if err != nil { 1312 return nil, nil, err 1313 } 1314 1315 r := &RepositoryLicense{} 1316 resp, err := s.client.Do(ctx, req, r) 1317 if err != nil { 1318 return nil, resp, err 1319 } 1320 1321 return r, resp, nil 1322 } 1323 1324 // GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch. 1325 // 1326 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-pull-request-review-protection 1327 func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { 1328 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1329 req, err := s.client.NewRequest("GET", u, nil) 1330 if err != nil { 1331 return nil, nil, err 1332 } 1333 1334 // TODO: remove custom Accept header when this API fully launches 1335 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1336 1337 r := new(PullRequestReviewsEnforcement) 1338 resp, err := s.client.Do(ctx, req, r) 1339 if err != nil { 1340 return nil, resp, err 1341 } 1342 1343 return r, resp, nil 1344 } 1345 1346 // UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch. 1347 // It requires admin access and branch protection to be enabled. 1348 // 1349 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#update-pull-request-review-protection 1350 func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { 1351 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1352 req, err := s.client.NewRequest("PATCH", u, patch) 1353 if err != nil { 1354 return nil, nil, err 1355 } 1356 1357 // TODO: remove custom Accept header when this API fully launches 1358 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1359 1360 r := new(PullRequestReviewsEnforcement) 1361 resp, err := s.client.Do(ctx, req, r) 1362 if err != nil { 1363 return nil, resp, err 1364 } 1365 1366 return r, resp, err 1367 } 1368 1369 // DisableDismissalRestrictions disables dismissal restrictions of a protected branch. 1370 // It requires admin access and branch protection to be enabled. 1371 // 1372 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#update-pull-request-review-protection 1373 func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { 1374 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1375 1376 data := new(struct { 1377 DismissalRestrictionsRequest `json:"dismissal_restrictions"` 1378 }) 1379 1380 req, err := s.client.NewRequest("PATCH", u, data) 1381 if err != nil { 1382 return nil, nil, err 1383 } 1384 1385 // TODO: remove custom Accept header when this API fully launches 1386 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1387 1388 r := new(PullRequestReviewsEnforcement) 1389 resp, err := s.client.Do(ctx, req, r) 1390 if err != nil { 1391 return nil, resp, err 1392 } 1393 1394 return r, resp, err 1395 } 1396 1397 // RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. 1398 // 1399 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#delete-pull-request-review-protection 1400 func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { 1401 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1402 req, err := s.client.NewRequest("DELETE", u, nil) 1403 if err != nil { 1404 return nil, err 1405 } 1406 1407 return s.client.Do(ctx, req, nil) 1408 } 1409 1410 // GetAdminEnforcement gets admin enforcement information of a protected branch. 1411 // 1412 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-admin-branch-protection 1413 func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { 1414 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1415 req, err := s.client.NewRequest("GET", u, nil) 1416 if err != nil { 1417 return nil, nil, err 1418 } 1419 1420 r := new(AdminEnforcement) 1421 resp, err := s.client.Do(ctx, req, r) 1422 if err != nil { 1423 return nil, resp, err 1424 } 1425 1426 return r, resp, nil 1427 } 1428 1429 // AddAdminEnforcement adds admin enforcement to a protected branch. 1430 // It requires admin access and branch protection to be enabled. 1431 // 1432 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#set-admin-branch-protection 1433 func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { 1434 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1435 req, err := s.client.NewRequest("POST", u, nil) 1436 if err != nil { 1437 return nil, nil, err 1438 } 1439 1440 r := new(AdminEnforcement) 1441 resp, err := s.client.Do(ctx, req, r) 1442 if err != nil { 1443 return nil, resp, err 1444 } 1445 1446 return r, resp, err 1447 } 1448 1449 // RemoveAdminEnforcement removes admin enforcement from a protected branch. 1450 // 1451 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#delete-admin-branch-protection 1452 func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { 1453 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1454 req, err := s.client.NewRequest("DELETE", u, nil) 1455 if err != nil { 1456 return nil, err 1457 } 1458 1459 return s.client.Do(ctx, req, nil) 1460 } 1461 1462 // repositoryTopics represents a collection of repository topics. 1463 type repositoryTopics struct { 1464 Names []string `json:"names"` 1465 } 1466 1467 // ListAllTopics lists topics for a repository. 1468 // 1469 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-all-repository-topics 1470 func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) { 1471 u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) 1472 req, err := s.client.NewRequest("GET", u, nil) 1473 if err != nil { 1474 return nil, nil, err 1475 } 1476 1477 // TODO: remove custom Accept header when this API fully launches. 1478 req.Header.Set("Accept", mediaTypeTopicsPreview) 1479 1480 topics := new(repositoryTopics) 1481 resp, err := s.client.Do(ctx, req, topics) 1482 if err != nil { 1483 return nil, resp, err 1484 } 1485 1486 return topics.Names, resp, nil 1487 } 1488 1489 // ReplaceAllTopics replaces topics for a repository. 1490 // 1491 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#replace-all-repository-topics 1492 func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) { 1493 u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) 1494 t := &repositoryTopics{ 1495 Names: topics, 1496 } 1497 if t.Names == nil { 1498 t.Names = []string{} 1499 } 1500 req, err := s.client.NewRequest("PUT", u, t) 1501 if err != nil { 1502 return nil, nil, err 1503 } 1504 1505 // TODO: remove custom Accept header when this API fully launches. 1506 req.Header.Set("Accept", mediaTypeTopicsPreview) 1507 1508 t = new(repositoryTopics) 1509 resp, err := s.client.Do(ctx, req, t) 1510 if err != nil { 1511 return nil, resp, err 1512 } 1513 1514 return t.Names, resp, nil 1515 } 1516 1517 // ListApps lists the GitHub apps that have push access to a given protected branch. 1518 // It requires the GitHub apps to have `write` access to the `content` permission. 1519 // 1520 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-apps-with-access-to-the-protected-branch 1521 func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { 1522 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1523 req, err := s.client.NewRequest("GET", u, nil) 1524 if err != nil { 1525 return nil, nil, err 1526 } 1527 1528 var apps []*App 1529 resp, err := s.client.Do(ctx, req, &apps) 1530 if err != nil { 1531 return nil, resp, err 1532 } 1533 1534 return apps, resp, nil 1535 } 1536 1537 // ReplaceAppRestrictions replaces the apps that have push access to a given protected branch. 1538 // It removes all apps that previously had push access and grants push access to the new list of apps. 1539 // It requires the GitHub apps to have `write` access to the `content` permission. 1540 // 1541 // Note: The list of users, apps, and teams in total is limited to 100 items. 1542 // 1543 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#set-app-access-restrictions 1544 func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { 1545 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1546 req, err := s.client.NewRequest("PUT", u, slug) 1547 if err != nil { 1548 return nil, nil, err 1549 } 1550 1551 var apps []*App 1552 resp, err := s.client.Do(ctx, req, &apps) 1553 if err != nil { 1554 return nil, resp, err 1555 } 1556 1557 return apps, resp, nil 1558 } 1559 1560 // AddAppRestrictions grants the specified apps push access to a given protected branch. 1561 // It requires the GitHub apps to have `write` access to the `content` permission. 1562 // 1563 // Note: The list of users, apps, and teams in total is limited to 100 items. 1564 // 1565 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#add-app-access-restrictions 1566 func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { 1567 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1568 req, err := s.client.NewRequest("POST", u, slug) 1569 if err != nil { 1570 return nil, nil, err 1571 } 1572 1573 var apps []*App 1574 resp, err := s.client.Do(ctx, req, &apps) 1575 if err != nil { 1576 return nil, resp, err 1577 } 1578 1579 return apps, resp, nil 1580 } 1581 1582 // RemoveAppRestrictions removes the ability of an app to push to this branch. 1583 // It requires the GitHub apps to have `write` access to the `content` permission. 1584 // 1585 // Note: The list of users, apps, and teams in total is limited to 100 items. 1586 // 1587 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#remove-app-access-restrictions 1588 func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) { 1589 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1590 req, err := s.client.NewRequest("DELETE", u, slug) 1591 if err != nil { 1592 return nil, nil, err 1593 } 1594 1595 var apps []*App 1596 resp, err := s.client.Do(ctx, req, &apps) 1597 if err != nil { 1598 return nil, resp, err 1599 } 1600 1601 return apps, resp, nil 1602 } 1603 1604 // TransferRequest represents a request to transfer a repository. 1605 type TransferRequest struct { 1606 NewOwner string `json:"new_owner"` 1607 TeamID []int64 `json:"team_ids,omitempty"` 1608 } 1609 1610 // Transfer transfers a repository from one account or organization to another. 1611 // 1612 // This method might return an *AcceptedError and a status code of 1613 // 202. This is because this is the status that GitHub returns to signify that 1614 // it has now scheduled the transfer of the repository in a background task. 1615 // A follow up request, after a delay of a second or so, should result 1616 // in a successful request. 1617 // 1618 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#transfer-a-repository 1619 func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, transfer TransferRequest) (*Repository, *Response, error) { 1620 u := fmt.Sprintf("repos/%v/%v/transfer", owner, repo) 1621 1622 req, err := s.client.NewRequest("POST", u, &transfer) 1623 if err != nil { 1624 return nil, nil, err 1625 } 1626 1627 r := new(Repository) 1628 resp, err := s.client.Do(ctx, req, r) 1629 if err != nil { 1630 return nil, resp, err 1631 } 1632 1633 return r, resp, nil 1634 } 1635 1636 // DispatchRequestOptions represents a request to trigger a repository_dispatch event. 1637 type DispatchRequestOptions struct { 1638 // EventType is a custom webhook event name. (Required.) 1639 EventType string `json:"event_type"` 1640 // ClientPayload is a custom JSON payload with extra information about the webhook event. 1641 // Defaults to an empty JSON object. 1642 ClientPayload *json.RawMessage `json:"client_payload,omitempty"` 1643 } 1644 1645 // Dispatch triggers a repository_dispatch event in a GitHub Actions workflow. 1646 // 1647 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#create-a-repository-dispatch-event 1648 func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) { 1649 u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo) 1650 1651 req, err := s.client.NewRequest("POST", u, &opts) 1652 if err != nil { 1653 return nil, nil, err 1654 } 1655 1656 r := new(Repository) 1657 resp, err := s.client.Do(ctx, req, r) 1658 if err != nil { 1659 return nil, resp, err 1660 } 1661 1662 return r, resp, nil 1663 } 1664 1665 // isBranchNotProtected determines whether a branch is not protected 1666 // based on the error message returned by GitHub API. 1667 func isBranchNotProtected(err error) bool { 1668 errorResponse, ok := err.(*ErrorResponse) 1669 return ok && errorResponse.Message == githubBranchNotProtected 1670 }