Repository: google/go-github
Pull request #1471 (2020-03-24 14:42:14)

Implement support for repository visibility parameter
Implements support for specifying a repositories visibility. It can be
one of public, private or internal (if the organization is associated
with an enterprise account).

The associated preview header (nebula) has also been added.

Resolves: #1470 

codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=h1) Report
> Merging [#1471](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=desc) into [master](https://codecov.io/gh/google/go-github/commit/7726a3e3e3b67ab86c97198c8d682b09108a27b7&el=desc) will **increase** coverage by `5.10%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/google/go-github/pull/1471/graphs/tree.svg?width=650&height=150&src=pr&token=EgYjGjZlI0)](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1471      +/-   ##
==========================================
+ Coverage   68.16%   73.27%   +5.10%     
==========================================
  Files          94       94              
  Lines        8419     6784    -1635     
==========================================
- Hits         5739     4971     -768     
+ Misses       1819      952     -867     
  Partials      861      861              
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [github/github.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL2dpdGh1Yi5nbw==) | `89.74% <ø> (-0.03%)` | :arrow_down: |
| [github/repos.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL3JlcG9zLmdv) | `74.60% <100.00%> (+4.93%)` | :arrow_up: |
| [github/admin.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL2FkbWluLmdv) | `100.00% <0.00%> (ø)` | |
| [github/strings.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL3N0cmluZ3MuZ28=) | `100.00% <0.00%> (ø)` | |
| [github/activity.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL2FjdGl2aXR5Lmdv) | `100.00% <0.00%> (ø)` | |
| [github/timestamp.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL3RpbWVzdGFtcC5nbw==) | `100.00% <0.00%> (ø)` | |
| [github/admin\_stats.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL2FkbWluX3N0YXRzLmdv) | `100.00% <0.00%> (ø)` | |
| [github/repos\_traffic.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL3JlcG9zX3RyYWZmaWMuZ28=) | `100.00% <0.00%> (ø)` | |
| [github/pulls\_reviewers.go](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree#diff-Z2l0aHViL3B1bGxzX3Jldmlld2Vycy5nbw==) | `100.00% <0.00%> (ø)` | |
| ... and [83 more](https://codecov.io/gh/google/go-github/pull/1471/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=footer). Last update [7726a3e...c414f9d](https://codecov.io/gh/google/go-github/pull/1471?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

patrickmarabeas: What is the release cadence for this project - I would like to put this to use in the Github Terraform Provider ASAP!
gmlewis: We used to do a semver (major, minor, patch) release on each merged PR, but that got way too extreme... so now we release on demand.  I can make a new release after this PR is merged.
patrickmarabeas: That would be great - thanks @gmlewis!
gmlewis: Thank you, @wesleimp!
Merging, then making a minor release.

Patch:
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 519123cd..27e8b136 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.go b/github/github.go
index 15715cf0..c9bdff55 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 bce3c942..41249226 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 {


Test patch:
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index b85d3a62..df474203 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/repos_test.go b/github/repos_test.go
index d1c60cb0..889a8fc8 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)
 		}