diff --git a/github/github-accessors.go b/github/github-accessors.go index 519123cdcf..27e8b136ca 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -10708,6 +10708,14 @@ func (r *Repository) GetURL() string { return *r.URL } +// GetVisibility returns the Visibility field if it's non-nil, zero value otherwise. +func (r *Repository) GetVisibility() string { + if r == nil || r.Visibility == nil { + return "" + } + return *r.Visibility +} + // GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise. func (r *Repository) GetWatchersCount() int { if r == nil || r.WatchersCount == nil { diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index b85d3a62c3..df47420330 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1301,8 +1301,9 @@ func TestRepository_String(t *testing.T) { TagsURL: String(""), TreesURL: String(""), TeamsURL: String(""), + Visibility: String(""), } - want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}` + want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:"", Visibility:""}` if got := v.String(); got != want { t.Errorf("Repository.String = %v, want %v", got, want) } diff --git a/github/github.go b/github/github.go index 15715cf0a9..c9bdff55f3 100644 --- a/github/github.go +++ b/github/github.go @@ -138,6 +138,9 @@ const ( // https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/ mediaTypeOAuthAppPreview = "application/vnd.github.doctor-strange-preview+json" + + // https://developer.github.com/changes/2019-12-03-internal-visibility-changes/ + mediaTypeRepositoryVisibilityPreview = "application/vnd.github.nebula-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/repos.go b/github/repos.go index bce3c94274..41249226d1 100644 --- a/github/repos.go +++ b/github/repos.go @@ -121,6 +121,11 @@ type Repository struct { // TextMatches is only populated from search results that request text matches // See: search.go and https://developer.github.com/v3/search/#text-match-metadata TextMatches []*TextMatch `json:"text_matches,omitempty"` + + // Visibility is only used for Create and Edit endpoints. The visibility field + // overrides the field parameter when both are used. + // Can be one of public, private or internal. + Visibility *string `json:"visibility,omitempty"` } func (r Repository) String() string { @@ -295,11 +300,12 @@ type createRepoRequest struct { Description *string `json:"description,omitempty"` Homepage *string `json:"homepage,omitempty"` - Private *bool `json:"private,omitempty"` - HasIssues *bool `json:"has_issues,omitempty"` - HasProjects *bool `json:"has_projects,omitempty"` - HasWiki *bool `json:"has_wiki,omitempty"` - IsTemplate *bool `json:"is_template,omitempty"` + Private *bool `json:"private,omitempty"` + Visibility *string `json:"visibility,omitempty"` + HasIssues *bool `json:"has_issues,omitempty"` + HasProjects *bool `json:"has_projects,omitempty"` + HasWiki *bool `json:"has_wiki,omitempty"` + IsTemplate *bool `json:"is_template,omitempty"` // Creating an organization repository. Required for non-owners. TeamID *int64 `json:"team_id,omitempty"` @@ -334,6 +340,7 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo Description: repo.Description, Homepage: repo.Homepage, Private: repo.Private, + Visibility: repo.Visibility, HasIssues: repo.HasIssues, HasProjects: repo.HasProjects, HasWiki: repo.HasWiki, @@ -353,7 +360,8 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo return nil, nil, err } - req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) + acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { @@ -469,7 +477,8 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo return nil, nil, err } - req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview) + acceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) r := new(Repository) resp, err := s.client.Do(ctx, req, r) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index d1c60cb010..889a8fc8dd 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -251,12 +251,13 @@ func TestRepositoriesService_Create_user(t *testing.T) { Archived: Bool(true), // not passed along. } + wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { v := new(createRepoRequest) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) want := &createRepoRequest{Name: String("n")} if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) @@ -313,12 +314,13 @@ func TestRepositoriesService_Create_org(t *testing.T) { Archived: Bool(true), // not passed along. } + wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) { v := new(createRepoRequest) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") - testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) want := &createRepoRequest{Name: String("n")} if !reflect.DeepEqual(v, want) { t.Errorf("Request body = %+v, want %+v", v, want) @@ -551,12 +553,13 @@ func TestRepositoriesService_Edit(t *testing.T) { i := true input := &Repository{HasIssues: &i} + wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { v := new(Repository) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") - testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) + testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) }