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