github.com/google/go-github/v52@v52.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/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 RequiredSignatures *SignaturesProtectedBranch `json:"required_signatures,omitempty"` 851 URL *string `json:"url,omitempty"` 852 } 853 854 // BlockCreations represents whether users can push changes that create branches. If this is true, this 855 // setting blocks pushes that create new branches, unless the push is initiated by a user, team, or app 856 // which has the ability to push. 857 type BlockCreations struct { 858 Enabled *bool `json:"enabled,omitempty"` 859 } 860 861 // LockBranch represents if the branch is marked as read-only. If this is true, users will not be able to push to the branch. 862 type LockBranch struct { 863 Enabled *bool `json:"enabled,omitempty"` 864 } 865 866 // AllowForkSyncing represents whether users can pull changes from upstream when the branch is locked. 867 type AllowForkSyncing struct { 868 Enabled *bool `json:"enabled,omitempty"` 869 } 870 871 // BranchProtectionRule represents the rule applied to a repositories branch. 872 type BranchProtectionRule struct { 873 ID *int64 `json:"id,omitempty"` 874 RepositoryID *int64 `json:"repository_id,omitempty"` 875 Name *string `json:"name,omitempty"` 876 CreatedAt *Timestamp `json:"created_at,omitempty"` 877 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 878 PullRequestReviewsEnforcementLevel *string `json:"pull_request_reviews_enforcement_level,omitempty"` 879 RequiredApprovingReviewCount *int `json:"required_approving_review_count,omitempty"` 880 DismissStaleReviewsOnPush *bool `json:"dismiss_stale_reviews_on_push,omitempty"` 881 AuthorizedDismissalActorsOnly *bool `json:"authorized_dismissal_actors_only,omitempty"` 882 IgnoreApprovalsFromContributors *bool `json:"ignore_approvals_from_contributors,omitempty"` 883 RequireCodeOwnerReview *bool `json:"require_code_owner_review,omitempty"` 884 RequiredStatusChecks []string `json:"required_status_checks,omitempty"` 885 RequiredStatusChecksEnforcementLevel *string `json:"required_status_checks_enforcement_level,omitempty"` 886 StrictRequiredStatusChecksPolicy *bool `json:"strict_required_status_checks_policy,omitempty"` 887 SignatureRequirementEnforcementLevel *string `json:"signature_requirement_enforcement_level,omitempty"` 888 LinearHistoryRequirementEnforcementLevel *string `json:"linear_history_requirement_enforcement_level,omitempty"` 889 AdminEnforced *bool `json:"admin_enforced,omitempty"` 890 AllowForcePushesEnforcementLevel *string `json:"allow_force_pushes_enforcement_level,omitempty"` 891 AllowDeletionsEnforcementLevel *string `json:"allow_deletions_enforcement_level,omitempty"` 892 MergeQueueEnforcementLevel *string `json:"merge_queue_enforcement_level,omitempty"` 893 RequiredDeploymentsEnforcementLevel *string `json:"required_deployments_enforcement_level,omitempty"` 894 RequiredConversationResolutionLevel *string `json:"required_conversation_resolution_level,omitempty"` 895 AuthorizedActorsOnly *bool `json:"authorized_actors_only,omitempty"` 896 AuthorizedActorNames []string `json:"authorized_actor_names,omitempty"` 897 } 898 899 // ProtectionChanges represents the changes to the rule if the BranchProtection was edited. 900 type ProtectionChanges struct { 901 AdminEnforced *AdminEnforcedChanges `json:"admin_enforced,omitempty"` 902 AllowDeletionsEnforcementLevel *AllowDeletionsEnforcementLevelChanges `json:"allow_deletions_enforcement_level,omitempty"` 903 AuthorizedActorNames *AuthorizedActorNames `json:"authorized_actor_names,omitempty"` 904 AuthorizedActorsOnly *AuthorizedActorsOnly `json:"authorized_actors_only,omitempty"` 905 AuthorizedDismissalActorsOnly *AuthorizedDismissalActorsOnlyChanges `json:"authorized_dismissal_actors_only,omitempty"` 906 CreateProtected *CreateProtectedChanges `json:"create_protected,omitempty"` 907 DismissStaleReviewsOnPush *DismissStaleReviewsOnPushChanges `json:"dismiss_stale_reviews_on_push,omitempty"` 908 LinearHistoryRequirementEnforcementLevel *LinearHistoryRequirementEnforcementLevelChanges `json:"linear_history_requirement_enforcement_level,omitempty"` 909 PullRequestReviewsEnforcementLevel *PullRequestReviewsEnforcementLevelChanges `json:"pull_request_reviews_enforcement_level,omitempty"` 910 RequireCodeOwnerReview *RequireCodeOwnerReviewChanges `json:"require_code_owner_review,omitempty"` 911 RequiredConversationResolutionLevel *RequiredConversationResolutionLevelChanges `json:"required_conversation_resolution_level,omitempty"` 912 RequiredDeploymentsEnforcementLevel *RequiredDeploymentsEnforcementLevelChanges `json:"required_deployments_enforcement_level,omitempty"` 913 RequiredStatusChecks *RequiredStatusChecksChanges `json:"required_status_checks,omitempty"` 914 RequiredStatusChecksEnforcementLevel *RequiredStatusChecksEnforcementLevelChanges `json:"required_status_checks_enforcement_level,omitempty"` 915 SignatureRequirementEnforcementLevel *SignatureRequirementEnforcementLevelChanges `json:"signature_requirement_enforcement_level,omitempty"` 916 } 917 918 // AdminEnforcedChanges represents the changes made to the AdminEnforced policy. 919 type AdminEnforcedChanges struct { 920 From *bool `json:"from,omitempty"` 921 } 922 923 // AllowDeletionsEnforcementLevelChanges represents the changes made to the AllowDeletionsEnforcementLevel policy. 924 type AllowDeletionsEnforcementLevelChanges struct { 925 From *string `json:"from,omitempty"` 926 } 927 928 // AuthorizedActorNames represents who are authorized to edit the branch protection rules. 929 type AuthorizedActorNames struct { 930 From []string `json:"from,omitempty"` 931 } 932 933 // AuthorizedActorsOnly represents if the branch rule can be edited by authorized actors only. 934 type AuthorizedActorsOnly struct { 935 From *bool `json:"from,omitempty"` 936 } 937 938 // AuthorizedDismissalActorsOnlyChanges represents the changes made to the AuthorizedDismissalActorsOnly policy. 939 type AuthorizedDismissalActorsOnlyChanges struct { 940 From *bool `json:"from,omitempty"` 941 } 942 943 // CreateProtectedChanges represents the changes made to the CreateProtected policy. 944 type CreateProtectedChanges struct { 945 From *bool `json:"from,omitempty"` 946 } 947 948 // DismissStaleReviewsOnPushChanges represents the changes made to the DismissStaleReviewsOnPushChanges policy. 949 type DismissStaleReviewsOnPushChanges struct { 950 From *bool `json:"from,omitempty"` 951 } 952 953 // LinearHistoryRequirementEnforcementLevelChanges represents the changes made to the LinearHistoryRequirementEnforcementLevel policy. 954 type LinearHistoryRequirementEnforcementLevelChanges struct { 955 From *string `json:"from,omitempty"` 956 } 957 958 // PullRequestReviewsEnforcementLevelChanges represents the changes made to the PullRequestReviewsEnforcementLevel policy. 959 type PullRequestReviewsEnforcementLevelChanges struct { 960 From *string `json:"from,omitempty"` 961 } 962 963 // RequireCodeOwnerReviewChanges represents the changes made to the RequireCodeOwnerReview policy. 964 type RequireCodeOwnerReviewChanges struct { 965 From *bool `json:"from,omitempty"` 966 } 967 968 // RequiredConversationResolutionLevelChanges represents the changes made to the RequiredConversationResolutionLevel policy. 969 type RequiredConversationResolutionLevelChanges struct { 970 From *string `json:"from,omitempty"` 971 } 972 973 // RequiredDeploymentsEnforcementLevelChanges represents the changes made to the RequiredDeploymentsEnforcementLevel policy. 974 type RequiredDeploymentsEnforcementLevelChanges struct { 975 From *string `json:"from,omitempty"` 976 } 977 978 // RequiredStatusChecksChanges represents the changes made to the RequiredStatusChecks policy. 979 type RequiredStatusChecksChanges struct { 980 From []string `json:"from,omitempty"` 981 } 982 983 // RequiredStatusChecksEnforcementLevelChanges represents the changes made to the RequiredStatusChecksEnforcementLevel policy. 984 type RequiredStatusChecksEnforcementLevelChanges struct { 985 From *string `json:"from,omitempty"` 986 } 987 988 // SignatureRequirementEnforcementLevelChanges represents the changes made to the SignatureRequirementEnforcementLevel policy. 989 type SignatureRequirementEnforcementLevelChanges struct { 990 From *string `json:"from,omitempty"` 991 } 992 993 // ProtectionRequest represents a request to create/edit a branch's protection. 994 type ProtectionRequest struct { 995 RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` 996 RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"` 997 EnforceAdmins bool `json:"enforce_admins"` 998 Restrictions *BranchRestrictionsRequest `json:"restrictions"` 999 // Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch. 1000 RequireLinearHistory *bool `json:"required_linear_history,omitempty"` 1001 // Permits force pushes to the protected branch by anyone with write access to the repository. 1002 AllowForcePushes *bool `json:"allow_force_pushes,omitempty"` 1003 // Allows deletion of the protected branch by anyone with write access to the repository. 1004 AllowDeletions *bool `json:"allow_deletions,omitempty"` 1005 // RequiredConversationResolution, if set to true, requires all comments 1006 // on the pull request to be resolved before it can be merged to a protected branch. 1007 RequiredConversationResolution *bool `json:"required_conversation_resolution,omitempty"` 1008 // BlockCreations, if set to true, will cause the restrictions setting to also block pushes 1009 // which create new branches, unless initiated by a user, team, app with the ability to push. 1010 BlockCreations *bool `json:"block_creations,omitempty"` 1011 // LockBranch, if set to true, will prevent users from pushing to the branch. 1012 LockBranch *bool `json:"lock_branch,omitempty"` 1013 // AllowForkSyncing, if set to true, will allow users to pull changes from upstream 1014 // when the branch is locked. 1015 AllowForkSyncing *bool `json:"allow_fork_syncing,omitempty"` 1016 } 1017 1018 // RequiredStatusChecks represents the protection status of a individual branch. 1019 type RequiredStatusChecks struct { 1020 // Require branches to be up to date before merging. (Required.) 1021 Strict bool `json:"strict"` 1022 // The list of status checks to require in order to merge into this 1023 // branch. (Deprecated. Note: only one of Contexts/Checks can be populated, 1024 // but at least one must be populated). 1025 Contexts []string `json:"contexts,omitempty"` 1026 // The list of status checks to require in order to merge into this 1027 // branch. 1028 Checks []*RequiredStatusCheck `json:"checks"` 1029 ContextsURL *string `json:"contexts_url,omitempty"` 1030 URL *string `json:"url,omitempty"` 1031 } 1032 1033 // RequiredStatusChecksRequest represents a request to edit a protected branch's status checks. 1034 type RequiredStatusChecksRequest struct { 1035 Strict *bool `json:"strict,omitempty"` 1036 // Note: if both Contexts and Checks are populated, 1037 // the GitHub API will only use Checks. 1038 Contexts []string `json:"contexts,omitempty"` 1039 Checks []*RequiredStatusCheck `json:"checks,omitempty"` 1040 } 1041 1042 // RequiredStatusCheck represents a status check of a protected branch. 1043 type RequiredStatusCheck struct { 1044 // The name of the required check. 1045 Context string `json:"context"` 1046 // The ID of the GitHub App that must provide this check. 1047 // Omit this field to automatically select the GitHub App 1048 // that has recently provided this check, 1049 // or any app if it was not set by a GitHub App. 1050 // Pass -1 to explicitly allow any app to set the status. 1051 AppID *int64 `json:"app_id,omitempty"` 1052 } 1053 1054 // PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch. 1055 type PullRequestReviewsEnforcement struct { 1056 // Allow specific users, teams, or apps to bypass pull request requirements. 1057 BypassPullRequestAllowances *BypassPullRequestAllowances `json:"bypass_pull_request_allowances,omitempty"` 1058 // Specifies which users, teams and apps can dismiss pull request reviews. 1059 DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions,omitempty"` 1060 // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. 1061 DismissStaleReviews bool `json:"dismiss_stale_reviews"` 1062 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 1063 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` 1064 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 1065 // Valid values are 1-6. 1066 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 1067 // RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it. 1068 RequireLastPushApproval bool `json:"require_last_push_approval"` 1069 } 1070 1071 // PullRequestReviewsEnforcementRequest represents request to set the pull request review 1072 // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above 1073 // because the request structure is different from the response structure. 1074 type PullRequestReviewsEnforcementRequest struct { 1075 // Allow specific users, teams, or apps to bypass pull request requirements. 1076 BypassPullRequestAllowancesRequest *BypassPullRequestAllowancesRequest `json:"bypass_pull_request_allowances,omitempty"` 1077 // Specifies which users, teams and apps should be allowed to dismiss pull request reviews. 1078 // User, team and app dismissal restrictions are only available for 1079 // organization-owned repositories. Must be nil for personal repositories. 1080 DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` 1081 // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required) 1082 DismissStaleReviews bool `json:"dismiss_stale_reviews"` 1083 // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. 1084 RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` 1085 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 1086 // Valid values are 1-6. 1087 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 1088 // RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it. 1089 RequireLastPushApproval *bool `json:"require_last_push_approval,omitempty"` 1090 } 1091 1092 // PullRequestReviewsEnforcementUpdate represents request to patch the pull request review 1093 // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementRequest above 1094 // because the patch request does not require all fields to be initialized. 1095 type PullRequestReviewsEnforcementUpdate struct { 1096 // Allow specific users, teams, or apps to bypass pull request requirements. 1097 BypassPullRequestAllowancesRequest *BypassPullRequestAllowancesRequest `json:"bypass_pull_request_allowances,omitempty"` 1098 // Specifies which users, teams and apps can dismiss pull request reviews. Can be omitted. 1099 DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` 1100 // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted. 1101 DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` 1102 // RequireCodeOwnerReviews specifies if merging pull requests is blocked until code owners have reviewed. 1103 RequireCodeOwnerReviews *bool `json:"require_code_owner_reviews,omitempty"` 1104 // RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged. 1105 // Valid values are 1 - 6 or 0 to not require reviewers. 1106 RequiredApprovingReviewCount int `json:"required_approving_review_count"` 1107 // RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it. 1108 RequireLastPushApproval *bool `json:"require_last_push_approval,omitempty"` 1109 } 1110 1111 // RequireLinearHistory represents the configuration to enforce branches with no merge commit. 1112 type RequireLinearHistory struct { 1113 Enabled bool `json:"enabled"` 1114 } 1115 1116 // AllowDeletions represents the configuration to accept deletion of protected branches. 1117 type AllowDeletions struct { 1118 Enabled bool `json:"enabled"` 1119 } 1120 1121 // AllowForcePushes represents the configuration to accept forced pushes on protected branches. 1122 type AllowForcePushes struct { 1123 Enabled bool `json:"enabled"` 1124 } 1125 1126 // RequiredConversationResolution, if enabled, requires all comments on the pull request to be resolved before it can be merged to a protected branch. 1127 type RequiredConversationResolution struct { 1128 Enabled bool `json:"enabled"` 1129 } 1130 1131 // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. 1132 type AdminEnforcement struct { 1133 URL *string `json:"url,omitempty"` 1134 Enabled bool `json:"enabled"` 1135 } 1136 1137 // BranchRestrictions represents the restriction that only certain users or 1138 // teams may push to a branch. 1139 type BranchRestrictions struct { 1140 // The list of user logins with push access. 1141 Users []*User `json:"users"` 1142 // The list of team slugs with push access. 1143 Teams []*Team `json:"teams"` 1144 // The list of app slugs with push access. 1145 Apps []*App `json:"apps"` 1146 } 1147 1148 // BranchRestrictionsRequest represents the request to create/edit the 1149 // restriction that only certain users or teams may push to a branch. It is 1150 // separate from BranchRestrictions above because the request structure is 1151 // different from the response structure. 1152 type BranchRestrictionsRequest struct { 1153 // The list of user logins with push access. (Required; use []string{} instead of nil for empty list.) 1154 Users []string `json:"users"` 1155 // The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.) 1156 Teams []string `json:"teams"` 1157 // The list of app slugs with push access. 1158 Apps []string `json:"apps"` 1159 } 1160 1161 // BypassPullRequestAllowances represents the people, teams, or apps who are allowed to bypass required pull requests. 1162 type BypassPullRequestAllowances struct { 1163 // The list of users allowed to bypass pull request requirements. 1164 Users []*User `json:"users"` 1165 // The list of teams allowed to bypass pull request requirements. 1166 Teams []*Team `json:"teams"` 1167 // The list of apps allowed to bypass pull request requirements. 1168 Apps []*App `json:"apps"` 1169 } 1170 1171 // BypassPullRequestAllowancesRequest represents the people, teams, or apps who are 1172 // allowed to bypass required pull requests. 1173 // It is separate from BypassPullRequestAllowances above because the request structure is 1174 // different from the response structure. 1175 type BypassPullRequestAllowancesRequest struct { 1176 // The list of user logins allowed to bypass pull request requirements. 1177 Users []string `json:"users"` 1178 // The list of team slugs allowed to bypass pull request requirements. 1179 Teams []string `json:"teams"` 1180 // The list of app slugs allowed to bypass pull request requirements. 1181 Apps []string `json:"apps"` 1182 } 1183 1184 // DismissalRestrictions specifies which users and teams can dismiss pull request reviews. 1185 type DismissalRestrictions struct { 1186 // The list of users who can dimiss pull request reviews. 1187 Users []*User `json:"users"` 1188 // The list of teams which can dismiss pull request reviews. 1189 Teams []*Team `json:"teams"` 1190 // The list of apps which can dismiss pull request reviews. 1191 Apps []*App `json:"apps"` 1192 } 1193 1194 // DismissalRestrictionsRequest represents the request to create/edit the 1195 // restriction to allows only specific users, teams or apps to dimiss pull request reviews. It is 1196 // separate from DismissalRestrictions above because the request structure is 1197 // different from the response structure. 1198 // Note: Both Users and Teams must be nil, or both must be non-nil. 1199 type DismissalRestrictionsRequest struct { 1200 // The list of user logins who can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 1201 Users *[]string `json:"users,omitempty"` 1202 // The list of team slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 1203 Teams *[]string `json:"teams,omitempty"` 1204 // The list of app slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.) 1205 Apps *[]string `json:"apps,omitempty"` 1206 } 1207 1208 // SignaturesProtectedBranch represents the protection status of an individual branch. 1209 type SignaturesProtectedBranch struct { 1210 URL *string `json:"url,omitempty"` 1211 // Commits pushed to matching branches must have verified signatures. 1212 Enabled *bool `json:"enabled,omitempty"` 1213 } 1214 1215 // ListBranches lists branches for the specified repository. 1216 // 1217 // GitHub API docs: https://docs.github.com/en/rest/branches/branches#list-branches 1218 func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opts *BranchListOptions) ([]*Branch, *Response, error) { 1219 u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) 1220 u, err := addOptions(u, opts) 1221 if err != nil { 1222 return nil, nil, err 1223 } 1224 1225 req, err := s.client.NewRequest("GET", u, nil) 1226 if err != nil { 1227 return nil, nil, err 1228 } 1229 1230 var branches []*Branch 1231 resp, err := s.client.Do(ctx, req, &branches) 1232 if err != nil { 1233 return nil, resp, err 1234 } 1235 1236 return branches, resp, nil 1237 } 1238 1239 // GetBranch gets the specified branch for a repository. 1240 // 1241 // GitHub API docs: https://docs.github.com/en/rest/branches/branches#get-a-branch 1242 func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string, followRedirects bool) (*Branch, *Response, error) { 1243 u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) 1244 1245 resp, err := s.client.roundTripWithOptionalFollowRedirect(ctx, u, followRedirects) 1246 if err != nil { 1247 return nil, nil, err 1248 } 1249 defer resp.Body.Close() 1250 1251 if resp.StatusCode != http.StatusOK { 1252 return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) 1253 } 1254 1255 b := new(Branch) 1256 err = json.NewDecoder(resp.Body).Decode(b) 1257 return b, newResponse(resp), err 1258 } 1259 1260 // renameBranchRequest represents a request to rename a branch. 1261 type renameBranchRequest struct { 1262 NewName string `json:"new_name"` 1263 } 1264 1265 // RenameBranch renames a branch in a repository. 1266 // 1267 // To rename a non-default branch: Users must have push access. GitHub Apps must have the `contents:write` repository permission. 1268 // To rename the default branch: Users must have admin or owner permissions. GitHub Apps must have the `administration:write` repository permission. 1269 // 1270 // GitHub API docs: https://docs.github.com/en/rest/branches/branches#rename-a-branch 1271 func (s *RepositoriesService) RenameBranch(ctx context.Context, owner, repo, branch, newName string) (*Branch, *Response, error) { 1272 u := fmt.Sprintf("repos/%v/%v/branches/%v/rename", owner, repo, branch) 1273 r := &renameBranchRequest{NewName: newName} 1274 req, err := s.client.NewRequest("POST", u, r) 1275 if err != nil { 1276 return nil, nil, err 1277 } 1278 1279 b := new(Branch) 1280 resp, err := s.client.Do(ctx, req, b) 1281 if err != nil { 1282 return nil, resp, err 1283 } 1284 1285 return b, resp, nil 1286 } 1287 1288 // GetBranchProtection gets the protection of a given branch. 1289 // 1290 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-branch-protection 1291 func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*Protection, *Response, error) { 1292 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1293 req, err := s.client.NewRequest("GET", u, nil) 1294 if err != nil { 1295 return nil, nil, err 1296 } 1297 1298 // TODO: remove custom Accept header when this API fully launches 1299 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1300 1301 p := new(Protection) 1302 resp, err := s.client.Do(ctx, req, p) 1303 if err != nil { 1304 if isBranchNotProtected(err) { 1305 err = ErrBranchNotProtected 1306 } 1307 return nil, resp, err 1308 } 1309 1310 return p, resp, nil 1311 } 1312 1313 // GetRequiredStatusChecks gets the required status checks for a given protected branch. 1314 // 1315 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-status-checks-protection 1316 func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) { 1317 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1318 req, err := s.client.NewRequest("GET", u, nil) 1319 if err != nil { 1320 return nil, nil, err 1321 } 1322 1323 p := new(RequiredStatusChecks) 1324 resp, err := s.client.Do(ctx, req, p) 1325 if err != nil { 1326 if isBranchNotProtected(err) { 1327 err = ErrBranchNotProtected 1328 } 1329 return nil, resp, err 1330 } 1331 1332 return p, resp, nil 1333 } 1334 1335 // ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch. 1336 // 1337 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-all-status-check-contexts 1338 func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) { 1339 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch) 1340 req, err := s.client.NewRequest("GET", u, nil) 1341 if err != nil { 1342 return nil, nil, err 1343 } 1344 1345 resp, err = s.client.Do(ctx, req, &contexts) 1346 if err != nil { 1347 if isBranchNotProtected(err) { 1348 err = ErrBranchNotProtected 1349 } 1350 return nil, resp, err 1351 } 1352 1353 return contexts, resp, nil 1354 } 1355 1356 // UpdateBranchProtection updates the protection of a given branch. 1357 // 1358 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-branch-protection 1359 func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, repo, branch string, preq *ProtectionRequest) (*Protection, *Response, error) { 1360 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1361 req, err := s.client.NewRequest("PUT", u, preq) 1362 if err != nil { 1363 return nil, nil, err 1364 } 1365 1366 // TODO: remove custom Accept header when this API fully launches 1367 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1368 1369 p := new(Protection) 1370 resp, err := s.client.Do(ctx, req, p) 1371 if err != nil { 1372 return nil, resp, err 1373 } 1374 1375 return p, resp, nil 1376 } 1377 1378 // RemoveBranchProtection removes the protection of a given branch. 1379 // 1380 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-branch-protection 1381 func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) { 1382 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch) 1383 req, err := s.client.NewRequest("DELETE", u, nil) 1384 if err != nil { 1385 return nil, err 1386 } 1387 1388 return s.client.Do(ctx, req, nil) 1389 } 1390 1391 // GetSignaturesProtectedBranch gets required signatures of protected branch. 1392 // 1393 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-commit-signature-protection 1394 func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { 1395 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1396 req, err := s.client.NewRequest("GET", u, nil) 1397 if err != nil { 1398 return nil, nil, err 1399 } 1400 1401 // TODO: remove custom Accept header when this API fully launches 1402 req.Header.Set("Accept", mediaTypeSignaturePreview) 1403 1404 p := new(SignaturesProtectedBranch) 1405 resp, err := s.client.Do(ctx, req, p) 1406 if err != nil { 1407 return nil, resp, err 1408 } 1409 1410 return p, resp, nil 1411 } 1412 1413 // RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch. 1414 // It requires admin access and branch protection to be enabled. 1415 // 1416 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#create-commit-signature-protection 1417 func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) { 1418 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1419 req, err := s.client.NewRequest("POST", u, nil) 1420 if err != nil { 1421 return nil, nil, err 1422 } 1423 1424 // TODO: remove custom Accept header when this API fully launches 1425 req.Header.Set("Accept", mediaTypeSignaturePreview) 1426 1427 r := new(SignaturesProtectedBranch) 1428 resp, err := s.client.Do(ctx, req, r) 1429 if err != nil { 1430 return nil, resp, err 1431 } 1432 1433 return r, resp, nil 1434 } 1435 1436 // OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch. 1437 // 1438 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-commit-signature-protection 1439 func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) { 1440 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch) 1441 req, err := s.client.NewRequest("DELETE", u, nil) 1442 if err != nil { 1443 return nil, err 1444 } 1445 1446 // TODO: remove custom Accept header when this API fully launches 1447 req.Header.Set("Accept", mediaTypeSignaturePreview) 1448 1449 return s.client.Do(ctx, req, nil) 1450 } 1451 1452 // UpdateRequiredStatusChecks updates the required status checks for a given protected branch. 1453 // 1454 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-status-check-protection 1455 func (s *RepositoriesService) UpdateRequiredStatusChecks(ctx context.Context, owner, repo, branch string, sreq *RequiredStatusChecksRequest) (*RequiredStatusChecks, *Response, error) { 1456 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1457 req, err := s.client.NewRequest("PATCH", u, sreq) 1458 if err != nil { 1459 return nil, nil, err 1460 } 1461 1462 sc := new(RequiredStatusChecks) 1463 resp, err := s.client.Do(ctx, req, sc) 1464 if err != nil { 1465 return nil, resp, err 1466 } 1467 1468 return sc, resp, nil 1469 } 1470 1471 // RemoveRequiredStatusChecks removes the required status checks for a given protected branch. 1472 // 1473 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-status-check-protection 1474 func (s *RepositoriesService) RemoveRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*Response, error) { 1475 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch) 1476 req, err := s.client.NewRequest("DELETE", u, nil) 1477 if err != nil { 1478 return nil, err 1479 } 1480 1481 return s.client.Do(ctx, req, nil) 1482 } 1483 1484 // License gets the contents of a repository's license if one is detected. 1485 // 1486 // GitHub API docs: https://docs.github.com/en/rest/licenses#get-the-license-for-a-repository 1487 func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) { 1488 u := fmt.Sprintf("repos/%v/%v/license", owner, repo) 1489 req, err := s.client.NewRequest("GET", u, nil) 1490 if err != nil { 1491 return nil, nil, err 1492 } 1493 1494 r := &RepositoryLicense{} 1495 resp, err := s.client.Do(ctx, req, r) 1496 if err != nil { 1497 return nil, resp, err 1498 } 1499 1500 return r, resp, nil 1501 } 1502 1503 // GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch. 1504 // 1505 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-pull-request-review-protection 1506 func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { 1507 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1508 req, err := s.client.NewRequest("GET", u, nil) 1509 if err != nil { 1510 return nil, nil, err 1511 } 1512 1513 // TODO: remove custom Accept header when this API fully launches 1514 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1515 1516 r := new(PullRequestReviewsEnforcement) 1517 resp, err := s.client.Do(ctx, req, r) 1518 if err != nil { 1519 return nil, resp, err 1520 } 1521 1522 return r, resp, nil 1523 } 1524 1525 // UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch. 1526 // It requires admin access and branch protection to be enabled. 1527 // 1528 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-pull-request-review-protection 1529 func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { 1530 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1531 req, err := s.client.NewRequest("PATCH", u, patch) 1532 if err != nil { 1533 return nil, nil, err 1534 } 1535 1536 // TODO: remove custom Accept header when this API fully launches 1537 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1538 1539 r := new(PullRequestReviewsEnforcement) 1540 resp, err := s.client.Do(ctx, req, r) 1541 if err != nil { 1542 return nil, resp, err 1543 } 1544 1545 return r, resp, nil 1546 } 1547 1548 // DisableDismissalRestrictions disables dismissal restrictions of a protected branch. 1549 // It requires admin access and branch protection to be enabled. 1550 // 1551 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#update-pull-request-review-protection 1552 func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { 1553 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1554 1555 data := new(struct { 1556 DismissalRestrictionsRequest `json:"dismissal_restrictions"` 1557 }) 1558 1559 req, err := s.client.NewRequest("PATCH", u, data) 1560 if err != nil { 1561 return nil, nil, err 1562 } 1563 1564 // TODO: remove custom Accept header when this API fully launches 1565 req.Header.Set("Accept", mediaTypeRequiredApprovingReviewsPreview) 1566 1567 r := new(PullRequestReviewsEnforcement) 1568 resp, err := s.client.Do(ctx, req, r) 1569 if err != nil { 1570 return nil, resp, err 1571 } 1572 1573 return r, resp, nil 1574 } 1575 1576 // RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. 1577 // 1578 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-pull-request-review-protection 1579 func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { 1580 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) 1581 req, err := s.client.NewRequest("DELETE", u, nil) 1582 if err != nil { 1583 return nil, err 1584 } 1585 1586 return s.client.Do(ctx, req, nil) 1587 } 1588 1589 // GetAdminEnforcement gets admin enforcement information of a protected branch. 1590 // 1591 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-admin-branch-protection 1592 func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { 1593 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1594 req, err := s.client.NewRequest("GET", u, nil) 1595 if err != nil { 1596 return nil, nil, err 1597 } 1598 1599 r := new(AdminEnforcement) 1600 resp, err := s.client.Do(ctx, req, r) 1601 if err != nil { 1602 return nil, resp, err 1603 } 1604 1605 return r, resp, nil 1606 } 1607 1608 // AddAdminEnforcement adds admin enforcement to a protected branch. 1609 // It requires admin access and branch protection to be enabled. 1610 // 1611 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-admin-branch-protection 1612 func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { 1613 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1614 req, err := s.client.NewRequest("POST", u, nil) 1615 if err != nil { 1616 return nil, nil, err 1617 } 1618 1619 r := new(AdminEnforcement) 1620 resp, err := s.client.Do(ctx, req, r) 1621 if err != nil { 1622 return nil, resp, err 1623 } 1624 1625 return r, resp, nil 1626 } 1627 1628 // RemoveAdminEnforcement removes admin enforcement from a protected branch. 1629 // 1630 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#delete-admin-branch-protection 1631 func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { 1632 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) 1633 req, err := s.client.NewRequest("DELETE", u, nil) 1634 if err != nil { 1635 return nil, err 1636 } 1637 1638 return s.client.Do(ctx, req, nil) 1639 } 1640 1641 // repositoryTopics represents a collection of repository topics. 1642 type repositoryTopics struct { 1643 Names []string `json:"names"` 1644 } 1645 1646 // ListAllTopics lists topics for a repository. 1647 // 1648 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#get-all-repository-topics 1649 func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) { 1650 u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) 1651 req, err := s.client.NewRequest("GET", u, nil) 1652 if err != nil { 1653 return nil, nil, err 1654 } 1655 1656 // TODO: remove custom Accept header when this API fully launches. 1657 req.Header.Set("Accept", mediaTypeTopicsPreview) 1658 1659 topics := new(repositoryTopics) 1660 resp, err := s.client.Do(ctx, req, topics) 1661 if err != nil { 1662 return nil, resp, err 1663 } 1664 1665 return topics.Names, resp, nil 1666 } 1667 1668 // ReplaceAllTopics replaces all repository topics. 1669 // 1670 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#replace-all-repository-topics 1671 func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) { 1672 u := fmt.Sprintf("repos/%v/%v/topics", owner, repo) 1673 t := &repositoryTopics{ 1674 Names: topics, 1675 } 1676 if t.Names == nil { 1677 t.Names = []string{} 1678 } 1679 req, err := s.client.NewRequest("PUT", u, t) 1680 if err != nil { 1681 return nil, nil, err 1682 } 1683 1684 // TODO: remove custom Accept header when this API fully launches. 1685 req.Header.Set("Accept", mediaTypeTopicsPreview) 1686 1687 t = new(repositoryTopics) 1688 resp, err := s.client.Do(ctx, req, t) 1689 if err != nil { 1690 return nil, resp, err 1691 } 1692 1693 return t.Names, resp, nil 1694 } 1695 1696 // ListApps lists the GitHub apps that have push access to a given protected branch. 1697 // It requires the GitHub apps to have `write` access to the `content` permission. 1698 // 1699 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch 1700 // 1701 // Deprecated: Please use ListAppRestrictions instead. 1702 func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { 1703 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1704 req, err := s.client.NewRequest("GET", u, nil) 1705 if err != nil { 1706 return nil, nil, err 1707 } 1708 1709 var apps []*App 1710 resp, err := s.client.Do(ctx, req, &apps) 1711 if err != nil { 1712 return nil, resp, err 1713 } 1714 1715 return apps, resp, nil 1716 } 1717 1718 // ListAppRestrictions lists the GitHub apps that have push access to a given protected branch. 1719 // It requires the GitHub apps to have `write` access to the `content` permission. 1720 // 1721 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch 1722 // 1723 // Note: This is a wrapper around ListApps so a naming convention with ListUserRestrictions and ListTeamRestrictions is preserved. 1724 func (s *RepositoriesService) ListAppRestrictions(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) { 1725 return s.ListApps(ctx, owner, repo, branch) 1726 } 1727 1728 // ReplaceAppRestrictions replaces the apps that have push access to a given protected branch. 1729 // It removes all apps that previously had push access and grants push access to the new list of apps. 1730 // It requires the GitHub apps to have `write` access to the `content` permission. 1731 // 1732 // Note: The list of users, apps, and teams in total is limited to 100 items. 1733 // 1734 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-app-access-restrictions 1735 func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) { 1736 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1737 req, err := s.client.NewRequest("PUT", u, apps) 1738 if err != nil { 1739 return nil, nil, err 1740 } 1741 1742 var newApps []*App 1743 resp, err := s.client.Do(ctx, req, &newApps) 1744 if err != nil { 1745 return nil, resp, err 1746 } 1747 1748 return newApps, resp, nil 1749 } 1750 1751 // AddAppRestrictions grants the specified apps push access to a given protected branch. 1752 // It requires the GitHub apps to have `write` access to the `content` permission. 1753 // 1754 // Note: The list of users, apps, and teams in total is limited to 100 items. 1755 // 1756 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-app-access-restrictions 1757 func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) { 1758 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1759 req, err := s.client.NewRequest("POST", u, apps) 1760 if err != nil { 1761 return nil, nil, err 1762 } 1763 1764 var newApps []*App 1765 resp, err := s.client.Do(ctx, req, &newApps) 1766 if err != nil { 1767 return nil, resp, err 1768 } 1769 1770 return newApps, resp, nil 1771 } 1772 1773 // RemoveAppRestrictions removes the restrictions of an app from pushing to this branch. 1774 // It requires the GitHub apps to have `write` access to the `content` permission. 1775 // 1776 // Note: The list of users, apps, and teams in total is limited to 100 items. 1777 // 1778 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-app-access-restrictions 1779 func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) { 1780 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch) 1781 req, err := s.client.NewRequest("DELETE", u, apps) 1782 if err != nil { 1783 return nil, nil, err 1784 } 1785 1786 var newApps []*App 1787 resp, err := s.client.Do(ctx, req, &newApps) 1788 if err != nil { 1789 return nil, resp, err 1790 } 1791 1792 return newApps, resp, nil 1793 } 1794 1795 // ListTeamRestrictions lists the GitHub teams that have push access to a given protected branch. 1796 // It requires the GitHub teams to have `write` access to the `content` permission. 1797 // 1798 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-teams-with-access-to-the-protected-branch 1799 func (s *RepositoriesService) ListTeamRestrictions(ctx context.Context, owner, repo, branch string) ([]*Team, *Response, error) { 1800 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1801 req, err := s.client.NewRequest("GET", u, nil) 1802 if err != nil { 1803 return nil, nil, err 1804 } 1805 1806 var teams []*Team 1807 resp, err := s.client.Do(ctx, req, &teams) 1808 if err != nil { 1809 return nil, resp, err 1810 } 1811 1812 return teams, resp, nil 1813 } 1814 1815 // ReplaceTeamRestrictions replaces the team that have push access to a given protected branch. 1816 // This removes all teams that previously had push access and grants push access to the new list of teams. 1817 // It requires the GitHub teams to have `write` access to the `content` permission. 1818 // 1819 // Note: The list of users, apps, and teams in total is limited to 100 items. 1820 // 1821 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-team-access-restrictions 1822 func (s *RepositoriesService) ReplaceTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) { 1823 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1824 req, err := s.client.NewRequest("PUT", u, teams) 1825 if err != nil { 1826 return nil, nil, err 1827 } 1828 1829 var newTeams []*Team 1830 resp, err := s.client.Do(ctx, req, &newTeams) 1831 if err != nil { 1832 return nil, resp, err 1833 } 1834 1835 return newTeams, resp, nil 1836 } 1837 1838 // AddTeamRestrictions grants the specified teams push access to a given protected branch. 1839 // It requires the GitHub teams to have `write` access to the `content` permission. 1840 // 1841 // Note: The list of users, apps, and teams in total is limited to 100 items. 1842 // 1843 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-team-access-restrictions 1844 func (s *RepositoriesService) AddTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) { 1845 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1846 req, err := s.client.NewRequest("POST", u, teams) 1847 if err != nil { 1848 return nil, nil, err 1849 } 1850 1851 var newTeams []*Team 1852 resp, err := s.client.Do(ctx, req, &newTeams) 1853 if err != nil { 1854 return nil, resp, err 1855 } 1856 1857 return newTeams, resp, nil 1858 } 1859 1860 // RemoveTeamRestrictions removes the restrictions of a team from pushing to this branch. 1861 // It requires the GitHub teams to have `write` access to the `content` permission. 1862 // 1863 // Note: The list of users, apps, and teams in total is limited to 100 items. 1864 // 1865 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-team-access-restrictions 1866 func (s *RepositoriesService) RemoveTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) { 1867 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch) 1868 req, err := s.client.NewRequest("DELETE", u, teams) 1869 if err != nil { 1870 return nil, nil, err 1871 } 1872 1873 var newTeams []*Team 1874 resp, err := s.client.Do(ctx, req, &newTeams) 1875 if err != nil { 1876 return nil, resp, err 1877 } 1878 1879 return newTeams, resp, nil 1880 } 1881 1882 // ListUserRestrictions lists the GitHub users that have push access to a given protected branch. 1883 // It requires the GitHub users to have `write` access to the `content` permission. 1884 // 1885 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-users-with-access-to-the-protected-branch 1886 func (s *RepositoriesService) ListUserRestrictions(ctx context.Context, owner, repo, branch string) ([]*User, *Response, error) { 1887 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1888 req, err := s.client.NewRequest("GET", u, nil) 1889 if err != nil { 1890 return nil, nil, err 1891 } 1892 1893 var users []*User 1894 resp, err := s.client.Do(ctx, req, &users) 1895 if err != nil { 1896 return nil, resp, err 1897 } 1898 1899 return users, resp, nil 1900 } 1901 1902 // ReplaceUserRestrictions replaces the user that have push access to a given protected branch. 1903 // It removes all users that previously had push access and grants push access to the new list of users. 1904 // It requires the GitHub users to have `write` access to the `content` permission. 1905 // 1906 // Note: The list of users, apps, and teams in total is limited to 100 items. 1907 // 1908 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-team-access-restrictions 1909 func (s *RepositoriesService) ReplaceUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) { 1910 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1911 req, err := s.client.NewRequest("PUT", u, users) 1912 if err != nil { 1913 return nil, nil, err 1914 } 1915 1916 var newUsers []*User 1917 resp, err := s.client.Do(ctx, req, &newUsers) 1918 if err != nil { 1919 return nil, resp, err 1920 } 1921 1922 return newUsers, resp, nil 1923 } 1924 1925 // AddUserRestrictions grants the specified users push access to a given protected branch. 1926 // It requires the GitHub users to have `write` access to the `content` permission. 1927 // 1928 // Note: The list of users, apps, and teams in total is limited to 100 items. 1929 // 1930 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-team-access-restrictions 1931 func (s *RepositoriesService) AddUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) { 1932 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1933 req, err := s.client.NewRequest("POST", u, users) 1934 if err != nil { 1935 return nil, nil, err 1936 } 1937 1938 var newUsers []*User 1939 resp, err := s.client.Do(ctx, req, &newUsers) 1940 if err != nil { 1941 return nil, resp, err 1942 } 1943 1944 return newUsers, resp, nil 1945 } 1946 1947 // RemoveUserRestrictions removes the restrictions of a user from pushing to this branch. 1948 // It requires the GitHub users to have `write` access to the `content` permission. 1949 // 1950 // Note: The list of users, apps, and teams in total is limited to 100 items. 1951 // 1952 // GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-team-access-restrictions 1953 func (s *RepositoriesService) RemoveUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) { 1954 u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch) 1955 req, err := s.client.NewRequest("DELETE", u, users) 1956 if err != nil { 1957 return nil, nil, err 1958 } 1959 1960 var newUsers []*User 1961 resp, err := s.client.Do(ctx, req, &newUsers) 1962 if err != nil { 1963 return nil, resp, err 1964 } 1965 1966 return newUsers, resp, nil 1967 } 1968 1969 // TransferRequest represents a request to transfer a repository. 1970 type TransferRequest struct { 1971 NewOwner string `json:"new_owner"` 1972 TeamID []int64 `json:"team_ids,omitempty"` 1973 } 1974 1975 // Transfer transfers a repository from one account or organization to another. 1976 // 1977 // This method might return an *AcceptedError and a status code of 1978 // 202. This is because this is the status that GitHub returns to signify that 1979 // it has now scheduled the transfer of the repository in a background task. 1980 // A follow up request, after a delay of a second or so, should result 1981 // in a successful request. 1982 // 1983 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#transfer-a-repository 1984 func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, transfer TransferRequest) (*Repository, *Response, error) { 1985 u := fmt.Sprintf("repos/%v/%v/transfer", owner, repo) 1986 1987 req, err := s.client.NewRequest("POST", u, &transfer) 1988 if err != nil { 1989 return nil, nil, err 1990 } 1991 1992 r := new(Repository) 1993 resp, err := s.client.Do(ctx, req, r) 1994 if err != nil { 1995 return nil, resp, err 1996 } 1997 1998 return r, resp, nil 1999 } 2000 2001 // DispatchRequestOptions represents a request to trigger a repository_dispatch event. 2002 type DispatchRequestOptions struct { 2003 // EventType is a custom webhook event name. (Required.) 2004 EventType string `json:"event_type"` 2005 // ClientPayload is a custom JSON payload with extra information about the webhook event. 2006 // Defaults to an empty JSON object. 2007 ClientPayload *json.RawMessage `json:"client_payload,omitempty"` 2008 } 2009 2010 // Dispatch triggers a repository_dispatch event in a GitHub Actions workflow. 2011 // 2012 // GitHub API docs: https://docs.github.com/en/rest/repos/repos#create-a-repository-dispatch-event 2013 func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) { 2014 u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo) 2015 2016 req, err := s.client.NewRequest("POST", u, &opts) 2017 if err != nil { 2018 return nil, nil, err 2019 } 2020 2021 r := new(Repository) 2022 resp, err := s.client.Do(ctx, req, r) 2023 if err != nil { 2024 return nil, resp, err 2025 } 2026 2027 return r, resp, nil 2028 } 2029 2030 // isBranchNotProtected determines whether a branch is not protected 2031 // based on the error message returned by GitHub API. 2032 func isBranchNotProtected(err error) bool { 2033 errorResponse, ok := err.(*ErrorResponse) 2034 return ok && errorResponse.Message == githubBranchNotProtected 2035 }