...

Source file src/github.com/google/go-github/v55/github/repos.go

Documentation: github.com/google/go-github/v55/github

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

View as plain text