github.com/google/go-github/v50@v50.2.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/rest/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 AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"` 67 AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` 68 AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` 69 AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"` 70 AllowForking *bool `json:"allow_forking,omitempty"` 71 WebCommitSignoffRequired *bool `json:"web_commit_signoff_required,omitempty"` 72 DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"` 73 UseSquashPRTitleAsDefault *bool `json:"use_squash_pr_title_as_default,omitempty"` 74 SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "COMMIT_OR_PR_TITLE" 75 SquashMergeCommitMessage *string `json:"squash_merge_commit_message,omitempty"` // Can be one of: "PR_BODY", "COMMIT_MESSAGES", "BLANK" 76 MergeCommitTitle *string `json:"merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "MERGE_MESSAGE" 77 MergeCommitMessage *string `json:"merge_commit_message,omitempty"` // Can be one of: "PR_BODY", "PR_TITLE", "BLANK" 78 Topics []string `json:"topics,omitempty"` 79 Archived *bool `json:"archived,omitempty"` 80 Disabled *bool `json:"disabled,omitempty"` 81 82 // Only provided when using RepositoriesService.Get while in preview 83 License *License `json:"license,omitempty"` 84 85 // Additional mutable fields when creating and editing a repository 86 Private *bool `json:"private,omitempty"` 87 HasIssues *bool `json:"has_issues,omitempty"` 88 HasWiki *bool `json:"has_wiki,omitempty"` 89 HasPages *bool `json:"has_pages,omitempty"` 90 HasProjects *bool `json:"has_projects,omitempty"` 91 HasDownloads *bool `json:"has_downloads,omitempty"` 92 HasDiscussions *bool `json:"has_discussions,omitempty"` 93 IsTemplate *bool `json:"is_template,omitempty"` 94 LicenseTemplate *string `json:"license_template,omitempty"` 95 GitignoreTemplate *string `json:"gitignore_template,omitempty"` 96 97 // Options for configuring Advanced Security and Secret Scanning 98 SecurityAndAnalysis *SecurityAndAnalysis `json:"security_and_analysis,omitempty"` 99 100 // Creating an organization repository. Required for non-owners. 101 TeamID *int64 `json:"team_id,omitempty"` 102 103 // API URLs 104 URL *string `json:"url,omitempty"` 105 ArchiveURL *string `json:"archive_url,omitempty"` 106 AssigneesURL *string `json:"assignees_url,omitempty"` 107 BlobsURL *string `json:"blobs_url,omitempty"` 108 BranchesURL *string `json:"branches_url,omitempty"` 109 CollaboratorsURL *string `json:"collaborators_url,omitempty"` 110 CommentsURL *string `json:"comments_url,omitempty"` 111 CommitsURL *string `json:"commits_url,omitempty"` 112 CompareURL *string `json:"compare_url,omitempty"` 113 ContentsURL *string `json:"contents_url,omitempty"` 114 ContributorsURL *string `json:"contributors_url,omitempty"` 115 DeploymentsURL *string `json:"deployments_url,omitempty"` 116 DownloadsURL *string `json:"downloads_url,omitempty"` 117 EventsURL *string `json:"events_url,omitempty"` 118 ForksURL *string `json:"forks_url,omitempty"` 119 GitCommitsURL *string `json:"git_commits_url,omitempty"` 120 GitRefsURL *string `json:"git_refs_url,omitempty"` 121 GitTagsURL *string `json:"git_tags_url,omitempty"` 122 HooksURL *string `json:"hooks_url,omitempty"` 123 IssueCommentURL *string `json:"issue_comment_url,omitempty"` 124 IssueEventsURL *string `json:"issue_events_url,omitempty"` 125 IssuesURL *string `json:"issues_url,omitempty"` 126 KeysURL *string `json:"keys_url,omitempty"` 127 LabelsURL *string `json:"labels_url,omitempty"` 128 LanguagesURL *string `json:"languages_url,omitempty"` 129 MergesURL *string `json:"merges_url,omitempty"` 130 MilestonesURL *string `json:"milestones_url,omitempty"` 131 NotificationsURL *string `json:"notifications_url,omitempty"` 132 PullsURL *string `json:"pulls_url,omitempty"` 133 ReleasesURL *string `json:"releases_url,omitempty"` 134 StargazersURL *string `json:"stargazers_url,omitempty"` 135 StatusesURL *string `json:"statuses_url,omitempty"` 136 SubscribersURL *string `json:"subscribers_url,omitempty"` 137 SubscriptionURL *string `json:"subscription_url,omitempty"` 138 TagsURL *string `json:"tags_url,omitempty"` 139 TreesURL *string `json:"trees_url,omitempty"` 140 TeamsURL *string `json:"teams_url,omitempty"` 141 142 // TextMatches is only populated from search results that request text matches 143 // See: search.go and https://docs.github.com/en/rest/search/#text-match-metadata 144 TextMatches []*TextMatch `json:"text_matches,omitempty"` 145 146 // Visibility is only used for Create and Edit endpoints. The visibility field 147 // overrides the field parameter when both are used. 148 // Can be one of public, private or internal. 149 Visibility *string `json:"visibility,omitempty"` 150 151 // RoleName is only returned by the API 'check team permissions for a repository'. 152 // See: teams.go (IsTeamRepoByID) https://docs.github.com/en/rest/teams/teams#check-team-permissions-for-a-repository 153 RoleName *string `json:"role_name,omitempty"` 154 } 155 156 func (r Repository) String() string { 157 return Stringify(r) 158 } 159 160 // BranchListOptions specifies the optional parameters to the 161 // RepositoriesService.ListBranches method. 162 type BranchListOptions struct { 163 // Setting to true returns only protected branches. 164 // When set to false, only unprotected branches are returned. 165 // Omitting this parameter returns all branches. 166 // Default: nil 167 Protected *bool `url:"protected,omitempty"` 168 169 ListOptions 170 } 171 172 // RepositoryListOptions specifies the optional parameters to the 173 // RepositoriesService.List method. 174 type RepositoryListOptions struct { 175 // Visibility of repositories to list. Can be one of all, public, or private. 176 // Default: all 177 Visibility string `url:"visibility,omitempty"` 178 179 // List repos of given affiliation[s]. 180 // Comma-separated list of values. Can include: 181 // * owner: Repositories that are owned by the authenticated user. 182 // * collaborator: Repositories that the user has been added to as a 183 // collaborator. 184 // * organization_member: Repositories that the user has access to through 185 // being a member of an organization. This includes every repository on 186 // every team that the user is on. 187 // Default: owner,collaborator,organization_member 188 Affiliation string `url:"affiliation,omitempty"` 189 190 // Type of repositories to list. 191 // Can be one of all, owner, public, private, member. Default: all 192 // Will cause a 422 error if used in the same request as visibility or 193 // affiliation. 194 Type string `url:"type,omitempty"` 195 196 // How to sort the repository list. Can be one of created, updated, pushed, 197 // full_name. Default: full_name 198 Sort string `url:"sort,omitempty"` 199 200 // Direction in which to sort repositories. Can be one of asc or desc. 201 // Default: when using full_name: asc; otherwise desc 202 Direction string `url:"direction,omitempty"` 203 204 ListOptions 205 } 206 207 // SecurityAndAnalysis specifies the optional advanced security features 208 // that are enabled on a given repository. 209 type SecurityAndAnalysis struct { 210 AdvancedSecurity *AdvancedSecurity `json:"advanced_security,omitempty"` 211 SecretScanning *SecretScanning `json:"secret_scanning,omitempty"` 212 SecretScanningPushProtection *SecretScanningPushProtection `json:"secret_scanning_push_protection,omitempty"` 213 } 214 215 func (s SecurityAndAnalysis) String() string { 216 return Stringify(s) 217 } 218 219 // AdvancedSecurity specifies the state of advanced security on a repository. 220 // 221 // GitHub API docs: https://docs.github.com/en/github/getting-started-with-github/learning-about-github/about-github-advanced-security 222 type AdvancedSecurity struct { 223 Status *string `json:"status,omitempty"` 224 } 225 226 func (a AdvancedSecurity) String() string { 227 return Stringify(a) 228 } 229 230 // SecretScanning specifies the state of secret scanning on a repository. 231 // 232 // GitHub API docs: https://docs.github.com/en/code-security/secret-security/about-secret-scanning 233 type SecretScanning struct { 234 Status *string `json:"status,omitempty"` 235 } 236 237 func (s SecretScanning) String() string { 238 return Stringify(s) 239 } 240 241 // SecretScanningPushProtection specifies the state of secret scanning push protection on a repository. 242 // 243 // GitHub API docs: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-for-partner-patterns 244 type SecretScanningPushProtection struct { 245 Status *string `json:"status,omitempty"` 246 } 247 248 // List the repositories for a user. Passing the empty string will list 249 // repositories for the authenticated user. 250 // 251 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-repositories-for-the-authenticated-user 252 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-repositories-for-a-user 253 func (s *RepositoriesService) List(ctx context.Context, user string, opts *RepositoryListOptions) ([]*Repository, *Response, error) { 254 var u string 255 if user != "" { 256 u = fmt.Sprintf("users/%v/repos", user) 257 } else { 258 u = "user/repos" 259 } 260 u, err := addOptions(u, opts) 261 if err != nil { 262 return nil, nil, err 263 } 264 265 req, err := s.client.NewRequest("GET", u, nil) 266 if err != nil { 267 return nil, nil, err 268 } 269 270 // TODO: remove custom Accept headers when APIs fully launch. 271 acceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 272 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 273 274 var repos []*Repository 275 resp, err := s.client.Do(ctx, req, &repos) 276 if err != nil { 277 return nil, resp, err 278 } 279 280 return repos, resp, nil 281 } 282 283 // RepositoryListByOrgOptions specifies the optional parameters to the 284 // RepositoriesService.ListByOrg method. 285 type RepositoryListByOrgOptions struct { 286 // Type of repositories to list. Possible values are: all, public, private, 287 // forks, sources, member. Default is "all". 288 Type string `url:"type,omitempty"` 289 290 // How to sort the repository list. Can be one of created, updated, pushed, 291 // full_name. Default is "created". 292 Sort string `url:"sort,omitempty"` 293 294 // Direction in which to sort repositories. Can be one of asc or desc. 295 // Default when using full_name: asc; otherwise desc. 296 Direction string `url:"direction,omitempty"` 297 298 ListOptions 299 } 300 301 // ListByOrg lists the repositories for an organization. 302 // 303 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-organization-repositories 304 func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opts *RepositoryListByOrgOptions) ([]*Repository, *Response, error) { 305 u := fmt.Sprintf("orgs/%v/repos", org) 306 u, err := addOptions(u, opts) 307 if err != nil { 308 return nil, nil, err 309 } 310 311 req, err := s.client.NewRequest("GET", u, nil) 312 if err != nil { 313 return nil, nil, err 314 } 315 316 // TODO: remove custom Accept headers when APIs fully launch. 317 acceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 318 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 319 320 var repos []*Repository 321 resp, err := s.client.Do(ctx, req, &repos) 322 if err != nil { 323 return nil, resp, err 324 } 325 326 return repos, resp, nil 327 } 328 329 // RepositoryListAllOptions specifies the optional parameters to the 330 // RepositoriesService.ListAll method. 331 type RepositoryListAllOptions struct { 332 // ID of the last repository seen 333 Since int64 `url:"since,omitempty"` 334 } 335 336 // ListAll lists all GitHub repositories in the order that they were created. 337 // 338 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-public-repositories 339 func (s *RepositoriesService) ListAll(ctx context.Context, opts *RepositoryListAllOptions) ([]*Repository, *Response, error) { 340 u, err := addOptions("repositories", opts) 341 if err != nil { 342 return nil, nil, err 343 } 344 345 req, err := s.client.NewRequest("GET", u, nil) 346 if err != nil { 347 return nil, nil, err 348 } 349 350 var repos []*Repository 351 resp, err := s.client.Do(ctx, req, &repos) 352 if err != nil { 353 return nil, resp, err 354 } 355 356 return repos, resp, nil 357 } 358 359 // createRepoRequest is a subset of Repository and is used internally 360 // by Create to pass only the known fields for the endpoint. 361 // 362 // See https://github.com/google/go-github/issues/1014 for more 363 // information. 364 type createRepoRequest struct { 365 // Name is required when creating a repo. 366 Name *string `json:"name,omitempty"` 367 Description *string `json:"description,omitempty"` 368 Homepage *string `json:"homepage,omitempty"` 369 370 Private *bool `json:"private,omitempty"` 371 Visibility *string `json:"visibility,omitempty"` 372 HasIssues *bool `json:"has_issues,omitempty"` 373 HasProjects *bool `json:"has_projects,omitempty"` 374 HasWiki *bool `json:"has_wiki,omitempty"` 375 HasDiscussions *bool `json:"has_discussions,omitempty"` 376 IsTemplate *bool `json:"is_template,omitempty"` 377 378 // Creating an organization repository. Required for non-owners. 379 TeamID *int64 `json:"team_id,omitempty"` 380 381 AutoInit *bool `json:"auto_init,omitempty"` 382 GitignoreTemplate *string `json:"gitignore_template,omitempty"` 383 LicenseTemplate *string `json:"license_template,omitempty"` 384 AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"` 385 AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"` 386 AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"` 387 AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"` 388 AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"` 389 AllowForking *bool `json:"allow_forking,omitempty"` 390 DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"` 391 UseSquashPRTitleAsDefault *bool `json:"use_squash_pr_title_as_default,omitempty"` 392 SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"` 393 SquashMergeCommitMessage *string `json:"squash_merge_commit_message,omitempty"` 394 MergeCommitTitle *string `json:"merge_commit_title,omitempty"` 395 MergeCommitMessage *string `json:"merge_commit_message,omitempty"` 396 } 397 398 // Create a new repository. If an organization is specified, the new 399 // repository will be created under that org. If the empty string is 400 // specified, it will be created for the authenticated user. 401 // 402 // Note that only a subset of the repo fields are used and repo must 403 // not be nil. 404 // 405 // Also note that this method will return the response without actually 406 // waiting for GitHub to finish creating the repository and letting the 407 // changes propagate throughout its servers. You may set up a loop with 408 // exponential back-off to verify repository's creation. 409 // 410 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#create-a-repository-for-the-authenticated-user 411 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#create-an-organization-repository 412 func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) { 413 var u string 414 if org != "" { 415 u = fmt.Sprintf("orgs/%v/repos", org) 416 } else { 417 u = "user/repos" 418 } 419 420 repoReq := &createRepoRequest{ 421 Name: repo.Name, 422 Description: repo.Description, 423 Homepage: repo.Homepage, 424 Private: repo.Private, 425 Visibility: repo.Visibility, 426 HasIssues: repo.HasIssues, 427 HasProjects: repo.HasProjects, 428 HasWiki: repo.HasWiki, 429 HasDiscussions: repo.HasDiscussions, 430 IsTemplate: repo.IsTemplate, 431 TeamID: repo.TeamID, 432 AutoInit: repo.AutoInit, 433 GitignoreTemplate: repo.GitignoreTemplate, 434 LicenseTemplate: repo.LicenseTemplate, 435 AllowSquashMerge: repo.AllowSquashMerge, 436 AllowMergeCommit: repo.AllowMergeCommit, 437 AllowRebaseMerge: repo.AllowRebaseMerge, 438 AllowUpdateBranch: repo.AllowUpdateBranch, 439 AllowAutoMerge: repo.AllowAutoMerge, 440 AllowForking: repo.AllowForking, 441 DeleteBranchOnMerge: repo.DeleteBranchOnMerge, 442 UseSquashPRTitleAsDefault: repo.UseSquashPRTitleAsDefault, 443 SquashMergeCommitTitle: repo.SquashMergeCommitTitle, 444 SquashMergeCommitMessage: repo.SquashMergeCommitMessage, 445 MergeCommitTitle: repo.MergeCommitTitle, 446 MergeCommitMessage: repo.MergeCommitMessage, 447 } 448 449 req, err := s.client.NewRequest("POST", u, repoReq) 450 if err != nil { 451 return nil, nil, err 452 } 453 454 acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 455 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 456 r := new(Repository) 457 resp, err := s.client.Do(ctx, req, r) 458 if err != nil { 459 return nil, resp, err 460 } 461 462 return r, resp, nil 463 } 464 465 // TemplateRepoRequest represents a request to create a repository from a template. 466 type TemplateRepoRequest struct { 467 // Name is required when creating a repo. 468 Name *string `json:"name,omitempty"` 469 Owner *string `json:"owner,omitempty"` 470 Description *string `json:"description,omitempty"` 471 472 IncludeAllBranches *bool `json:"include_all_branches,omitempty"` 473 Private *bool `json:"private,omitempty"` 474 } 475 476 // CreateFromTemplate generates a repository from a template. 477 // 478 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#create-a-repository-using-a-template 479 func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) { 480 u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo) 481 482 req, err := s.client.NewRequest("POST", u, templateRepoReq) 483 if err != nil { 484 return nil, nil, err 485 } 486 487 req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) 488 r := new(Repository) 489 resp, err := s.client.Do(ctx, req, r) 490 if err != nil { 491 return nil, resp, err 492 } 493 494 return r, resp, nil 495 } 496 497 // Get fetches a repository. 498 // 499 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#get-a-repository 500 func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) { 501 u := fmt.Sprintf("repos/%v/%v", owner, repo) 502 req, err := s.client.NewRequest("GET", u, nil) 503 if err != nil { 504 return nil, nil, err 505 } 506 507 // TODO: remove custom Accept header when the license support fully launches 508 // https://docs.github.com/en/rest/licenses/#get-a-repositorys-license 509 acceptHeaders := []string{ 510 mediaTypeCodesOfConductPreview, 511 mediaTypeTopicsPreview, 512 mediaTypeRepositoryTemplatePreview, 513 mediaTypeRepositoryVisibilityPreview, 514 } 515 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 516 517 repository := new(Repository) 518 resp, err := s.client.Do(ctx, req, repository) 519 if err != nil { 520 return nil, resp, err 521 } 522 523 return repository, resp, nil 524 } 525 526 // GetCodeOfConduct gets the contents of a repository's code of conduct. 527 // Note that https://docs.github.com/en/rest/codes-of-conduct#about-the-codes-of-conduct-api 528 // says to use the GET /repos/{owner}/{repo} endpoint. 529 // 530 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#update-a-repository 531 func (s *RepositoriesService) GetCodeOfConduct(ctx context.Context, owner, repo string) (*CodeOfConduct, *Response, error) { 532 u := fmt.Sprintf("repos/%v/%v", owner, repo) 533 req, err := s.client.NewRequest("GET", u, nil) 534 if err != nil { 535 return nil, nil, err 536 } 537 538 // TODO: remove custom Accept header when this API fully launches. 539 req.Header.Set("Accept", mediaTypeCodesOfConductPreview) 540 541 r := new(Repository) 542 resp, err := s.client.Do(ctx, req, r) 543 if err != nil { 544 return nil, resp, err 545 } 546 547 return r.GetCodeOfConduct(), resp, nil 548 } 549 550 // GetByID fetches a repository. 551 // 552 // Note: GetByID uses the undocumented GitHub API endpoint /repositories/:id. 553 func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repository, *Response, error) { 554 u := fmt.Sprintf("repositories/%d", id) 555 req, err := s.client.NewRequest("GET", u, nil) 556 if err != nil { 557 return nil, nil, err 558 } 559 560 repository := new(Repository) 561 resp, err := s.client.Do(ctx, req, repository) 562 if err != nil { 563 return nil, resp, err 564 } 565 566 return repository, resp, nil 567 } 568 569 // Edit updates a repository. 570 // 571 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#update-a-repository 572 func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repository *Repository) (*Repository, *Response, error) { 573 u := fmt.Sprintf("repos/%v/%v", owner, repo) 574 req, err := s.client.NewRequest("PATCH", u, repository) 575 if err != nil { 576 return nil, nil, err 577 } 578 579 acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 580 req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) 581 r := new(Repository) 582 resp, err := s.client.Do(ctx, req, r) 583 if err != nil { 584 return nil, resp, err 585 } 586 587 return r, resp, nil 588 } 589 590 // Delete a repository. 591 // 592 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#delete-a-repository 593 func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*Response, error) { 594 u := fmt.Sprintf("repos/%v/%v", owner, repo) 595 req, err := s.client.NewRequest("DELETE", u, nil) 596 if err != nil { 597 return nil, err 598 } 599 600 return s.client.Do(ctx, req, nil) 601 } 602 603 // Contributor represents a repository contributor 604 type Contributor struct { 605 Login *string `json:"login,omitempty"` 606 ID *int64 `json:"id,omitempty"` 607 NodeID *string `json:"node_id,omitempty"` 608 AvatarURL *string `json:"avatar_url,omitempty"` 609 GravatarID *string `json:"gravatar_id,omitempty"` 610 URL *string `json:"url,omitempty"` 611 HTMLURL *string `json:"html_url,omitempty"` 612 FollowersURL *string `json:"followers_url,omitempty"` 613 FollowingURL *string `json:"following_url,omitempty"` 614 GistsURL *string `json:"gists_url,omitempty"` 615 StarredURL *string `json:"starred_url,omitempty"` 616 SubscriptionsURL *string `json:"subscriptions_url,omitempty"` 617 OrganizationsURL *string `json:"organizations_url,omitempty"` 618 ReposURL *string `json:"repos_url,omitempty"` 619 EventsURL *string `json:"events_url,omitempty"` 620 ReceivedEventsURL *string `json:"received_events_url,omitempty"` 621 Type *string `json:"type,omitempty"` 622 SiteAdmin *bool `json:"site_admin,omitempty"` 623 Contributions *int `json:"contributions,omitempty"` 624 Name *string `json:"name,omitempty"` 625 Email *string `json:"email,omitempty"` 626 } 627 628 // ListContributorsOptions specifies the optional parameters to the 629 // RepositoriesService.ListContributors method. 630 type ListContributorsOptions struct { 631 // Include anonymous contributors in results or not 632 Anon string `url:"anon,omitempty"` 633 634 ListOptions 635 } 636 637 // GetVulnerabilityAlerts checks if vulnerability alerts are enabled for a repository. 638 // 639 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#check-if-vulnerability-alerts-are-enabled-for-a-repository 640 func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, repository string) (bool, *Response, error) { 641 u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) 642 643 req, err := s.client.NewRequest("GET", u, nil) 644 if err != nil { 645 return false, nil, err 646 } 647 648 // TODO: remove custom Accept header when this API fully launches 649 req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 650 651 resp, err := s.client.Do(ctx, req, nil) 652 vulnerabilityAlertsEnabled, err := parseBoolResponse(err) 653 return vulnerabilityAlertsEnabled, resp, err 654 } 655 656 // EnableVulnerabilityAlerts enables vulnerability alerts and the dependency graph for a repository. 657 // 658 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#enable-vulnerability-alerts 659 func (s *RepositoriesService) EnableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) { 660 u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) 661 662 req, err := s.client.NewRequest("PUT", u, nil) 663 if err != nil { 664 return nil, err 665 } 666 667 // TODO: remove custom Accept header when this API fully launches 668 req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 669 670 return s.client.Do(ctx, req, nil) 671 } 672 673 // DisableVulnerabilityAlerts disables vulnerability alerts and the dependency graph for a repository. 674 // 675 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#disable-vulnerability-alerts 676 func (s *RepositoriesService) DisableVulnerabilityAlerts(ctx context.Context, owner, repository string) (*Response, error) { 677 u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository) 678 679 req, err := s.client.NewRequest("DELETE", u, nil) 680 if err != nil { 681 return nil, err 682 } 683 684 // TODO: remove custom Accept header when this API fully launches 685 req.Header.Set("Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 686 687 return s.client.Do(ctx, req, nil) 688 } 689 690 // EnableAutomatedSecurityFixes enables the automated security fixes for a repository. 691 // 692 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#enable-automated-security-fixes 693 func (s *RepositoriesService) EnableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { 694 u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) 695 696 req, err := s.client.NewRequest("PUT", u, nil) 697 if err != nil { 698 return nil, err 699 } 700 701 // TODO: remove custom Accept header when this API fully launches 702 req.Header.Set("Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 703 704 return s.client.Do(ctx, req, nil) 705 } 706 707 // DisableAutomatedSecurityFixes disables vulnerability alerts and the dependency graph for a repository. 708 // 709 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#disable-automated-security-fixes 710 func (s *RepositoriesService) DisableAutomatedSecurityFixes(ctx context.Context, owner, repository string) (*Response, error) { 711 u := fmt.Sprintf("repos/%v/%v/automated-security-fixes", owner, repository) 712 713 req, err := s.client.NewRequest("DELETE", u, nil) 714 if err != nil { 715 return nil, err 716 } 717 718 // TODO: remove custom Accept header when this API fully launches 719 req.Header.Set("Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 720 721 return s.client.Do(ctx, req, nil) 722 } 723 724 // ListContributors lists contributors for a repository. 725 // 726 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-repository-contributors 727 func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opts *ListContributorsOptions) ([]*Contributor, *Response, error) { 728 u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository) 729 u, err := addOptions(u, opts) 730 if err != nil { 731 return nil, nil, err 732 } 733 734 req, err := s.client.NewRequest("GET", u, nil) 735 if err != nil { 736 return nil, nil, err 737 } 738 739 var contributor []*Contributor 740 resp, err := s.client.Do(ctx, req, &contributor) 741 if err != nil { 742 return nil, resp, err 743 } 744 745 return contributor, resp, nil 746 } 747 748 // ListLanguages lists languages for the specified repository. The returned map 749 // specifies the languages and the number of bytes of code written in that 750 // language. For example: 751 // 752 // { 753 // "C": 78769, 754 // "Python": 7769 755 // } 756 // 757 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-repository-languages 758 func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, repo string) (map[string]int, *Response, error) { 759 u := fmt.Sprintf("repos/%v/%v/languages", owner, repo) 760 req, err := s.client.NewRequest("GET", u, nil) 761 if err != nil { 762 return nil, nil, err 763 } 764 765 languages := make(map[string]int) 766 resp, err := s.client.Do(ctx, req, &languages) 767 if err != nil { 768 return nil, resp, err 769 } 770 771 return languages, resp, nil 772 } 773 774 // ListTeams lists the teams for the specified repository. 775 // 776 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-repository-teams 777 func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*Team, *Response, error) { 778 u := fmt.Sprintf("repos/%v/%v/teams", owner, repo) 779 u, err := addOptions(u, opts) 780 if err != nil { 781 return nil, nil, err 782 } 783 784 req, err := s.client.NewRequest("GET", u, nil) 785 if err != nil { 786 return nil, nil, err 787 } 788 789 var teams []*Team 790 resp, err := s.client.Do(ctx, req, &teams) 791 if err != nil { 792 return nil, resp, err 793 } 794 795 return teams, resp, nil 796 } 797 798 // RepositoryTag represents a repository tag. 799 type RepositoryTag struct { 800 Name *string `json:"name,omitempty"` 801 Commit *Commit `json:"commit,omitempty"` 802 ZipballURL *string `json:"zipball_url,omitempty"` 803 TarballURL *string `json:"tarball_url,omitempty"` 804 } 805 806 // ListTags lists tags for the specified repository. 807 // 808 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#list-repository-tags 809 func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opts *ListOptions) ([]*RepositoryTag, *Response, error) { 810 u := fmt.Sprintf("repos/%v/%v/tags", owner, repo) 811 u, err := addOptions(u, opts) 812 if err != nil { 813 return nil, nil, err 814 } 815 816 req, err := s.client.NewRequest("GET", u, nil) 817 if err != nil { 818 return nil, nil, err 819 } 820 821 var tags []*RepositoryTag 822 resp, err := s.client.Do(ctx, req, &tags) 823 if err != nil { 824 return nil, resp, err 825 } 826 827 return tags, resp, nil 828 } 829 830 // Branch represents a repository branch 831 type Branch struct { 832 Name *string `json:"name,omitempty"` 833 Commit *RepositoryCommit `json:"commit,omitempty"` 834 Protected *bool `json:"protected,omitempty"` 835 } 836 837 // Protection represents a repository branch's protection. 838 type Protection struct { 839 RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` 840 RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"` 841 EnforceAdmins *AdminEnforcement `json:"enforce_admins"` 842 Restrictions *BranchRestrictions `json:"restrictions"` 843 RequireLinearHistory *RequireLinearHistory `json:"required_linear_history"` 844 AllowForcePushes *AllowForcePushes `json:"allow_force_pushes"` 845 AllowDeletions *AllowDeletions `json:"allow_deletions"` 846 RequiredConversationResolution *RequiredConversationResolution `json:"required_conversation_resolution"` 847 BlockCreations *BlockCreations `json:"block_creations,omitempty"` 848 LockBranch *LockBranch `json:"lock_branch,omitempty"` 849 AllowForkSyncing *AllowForkSyncing `json:"allow_fork_syncing,omitempty"` 850 } 851 852 // BlockCreations represents whether users can push changes that create branches. If this is true, this 853 // setting blocks pushes that create new branches, unless the push is initiated by a user, team, or app 854 // which has the ability to push. 855 type BlockCreations struct { 856 Enabled *bool `json:"enabled,omitempty"` 857 } 858 859 // LockBranch represents if the branch is marked as read-only. If this is true, users will not be able to push to the branch. 860 type LockBranch struct { 861 Enabled *bool `json:"enabled,omitempty"` 862 } 863 864 // AllowForkSyncing represents whether users can pull changes from upstream when the branch is locked. 865 type AllowForkSyncing struct { 866 Enabled *bool `json:"enabled,omitempty"` 867 } 868 869 // BranchProtectionRule represents the rule applied to a repositories branch. 870 type BranchProtectionRule struct { 871 ID *int64 `json:"id,omitempty"` 872 RepositoryID *int64 `json:"repository_id,omitempty"` 873 Name *string `json:"name,omitempty"` 874 CreatedAt *Timestamp `json:"created_at,omitempty"` 875 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 876 PullRequestReviewsEnforcementLevel *string `json:"pull_request_reviews_enforcement_level,omitempty"` 877 RequiredApprovingReviewCount *int `json:"required_approving_review_count,omitempty"` 878 DismissStaleReviewsOnPush *bool `json:"dismiss_stale_reviews_on_push,omitempty"` 879 AuthorizedDismissalActorsOnly *bool `json:"authorized_dismissal_actors_only,omitempty"` 880 IgnoreApprovalsFromContributors *bool `json:"ignore_approvals_from_contributors,omitempty"` 881 RequireCodeOwnerReview *bool `json:"require_code_owner_review,omitempty"` 882 RequiredStatusChecks []string `json:"required_status_checks,omitempty"` 883 RequiredStatusChecksEnforcementLevel *string `json:"required_status_checks_enforcement_level,omitempty"` 884 StrictRequiredStatusChecksPolicy *bool `json:"strict_required_status_checks_policy,omitempty"` 885 SignatureRequirementEnforcementLevel *string `json:"signature_requirement_enforcement_level,omitempty"` 886 LinearHistoryRequirementEnforcementLevel *string `json:"linear_history_requirement_enforcement_level,omitempty"` 887 AdminEnforced *bool `json:"admin_enforced,omitempty"` 888 AllowForcePushesEnforcementLevel *string `json:"allow_force_pushes_enforcement_level,omitempty"` 889 AllowDeletionsEnforcementLevel *string `json:"allow_deletions_enforcement_level,omitempty"` 890 MergeQueueEnforcementLevel *string `json:"merge_queue_enforcement_level,omitempty"` 891 RequiredDeploymentsEnforcementLevel *string `json:"required_deployments_enforcement_level,omitempty"` 892 RequiredConversationResolutionLevel *string `json:"required_conversation_resolution_level,omitempty"` 893 AuthorizedActorsOnly *bool `json:"authorized_actors_only,omitempty"` 894 AuthorizedActorNames []string `json:"authorized_actor_names,omitempty"` 895 } 896 897 // ProtectionChanges represents the changes to the rule if the BranchProtection was edited. 898 type ProtectionChanges struct { 899 AdminEnforced *AdminEnforcedChanges `json:"admin_enforced,omitempty"` 900 AllowDeletionsEnforcementLevel *AllowDeletionsEnforcementLevelChanges `json:"allow_deletions_enforcement_level,omitempty"` 901 AuthorizedActorNames *AuthorizedActorNames `json:"authorized_actor_names,omitempty"` 902 AuthorizedActorsOnly *AuthorizedActorsOnly `json:"authorized_actors_only,omitempty"` 903 AuthorizedDismissalActorsOnly *AuthorizedDismissalActorsOnlyChanges `json:"authorized_dismissal_actors_only,omitempty"` 904 CreateProtected *CreateProtectedChanges `json:"create_protected,omitempty"` 905 DismissStaleReviewsOnPush *DismissStaleReviewsOnPushChanges `json:"dismiss_stale_reviews_on_push,omitempty"` 906 LinearHistoryRequirementEnforcementLevel *LinearHistoryRequirementEnforcementLevelChanges `json:"linear_history_requirement_enforcement_level,omitempty"` 907 PullRequestReviewsEnforcementLevel *PullRequestReviewsEnforcementLevelChanges `json:"pull_request_reviews_enforcement_level,omitempty"` 908 RequireCodeOwnerReview *RequireCodeOwnerReviewChanges `json:"require_code_owner_review,omitempty"` 909 RequiredConversationResolutionLevel *RequiredConversationResolutionLevelChanges `json:"required_conversation_resolution_level,omitempty"` 910 RequiredDeploymentsEnforcementLevel *RequiredDeploymentsEnforcementLevelChanges `json:"required_deployments_enforcement_level,omitempty"` 911 RequiredStatusChecks *RequiredStatusChecksChanges `json:"required_status_checks,omitempty"` 912 RequiredStatusChecksEnforcementLevel *RequiredStatusChecksEnforcementLevelChanges `json:"required_status_checks_enforcement_level,omitempty"` 913 SignatureRequirementEnforcementLevel *SignatureRequirementEnforcementLevelChanges `json:"signature_requirement_enforcement_level,omitempty"` 914 } 915 916 // AdminEnforcedChanges represents the changes made to the AdminEnforced policy. 917 type AdminEnforcedChanges struct { 918 From *bool `json:"from,omitempty"` 919 } 920 921 // AllowDeletionsEnforcementLevelChanges represents the changes made to the AllowDeletionsEnforcementLevel policy. 922 type AllowDeletionsEnforcementLevelChanges struct { 923 From *string `json:"from,omitempty"` 924 } 925 926 // AuthorizedActorNames represents who are authorized to edit the branch protection rules. 927 type AuthorizedActorNames struct { 928 From []string `json:"from,omitempty"` 929 } 930 931 // AuthorizedActorsOnly represents if the branch rule can be edited by authorized actors only. 932 type AuthorizedActorsOnly struct { 933 From *bool `json:"from,omitempty"` 934 } 935 936 // AuthorizedDismissalActorsOnlyChanges represents the changes made to the AuthorizedDismissalActorsOnly policy. 937 type AuthorizedDismissalActorsOnlyChanges struct { 938 From *bool `json:"from,omitempty"` 939 } 940 941 // CreateProtectedChanges represents the changes made to the CreateProtected policy. 942 type CreateProtectedChanges struct { 943 From *bool `json:"from,omitempty"` 944 } 945 946 // DismissStaleReviewsOnPushChanges represents the changes made to the DismissStaleReviewsOnPushChanges policy. 947 type DismissStaleReviewsOnPushChanges struct { 948 From *bool `json:"from,omitempty"` 949 } 950 951 // LinearHistoryRequirementEnforcementLevelChanges represents the changes made to the LinearHistoryRequirementEnforcementLevel policy. 952 type LinearHistoryRequirementEnforcementLevelChanges struct { 953 From *string `json:"from,omitempty"` 954 } 955 956 // PullRequestReviewsEnforcementLevelChanges represents the changes made to the PullRequestReviewsEnforcementLevel policy. 957 type PullRequestReviewsEnforcementLevelChanges struct { 958 From *string `json:"from,omitempty"` 959 } 960 961 // RequireCodeOwnerReviewChanges represents the changes made to the RequireCodeOwnerReview policy. 962 type RequireCodeOwnerReviewChanges struct { 963 From *bool `json:"from,omitempty"` 964 } 965 966 // RequiredConversationResolutionLevelChanges represents the changes made to the RequiredConversationResolutionLevel policy. 967 type RequiredConversationResolutionLevelChanges struct { 968 From *string `json:"from,omitempty"` 969 } 970 971 // RequiredDeploymentsEnforcementLevelChanges represents the changes made to the RequiredDeploymentsEnforcementLevel policy. 972 type RequiredDeploymentsEnforcementLevelChanges struct { 973 From *string `json:"from,omitempty"` 974 } 975 976 // RequiredStatusChecksChanges represents the changes made to the RequiredStatusChecks policy. 977 type RequiredStatusChecksChanges struct { 978 From []string `json:"from,omitempty"` 979 } 980 981 // RequiredStatusChecksEnforcementLevelChanges represents the changes made to the RequiredStatusChecksEnforcementLevel policy. 982 type RequiredStatusChecksEnforcementLevelChanges struct { 983 From *string `json:"from,omitempty"` 984 } 985 986 // SignatureRequirementEnforcementLevelChanges represents the changes made to the SignatureRequirementEnforcementLevel policy. 987 type SignatureRequirementEnforcementLevelChanges struct { 988 From *string `json:"from,omitempty"` 989 } 990 991 // ProtectionRequest represents a request to create/edit a branch's protection. 992 type ProtectionRequest struct { 993 RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` 994 RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"` 995 EnforceAdmins bool `json:"enforce_admins"` 996 Restrictions *BranchRestrictionsRequest `json:"restrictions"` 997 // Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch. 998 RequireLinearHistory *bool `json:"required_linear_history,omitempty"` 999 // Permits force pushes to the protected branch by anyone with write access to the repository. 1000 AllowForcePushes *bool `json:"allow_force_pushes,omitempty"` 1001 // Allows deletion of the protected branch by anyone with write access to the repository. 1002 AllowDeletions *bool `json:"allow_deletions,omitempty"` 1003 // RequiredConversationResolution, if set to true, requires all comments 1004 // on the pull request to be resolved before it can be merged to a protected branch. 1005 RequiredConversationResolution *bool `json:"required_conversation_resolution,omitempty"` 1006 // BlockCreations, if set to true, will cause the restrictions setting to also block pushes 1007 // which create new branches, unless initiated by a user, team, app with the ability to push. 1008 BlockCreations *bool `json:"block_creations,omitempty"` 1009 // LockBranch, if set to true, will prevent users from pushing to the branch. 1010 LockBranch *bool `json:"lock_branch,omitempty"` 1011 // AllowForkSyncing, if set to true, will allow users to pull changes from upstream 1012 // when the branch is locked. 1013 AllowForkSyncing *bool `json:"allow_fork_syncing,omitempty"` 1014 } 1015 1016 // RequiredStatusChecks represents the protection status of a individual branch. 1017 type RequiredStatusChecks struct { 1018 // Require branches to be up to date before merging. (Required.) 1019 Strict bool `json:"strict"` 1020 // The list of status checks to require in order to merge into this 1021 // branch. (Deprecated. Note: only one of Contexts/Checks can be populated, 1022 // but at least one must be populated). 1023 Contexts []string `json:"contexts,omitempty"` 1024 // The list of status checks to require in order to merge into this 1025 // branch. 1026 Checks []*RequiredStatusCheck `json:"checks"` 1027 } 1028 1029 // RequiredStatusChecksRequest represents a request to edit a protected branch's status checks. 1030 type RequiredStatusChecksRequest struct { 1031 Strict *bool `json:"strict,omitempty"` 1032 // Note: if both Contexts and Checks are populated, 1033 // the GitHub API will only use Checks. 1034 Contexts []string `json:"contexts,omitempty"` 1035 Checks []*RequiredStatusCheck `json:"checks,omitempty"` 1036 } 1037 1038 // RequiredStatusCheck represents a status check of a protected branch. 1039 type RequiredStatusCheck struct { 1040 // The name of the required check. 1041 Context string `json:"context"` 1042 // The ID of the GitHub App that must provide this check. 1043 // Omit this field to automatically select the GitHub App 1044 // that has recently provided this check, 1045 // or any app if it was not set by a GitHub App. 1046 // Pass -1 to explicitly allow any app to set the status. 1047 AppID *int64 `json:"app_id,omitempty"` 1048 } 1049 1050 // PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch. 1051 type PullRequestReviewsEnforcement struct { 1052 // Allow specific users, teams, or apps to bypass pull request requirements. 1053 BypassPullRequestAllowances *BypassPullRequestAllowances `json:"bypass_pull_request_allowances,omitempty"` 1054 // Specifies which users, teams and apps can dismiss pull request reviews. 1055 DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions,omitempty"` 1056 // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. 1057 DismissStaleReviews bool `json:"dismiss_stale_reviews"` 1058 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 1059 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` 1060 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 1061 // Valid values are 1-6. 1062 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 1063 // RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it. 1064 RequireLastPushApproval bool `json:"require_last_push_approval"` 1065 } 1066 1067 // PullRequestReviewsEnforcementRequest represents request to set the pull request review 1068 // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above 1069 // because the request structure is different from the response structure. 1070 type PullRequestReviewsEnforcementRequest struct { 1071 // Allow specific users, teams, or apps to bypass pull request requirements. 1072 BypassPullRequestAllowancesRequest *BypassPullRequestAllowancesRequest `json:"bypass_pull_request_allowances,omitempty"` 1073 // Specifies which users, teams and apps should be allowed to dismiss pull request reviews. 1074 // User, team and app dismissal restrictions are only available for 1075 // organization-owned repositories. Must be nil for personal repositories. 1076 DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` 1077 // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required) 1078 DismissStaleReviews bool `json:"dismiss_stale_reviews"` 1079 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 1080 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` 1081 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 1082 // Valid values are 1-6. 1083 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 1084 // RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it. 1085 RequireLastPushApproval *bool `json:"require_last_push_approval,omitempty"` 1086 } 1087 1088 // PullRequestReviewsEnforcementUpdate represents request to patch the pull request review 1089 // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementRequest above 1090 // because the patch request does not require all fields to be initialized. 1091 type PullRequestReviewsEnforcementUpdate struct { 1092 // Allow specific users, teams, or apps to bypass pull request requirements. 1093 BypassPullRequestAllowancesRequest *BypassPullRequestAllowancesRequest `json:"bypass_pull_request_allowances,omitempty"` 1094 // Specifies which users, teams and apps can dismiss pull request reviews. Can be omitted. 1095 DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` 1096 // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted. 1097 DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` 1098 // RequireCodeOwnerReviews specifies if merging pull requests is blocked until code owners have reviewed. 1099 RequireCodeOwnerReviews *bool `json:"require_code_owner_reviews,omitempty"` 1100 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 1101 // Valid values are 1 - 6 or 0 to not require reviewers. 1102 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 1103 // RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it. 1104 RequireLastPushApproval *bool `json:"require_last_push_approval,omitempty"` 1105 } 1106 1107 // RequireLinearHistory represents the configuration to enforce branches with no merge commit. 1108 type RequireLinearHistory struct { 1109 Enabled bool `json:"enabled"` 1110 } 1111 1112 // AllowDeletions represents the configuration to accept deletion of protected branches. 1113 type AllowDeletions struct { 1114 Enabled bool `json:"enabled"` 1115 } 1116 1117 // AllowForcePushes represents the configuration to accept forced pushes on protected branches. 1118 type AllowForcePushes struct { 1119 Enabled bool `json:"enabled"` 1120 } 1121 1122 // RequiredConversationResolution, if enabled, requires all comments on the pull request to be resolved before it can be merged to a protected branch. 1123 type RequiredConversationResolution struct { 1124 Enabled bool `json:"enabled"` 1125 } 1126 1127 // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. 1128 type AdminEnforcement struct { 1129 URL *string `json:"url,omitempty"` 1130 Enabled bool `json:"enabled"` 1131 } 1132 1133 // BranchRestrictions represents the restriction that only certain users or 1134 // teams may push to a branch. 1135 type BranchRestrictions struct { 1136 // The list of user logins with push access. 1137 Users []*User `json:"users"` 1138 // The list of team slugs with push access. 1139 Teams []*Team `json:"teams"` 1140 // The list of app slugs with push access. 1141 Apps []*App `json:"apps"` 1142 } 1143 1144 // BranchRestrictionsRequest represents the request to create/edit the 1145 // restriction that only certain users or teams may push to a branch. It is 1146 // separate from BranchRestrictions above because the request structure is 1147 // different from the response structure. 1148 type BranchRestrictionsRequest struct { 1149 // The list of user logins with push access. (Required; use []string{} instead of nil for empty list.) 1150 Users []string `json:"users"` 1151 // The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.) 1152 Teams []string `json:"teams"` 1153 // The list of app slugs with push access. 1154 Apps []string `json:"apps"` 1155 } 1156 1157 // BypassPullRequestAllowances represents the people, teams, or apps who are allowed to bypass required pull requests. 1158 type BypassPullRequestAllowances struct { 1159 // The list of users allowed to bypass pull request requirements. 1160 Users []*User `json:"users"` 1161 // The list of teams allowed to bypass pull request requirements. 1162 Teams []*Team `json:"teams"` 1163 // The list of apps allowed to bypass pull request requirements. 1164 Apps []*App `json:"apps"` 1165 } 1166 1167 // BypassPullRequestAllowancesRequest represents the people, teams, or apps who are 1168 // allowed to bypass required pull requests. 1169 // It is separate from BypassPullRequestAllowances above because the request structure is 1170 // different from the response structure. 1171 type BypassPullRequestAllowancesRequest struct { 1172 // The list of user logins allowed to bypass pull request requirements. 1173 Users []string `json:"users"` 1174 // The list of team slugs allowed to bypass pull request requirements. 1175 Teams []string `json:"teams"` 1176 // The list of app slugs allowed to bypass pull request requirements. 1177 Apps []string `json:"apps"` 1178 } 1179 1180 // DismissalRestrictions specifies which users and teams can dismiss pull request reviews. 1181 type DismissalRestrictions struct { 1182 // The list of users who can dimiss pull request reviews. 1183 Users []*User `json:"users"` 1184 // The list of teams which can dismiss pull request reviews. 1185 Teams []*Team `json:"teams"` 1186 // The list of apps which can dismiss pull request reviews. 1187 Apps []*App `json:"apps"` 1188 } 1189 1190 // DismissalRestrictionsRequest represents the request to create/edit the 1191 // restriction to allows only specific users, teams or apps to dimiss pull request reviews. It is 1192 // separate from DismissalRestrictions above because the request structure is 1193 // different from the response structure. 1194 // Note: Both Users and Teams must be nil, or both must be non-nil. 1195 type DismissalRestrictionsRequest struct { 1196 // The list of user logins who can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 1197 Users *[]string `json:"users,omitempty"` 1198 // The list of team slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 1199 Teams *[]string `json:"teams,omitempty"` 1200 // The list of app slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 1201 Apps *[]string `json:"apps,omitempty"` 1202 } 1203 1204 // SignaturesProtectedBranch represents the protection status of an individual branch. 1205 type SignaturesProtectedBranch struct { 1206 URL *string `json:"url,omitempty"` 1207 // Commits pushed to matching branches must have verified signatures. 1208 Enabled *bool `json:"enabled,omitempty"` 1209 } 1210 1211 // ListBranches lists branches for the specified repository. 1212 // 1213 // GitHub API docs: https://docs.github.com/en/rest/branches/branches#list-branches 1214 func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) { 1215 u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) 1216 u, err := addOptions(u, opts) 1217 if err != nil { 1218 return nil, nil, err 1219 } 1220 1221 req, err := s.client.NewRequest("GET", u, nil) 1222 if err != nil { 1223 return nil, nil, err 1224 } 1225 1226 var branches []*Branch 1227 resp, err := s.client.Do(ctx, req, &branches) 1228 if err != nil { 1229 return nil, resp, err 1230 } 1231 1232 return branches, resp, nil 1233 } 1234 1235 // GetBranch gets the specified branch for a repository. 1236 // 1237 // GitHub API docs: https://docs.github.com/en/rest/branches/branches#get-a-branch 1238 func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string, followRedirects bool) (*Branch, *Response, error) { 1239 u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) 1240 1241 resp, err := s.client.roundTripWithOptionalFollowRedirect(ctx, u, followRedirects) 1242 if err != nil { 1243 return nil, nil, err 1244 } 1245 defer resp.Body.Close() 1246 1247 if resp.StatusCode != http.StatusOK { 1248 return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) 1249 } 1250 1251 b := new(Branch) 1252 err = json.NewDecoder(resp.Body).Decode(b) 1253 return b, newResponse(resp), err 1254 } 1255 1256 // renameBranchRequest represents a request to rename a branch. 1257 type renameBranchRequest struct { 1258 NewName string `json:"new_name"` 1259 } 1260 1261 // RenameBranch renames a branch in a repository. 1262 // 1263 // To rename a non-default branch: Users must have push access. GitHub Apps must have the `contents:write` repository permission. 1264 // To rename the default branch: Users must have admin or owner permissions. GitHub Apps must have the `administration:write` repository permission. 1265 // 1266 // GitHub API docs: https://docs.github.com/en/rest/branches/branches#rename-a-branch 1267 func (s *RepositoriesService) RenameBranch(ctx context.Context, owner, repo, branch, newName string) (*Branch, *Response, error) { 1268 u := fmt.Sprintf("repos/%v/%v/branches/%v/rename", owner, repo, branch) 1269 r := &renameBranchRequest{NewName: newName} 1270 req, err := s.client.NewRequest("POST", u, r) 1271 if err != nil { 1272 return nil, nil, err 1273 } 1274 1275 b := new(Branch) 1276 resp, err := s.client.Do(ctx, req, b) 1277 if err != nil { 1278 return nil, resp, err 1279 } 1280 1281 return b, resp, nil 1282 } 1283 1284 // GetBranchProtection gets the protection of a given branch. 1285 // 1286 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-branch-protection 1287 func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*Protection, *Response, error) { 1288 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1289 req, err := s.client.NewRequest("GET", u, nil) 1290 if err != nil { 1291 return nil, nil, err 1292 } 1293 1294 // TODO: remove custom Accept header when this API fully launches 1295 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1296 1297 p := new(Protection) 1298 resp, err := s.client.Do(ctx, req, p) 1299 if err != nil { 1300 if isBranchNotProtected(err) { 1301 err = ErrBranchNotProtected 1302 } 1303 return nil, resp, err 1304 } 1305 1306 return p, resp, nil 1307 } 1308 1309 // GetRequiredStatusChecks gets the required status checks for a given protected branch. 1310 // 1311 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-status-checks-protection 1312 func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) { 1313 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1314 req, err := s.client.NewRequest("GET", u, nil) 1315 if err != nil { 1316 return nil, nil, err 1317 } 1318 1319 p := new(RequiredStatusChecks) 1320 resp, err := s.client.Do(ctx, req, p) 1321 if err != nil { 1322 if isBranchNotProtected(err) { 1323 err = ErrBranchNotProtected 1324 } 1325 return nil, resp, err 1326 } 1327 1328 return p, resp, nil 1329 } 1330 1331 // ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch. 1332 // 1333 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-all-status-check-contexts 1334 func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) { 1335 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch) 1336 req, err := s.client.NewRequest("GET", u, nil) 1337 if err != nil { 1338 return nil, nil, err 1339 } 1340 1341 resp, err = s.client.Do(ctx, req, &contexts) 1342 if err != nil { 1343 if isBranchNotProtected(err) { 1344 err = ErrBranchNotProtected 1345 } 1346 return nil, resp, err 1347 } 1348 1349 return contexts, resp, nil 1350 } 1351 1352 // UpdateBranchProtection updates the protection of a given branch. 1353 // 1354 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-branch-protection 1355 func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, repo, branch string, preq *ProtectionRequest) (*Protection, *Response, error) { 1356 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1357 req, err := s.client.NewRequest("PUT", u, preq) 1358 if err != nil { 1359 return nil, nil, err 1360 } 1361 1362 // TODO: remove custom Accept header when this API fully launches 1363 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1364 1365 p := new(Protection) 1366 resp, err := s.client.Do(ctx, req, p) 1367 if err != nil { 1368 return nil, resp, err 1369 } 1370 1371 return p, resp, nil 1372 } 1373 1374 // RemoveBranchProtection removes the protection of a given branch. 1375 // 1376 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-branch-protection 1377 func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) { 1378 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1379 req, err := s.client.NewRequest("DELETE", u, nil) 1380 if err != nil { 1381 return nil, err 1382 } 1383 1384 return s.client.Do(ctx, req, nil) 1385 } 1386 1387 // GetSignaturesProtectedBranch gets required signatures of protected branch. 1388 // 1389 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-commit-signature-protection 1390 func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { 1391 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1392 req, err := s.client.NewRequest("GET", u, nil) 1393 if err != nil { 1394 return nil, nil, err 1395 } 1396 1397 // TODO: remove custom Accept header when this API fully launches 1398 req.Header.Set("Accept", mediaTypeSignaturePreview) 1399 1400 p := new(SignaturesProtectedBranch) 1401 resp, err := s.client.Do(ctx, req, p) 1402 if err != nil { 1403 return nil, resp, err 1404 } 1405 1406 return p, resp, nil 1407 } 1408 1409 // RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch. 1410 // It requires admin access and branch protection to be enabled. 1411 // 1412 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#create-commit-signature-protection 1413 func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { 1414 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1415 req, err := s.client.NewRequest("POST", u, nil) 1416 if err != nil { 1417 return nil, nil, err 1418 } 1419 1420 // TODO: remove custom Accept header when this API fully launches 1421 req.Header.Set("Accept", mediaTypeSignaturePreview) 1422 1423 r := new(SignaturesProtectedBranch) 1424 resp, err := s.client.Do(ctx, req, r) 1425 if err != nil { 1426 return nil, resp, err 1427 } 1428 1429 return r, resp, nil 1430 } 1431 1432 // OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch. 1433 // 1434 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-commit-signature-protection 1435 func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) { 1436 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1437 req, err := s.client.NewRequest("DELETE", u, nil) 1438 if err != nil { 1439 return nil, err 1440 } 1441 1442 // TODO: remove custom Accept header when this API fully launches 1443 req.Header.Set("Accept", mediaTypeSignaturePreview) 1444 1445 return s.client.Do(ctx, req, nil) 1446 } 1447 1448 // UpdateRequiredStatusChecks updates the required status checks for a given protected branch. 1449 // 1450 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-status-check-protection 1451 func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, owner, repo, branch string, sreq *RequiredStatusChecksRequest) (*RequiredStatusChecks, *Response, error) { 1452 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1453 req, err := s.client.NewRequest("PATCH", u, sreq) 1454 if err != nil { 1455 return nil, nil, err 1456 } 1457 1458 sc := new(RequiredStatusChecks) 1459 resp, err := s.client.Do(ctx, req, sc) 1460 if err != nil { 1461 return nil, resp, err 1462 } 1463 1464 return sc, resp, nil 1465 } 1466 1467 // RemoveRequiredStatusChecks removes the required status checks for a given protected branch. 1468 // 1469 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-status-check-protection 1470 func (s *RepositoriesService) RemoveRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*Response, error) { 1471 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1472 req, err := s.client.NewRequest("DELETE", u, nil) 1473 if err != nil { 1474 return nil, err 1475 } 1476 1477 return s.client.Do(ctx, req, nil) 1478 } 1479 1480 // License gets the contents of a repository's license if one is detected. 1481 // 1482 // GitHub API docs: https://docs.github.com/en/rest/licenses#get-the-license-for-a-repository 1483 func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) { 1484 u := fmt.Sprintf("repos/%v/%v/license", owner, repo) 1485 req, err := s.client.NewRequest("GET", u, nil) 1486 if err != nil { 1487 return nil, nil, err 1488 } 1489 1490 r := &RepositoryLicense{} 1491 resp, err := s.client.Do(ctx, req, r) 1492 if err != nil { 1493 return nil, resp, err 1494 } 1495 1496 return r, resp, nil 1497 } 1498 1499 // GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch. 1500 // 1501 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-pull-request-review-protection 1502 func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { 1503 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1504 req, err := s.client.NewRequest("GET", u, nil) 1505 if err != nil { 1506 return nil, nil, err 1507 } 1508 1509 // TODO: remove custom Accept header when this API fully launches 1510 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1511 1512 r := new(PullRequestReviewsEnforcement) 1513 resp, err := s.client.Do(ctx, req, r) 1514 if err != nil { 1515 return nil, resp, err 1516 } 1517 1518 return r, resp, nil 1519 } 1520 1521 // UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch. 1522 // It requires admin access and branch protection to be enabled. 1523 // 1524 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-pull-request-review-protection 1525 func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { 1526 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1527 req, err := s.client.NewRequest("PATCH", u, patch) 1528 if err != nil { 1529 return nil, nil, err 1530 } 1531 1532 // TODO: remove custom Accept header when this API fully launches 1533 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1534 1535 r := new(PullRequestReviewsEnforcement) 1536 resp, err := s.client.Do(ctx, req, r) 1537 if err != nil { 1538 return nil, resp, err 1539 } 1540 1541 return r, resp, nil 1542 } 1543 1544 // DisableDismissalRestrictions disables dismissal restrictions of a protected branch. 1545 // It requires admin access and branch protection to be enabled. 1546 // 1547 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-pull-request-review-protection 1548 func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { 1549 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1550 1551 data := new(struct { 1552 DismissalRestrictionsRequest `json:"dismissal_restrictions"` 1553 }) 1554 1555 req, err := s.client.NewRequest("PATCH", u, data) 1556 if err != nil { 1557 return nil, nil, err 1558 } 1559 1560 // TODO: remove custom Accept header when this API fully launches 1561 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1562 1563 r := new(PullRequestReviewsEnforcement) 1564 resp, err := s.client.Do(ctx, req, r) 1565 if err != nil { 1566 return nil, resp, err 1567 } 1568 1569 return r, resp, nil 1570 } 1571 1572 // RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. 1573 // 1574 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-pull-request-review-protection 1575 func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { 1576 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1577 req, err := s.client.NewRequest("DELETE", u, nil) 1578 if err != nil { 1579 return nil, err 1580 } 1581 1582 return s.client.Do(ctx, req, nil) 1583 } 1584 1585 // GetAdminEnforcement gets admin enforcement information of a protected branch. 1586 // 1587 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-admin-branch-protection 1588 func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { 1589 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1590 req, err := s.client.NewRequest("GET", u, nil) 1591 if err != nil { 1592 return nil, nil, err 1593 } 1594 1595 r := new(AdminEnforcement) 1596 resp, err := s.client.Do(ctx, req, r) 1597 if err != nil { 1598 return nil, resp, err 1599 } 1600 1601 return r, resp, nil 1602 } 1603 1604 // AddAdminEnforcement adds admin enforcement to a protected branch. 1605 // It requires admin access and branch protection to be enabled. 1606 // 1607 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-admin-branch-protection 1608 func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { 1609 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1610 req, err := s.client.NewRequest("POST", u, nil) 1611 if err != nil { 1612 return nil, nil, err 1613 } 1614 1615 r := new(AdminEnforcement) 1616 resp, err := s.client.Do(ctx, req, r) 1617 if err != nil { 1618 return nil, resp, err 1619 } 1620 1621 return r, resp, nil 1622 } 1623 1624 // RemoveAdminEnforcement removes admin enforcement from a protected branch. 1625 // 1626 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-admin-branch-protection 1627 func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { 1628 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1629 req, err := s.client.NewRequest("DELETE", u, nil) 1630 if err != nil { 1631 return nil, err 1632 } 1633 1634 return s.client.Do(ctx, req, nil) 1635 } 1636 1637 // repositoryTopics represents a collection of repository topics. 1638 type repositoryTopics struct { 1639 Names []string `json:"names"` 1640 } 1641 1642 // ListAllTopics lists topics for a repository. 1643 // 1644 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#get-all-repository-topics 1645 func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) { 1646 u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) 1647 req, err := s.client.NewRequest("GET", u, nil) 1648 if err != nil { 1649 return nil, nil, err 1650 } 1651 1652 // TODO: remove custom Accept header when this API fully launches. 1653 req.Header.Set("Accept", mediaTypeTopicsPreview) 1654 1655 topics := new(repositoryTopics) 1656 resp, err := s.client.Do(ctx, req, topics) 1657 if err != nil { 1658 return nil, resp, err 1659 } 1660 1661 return topics.Names, resp, nil 1662 } 1663 1664 // ReplaceAllTopics replaces all repository topics. 1665 // 1666 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#replace-all-repository-topics 1667 func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) { 1668 u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) 1669 t := &repositoryTopics{ 1670 Names: topics, 1671 } 1672 if t.Names == nil { 1673 t.Names = []string{} 1674 } 1675 req, err := s.client.NewRequest("PUT", u, t) 1676 if err != nil { 1677 return nil, nil, err 1678 } 1679 1680 // TODO: remove custom Accept header when this API fully launches. 1681 req.Header.Set("Accept", mediaTypeTopicsPreview) 1682 1683 t = new(repositoryTopics) 1684 resp, err := s.client.Do(ctx, req, t) 1685 if err != nil { 1686 return nil, resp, err 1687 } 1688 1689 return t.Names, resp, nil 1690 } 1691 1692 // ListApps lists the GitHub apps that have push access to a given protected branch. 1693 // It requires the GitHub apps to have `write` access to the `content` permission. 1694 // 1695 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch 1696 // 1697 // Deprecated: Please use ListAppRestrictions instead. 1698 func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { 1699 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1700 req, err := s.client.NewRequest("GET", u, nil) 1701 if err != nil { 1702 return nil, nil, err 1703 } 1704 1705 var apps []*App 1706 resp, err := s.client.Do(ctx, req, &apps) 1707 if err != nil { 1708 return nil, resp, err 1709 } 1710 1711 return apps, resp, nil 1712 } 1713 1714 // ListAppRestrictions lists the GitHub apps that have push access to a given protected branch. 1715 // It requires the GitHub apps to have `write` access to the `content` permission. 1716 // 1717 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch 1718 // 1719 // Note: This is a wrapper around ListApps so a naming convention with ListUserRestrictions and ListTeamRestrictions is preserved. 1720 func (s *RepositoriesService) ListAppRestrictions(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { 1721 return s.ListApps(ctx, owner, repo, branch) 1722 } 1723 1724 // ReplaceAppRestrictions replaces the apps that have push access to a given protected branch. 1725 // It removes all apps that previously had push access and grants push access to the new list of apps. 1726 // It requires the GitHub apps to have `write` access to the `content` permission. 1727 // 1728 // Note: The list of users, apps, and teams in total is limited to 100 items. 1729 // 1730 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-app-access-restrictions 1731 func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) { 1732 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1733 req, err := s.client.NewRequest("PUT", u, apps) 1734 if err != nil { 1735 return nil, nil, err 1736 } 1737 1738 var newApps []*App 1739 resp, err := s.client.Do(ctx, req, &newApps) 1740 if err != nil { 1741 return nil, resp, err 1742 } 1743 1744 return newApps, resp, nil 1745 } 1746 1747 // AddAppRestrictions grants the specified apps push access to a given protected branch. 1748 // It requires the GitHub apps to have `write` access to the `content` permission. 1749 // 1750 // Note: The list of users, apps, and teams in total is limited to 100 items. 1751 // 1752 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-app-access-restrictions 1753 func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) { 1754 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1755 req, err := s.client.NewRequest("POST", u, apps) 1756 if err != nil { 1757 return nil, nil, err 1758 } 1759 1760 var newApps []*App 1761 resp, err := s.client.Do(ctx, req, &newApps) 1762 if err != nil { 1763 return nil, resp, err 1764 } 1765 1766 return newApps, resp, nil 1767 } 1768 1769 // RemoveAppRestrictions removes the restrictions of an app from pushing to this branch. 1770 // It requires the GitHub apps to have `write` access to the `content` permission. 1771 // 1772 // Note: The list of users, apps, and teams in total is limited to 100 items. 1773 // 1774 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-app-access-restrictions 1775 func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) { 1776 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1777 req, err := s.client.NewRequest("DELETE", u, apps) 1778 if err != nil { 1779 return nil, nil, err 1780 } 1781 1782 var newApps []*App 1783 resp, err := s.client.Do(ctx, req, &newApps) 1784 if err != nil { 1785 return nil, resp, err 1786 } 1787 1788 return newApps, resp, nil 1789 } 1790 1791 // ListTeamRestrictions lists the GitHub teams that have push access to a given protected branch. 1792 // It requires the GitHub teams to have `write` access to the `content` permission. 1793 // 1794 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-teams-with-access-to-the-protected-branch 1795 func (s *RepositoriesService) ListTeamRestrictions(ctx context.Context, owner, repo, branch string) ([]*Team, *Response, error) { 1796 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1797 req, err := s.client.NewRequest("GET", u, nil) 1798 if err != nil { 1799 return nil, nil, err 1800 } 1801 1802 var teams []*Team 1803 resp, err := s.client.Do(ctx, req, &teams) 1804 if err != nil { 1805 return nil, resp, err 1806 } 1807 1808 return teams, resp, nil 1809 } 1810 1811 // ReplaceTeamRestrictions replaces the team that have push access to a given protected branch. 1812 // This removes all teams that previously had push access and grants push access to the new list of teams. 1813 // It requires the GitHub teams to have `write` access to the `content` permission. 1814 // 1815 // Note: The list of users, apps, and teams in total is limited to 100 items. 1816 // 1817 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-team-access-restrictions 1818 func (s *RepositoriesService) ReplaceTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) { 1819 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1820 req, err := s.client.NewRequest("PUT", u, teams) 1821 if err != nil { 1822 return nil, nil, err 1823 } 1824 1825 var newTeams []*Team 1826 resp, err := s.client.Do(ctx, req, &newTeams) 1827 if err != nil { 1828 return nil, resp, err 1829 } 1830 1831 return newTeams, resp, nil 1832 } 1833 1834 // AddTeamRestrictions grants the specified teams push access to a given protected branch. 1835 // It requires the GitHub teams to have `write` access to the `content` permission. 1836 // 1837 // Note: The list of users, apps, and teams in total is limited to 100 items. 1838 // 1839 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-team-access-restrictions 1840 func (s *RepositoriesService) AddTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) { 1841 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1842 req, err := s.client.NewRequest("POST", u, teams) 1843 if err != nil { 1844 return nil, nil, err 1845 } 1846 1847 var newTeams []*Team 1848 resp, err := s.client.Do(ctx, req, &newTeams) 1849 if err != nil { 1850 return nil, resp, err 1851 } 1852 1853 return newTeams, resp, nil 1854 } 1855 1856 // RemoveTeamRestrictions removes the restrictions of a team from pushing to this branch. 1857 // It requires the GitHub teams to have `write` access to the `content` permission. 1858 // 1859 // Note: The list of users, apps, and teams in total is limited to 100 items. 1860 // 1861 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-team-access-restrictions 1862 func (s *RepositoriesService) RemoveTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) { 1863 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1864 req, err := s.client.NewRequest("DELETE", u, teams) 1865 if err != nil { 1866 return nil, nil, err 1867 } 1868 1869 var newTeams []*Team 1870 resp, err := s.client.Do(ctx, req, &newTeams) 1871 if err != nil { 1872 return nil, resp, err 1873 } 1874 1875 return newTeams, resp, nil 1876 } 1877 1878 // ListUserRestrictions lists the GitHub users that have push access to a given protected branch. 1879 // It requires the GitHub users to have `write` access to the `content` permission. 1880 // 1881 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-users-with-access-to-the-protected-branch 1882 func (s *RepositoriesService) ListUserRestrictions(ctx context.Context, owner, repo, branch string) ([]*User, *Response, error) { 1883 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1884 req, err := s.client.NewRequest("GET", u, nil) 1885 if err != nil { 1886 return nil, nil, err 1887 } 1888 1889 var users []*User 1890 resp, err := s.client.Do(ctx, req, &users) 1891 if err != nil { 1892 return nil, resp, err 1893 } 1894 1895 return users, resp, nil 1896 } 1897 1898 // ReplaceUserRestrictions replaces the user that have push access to a given protected branch. 1899 // It removes all users that previously had push access and grants push access to the new list of users. 1900 // It requires the GitHub users to have `write` access to the `content` permission. 1901 // 1902 // Note: The list of users, apps, and teams in total is limited to 100 items. 1903 // 1904 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-team-access-restrictions 1905 func (s *RepositoriesService) ReplaceUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) { 1906 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1907 req, err := s.client.NewRequest("PUT", u, users) 1908 if err != nil { 1909 return nil, nil, err 1910 } 1911 1912 var newUsers []*User 1913 resp, err := s.client.Do(ctx, req, &newUsers) 1914 if err != nil { 1915 return nil, resp, err 1916 } 1917 1918 return newUsers, resp, nil 1919 } 1920 1921 // AddUserRestrictions grants the specified users push access to a given protected branch. 1922 // It requires the GitHub users to have `write` access to the `content` permission. 1923 // 1924 // Note: The list of users, apps, and teams in total is limited to 100 items. 1925 // 1926 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-team-access-restrictions 1927 func (s *RepositoriesService) AddUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) { 1928 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1929 req, err := s.client.NewRequest("POST", u, users) 1930 if err != nil { 1931 return nil, nil, err 1932 } 1933 1934 var newUsers []*User 1935 resp, err := s.client.Do(ctx, req, &newUsers) 1936 if err != nil { 1937 return nil, resp, err 1938 } 1939 1940 return newUsers, resp, nil 1941 } 1942 1943 // RemoveUserRestrictions removes the restrictions of a user from pushing to this branch. 1944 // It requires the GitHub users to have `write` access to the `content` permission. 1945 // 1946 // Note: The list of users, apps, and teams in total is limited to 100 items. 1947 // 1948 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-team-access-restrictions 1949 func (s *RepositoriesService) RemoveUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) { 1950 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1951 req, err := s.client.NewRequest("DELETE", u, users) 1952 if err != nil { 1953 return nil, nil, err 1954 } 1955 1956 var newUsers []*User 1957 resp, err := s.client.Do(ctx, req, &newUsers) 1958 if err != nil { 1959 return nil, resp, err 1960 } 1961 1962 return newUsers, resp, nil 1963 } 1964 1965 // TransferRequest represents a request to transfer a repository. 1966 type TransferRequest struct { 1967 NewOwner string `json:"new_owner"` 1968 TeamID []int64 `json:"team_ids,omitempty"` 1969 } 1970 1971 // Transfer transfers a repository from one account or organization to another. 1972 // 1973 // This method might return an *AcceptedError and a status code of 1974 // 202. This is because this is the status that GitHub returns to signify that 1975 // it has now scheduled the transfer of the repository in a background task. 1976 // A follow up request, after a delay of a second or so, should result 1977 // in a successful request. 1978 // 1979 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#transfer-a-repository 1980 func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, transfer TransferRequest) (*Repository, *Response, error) { 1981 u := fmt.Sprintf("repos/%v/%v/transfer", owner, repo) 1982 1983 req, err := s.client.NewRequest("POST", u, &transfer) 1984 if err != nil { 1985 return nil, nil, err 1986 } 1987 1988 r := new(Repository) 1989 resp, err := s.client.Do(ctx, req, r) 1990 if err != nil { 1991 return nil, resp, err 1992 } 1993 1994 return r, resp, nil 1995 } 1996 1997 // DispatchRequestOptions represents a request to trigger a repository_dispatch event. 1998 type DispatchRequestOptions struct { 1999 // EventType is a custom webhook event name. (Required.) 2000 EventType string `json:"event_type"` 2001 // ClientPayload is a custom JSON payload with extra information about the webhook event. 2002 // Defaults to an empty JSON object. 2003 ClientPayload *json.RawMessage `json:"client_payload,omitempty"` 2004 } 2005 2006 // Dispatch triggers a repository_dispatch event in a GitHub Actions workflow. 2007 // 2008 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#create-a-repository-dispatch-event 2009 func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) { 2010 u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo) 2011 2012 req, err := s.client.NewRequest("POST", u, &opts) 2013 if err != nil { 2014 return nil, nil, err 2015 } 2016 2017 r := new(Repository) 2018 resp, err := s.client.Do(ctx, req, r) 2019 if err != nil { 2020 return nil, resp, err 2021 } 2022 2023 return r, resp, nil 2024 } 2025 2026 // isBranchNotProtected determines whether a branch is not protected 2027 // based on the error message returned by GitHub API. 2028 func isBranchNotProtected(err error) bool { 2029 errorResponse, ok := err.(*ErrorResponse) 2030 return ok && errorResponse.Message == githubBranchNotProtected 2031 }