Repository: google/go-github
Pull request #1079 (2018-12-21 19:39:27)

Adding the new Interactions API support for repositories
Created files based on the `{service}_{api}.go` format i.e `interactions_repos.go`.

API response for repository interactions and organisation interactions is same so I've abstracted the `Interaction` struct in `interactions.go`.

This PR adds the API's to `GetRestrictions`, `UpdateRestrictions` and `RemoveRestrictions` for a given repository.


Patch:
diff --git a/README.md b/README.md
index 18c54e9f..32c586ff 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is
 ## Usage ##
 
 ```go
-import "github.com/google/go-github/v20/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
+import "github.com/google/go-github/v21/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
 import "github.com/google/go-github/github" // with go modules disabled
 ```
 
diff --git a/example/appengine/app.go b/example/appengine/app.go
index f36eaa0c..df8b6b4c 100644
--- a/example/appengine/app.go
+++ b/example/appengine/app.go
@@ -12,7 +12,7 @@ import (
 	"net/http"
 	"os"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 	"golang.org/x/oauth2"
 	"google.golang.org/appengine"
 	"google.golang.org/appengine/log"
diff --git a/example/basicauth/main.go b/example/basicauth/main.go
index fb0fdbf8..a5c33a4e 100644
--- a/example/basicauth/main.go
+++ b/example/basicauth/main.go
@@ -16,7 +16,7 @@ import (
 	"strings"
 	"syscall"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 	"golang.org/x/crypto/ssh/terminal"
 )
 
diff --git a/example/commitpr/main.go b/example/commitpr/main.go
index 7ebd3f0b..2ef30dfa 100644
--- a/example/commitpr/main.go
+++ b/example/commitpr/main.go
@@ -31,7 +31,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/example/migrations/main.go b/example/migrations/main.go
index dfeb7adf..dfba5c0c 100644
--- a/example/migrations/main.go
+++ b/example/migrations/main.go
@@ -12,7 +12,7 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/example/newrepo/main.go b/example/newrepo/main.go
index e2f30f74..71a4b6a5 100644
--- a/example/newrepo/main.go
+++ b/example/newrepo/main.go
@@ -16,7 +16,7 @@ import (
 	"log"
 	"os"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/example/simple/main.go b/example/simple/main.go
index 2468a546..45aadfa9 100644
--- a/example/simple/main.go
+++ b/example/simple/main.go
@@ -12,7 +12,7 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 )
 
 // Fetch all the public organizations' membership of a user.
diff --git a/github/github-accessors.go b/github/github-accessors.go
index ac4257ea..5fa9d3a3 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -3612,6 +3612,30 @@ func (i *InstallationToken) GetToken() string {
 	return *i.Token
 }
 
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (i *InteractionRestriction) GetExpiresAt() Timestamp {
+	if i == nil || i.ExpiresAt == nil {
+		return Timestamp{}
+	}
+	return *i.ExpiresAt
+}
+
+// GetLimit returns the Limit field if it's non-nil, zero value otherwise.
+func (i *InteractionRestriction) GetLimit() string {
+	if i == nil || i.Limit == nil {
+		return ""
+	}
+	return *i.Limit
+}
+
+// GetOrigin returns the Origin field if it's non-nil, zero value otherwise.
+func (i *InteractionRestriction) GetOrigin() string {
+	if i == nil || i.Origin == nil {
+		return ""
+	}
+	return *i.Origin
+}
+
 // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
 func (i *Invitation) GetCreatedAt() time.Time {
 	if i == nil || i.CreatedAt == nil {
diff --git a/github/github.go b/github/github.go
index 19ffecc7..7c0c2c1a 100644
--- a/github/github.go
+++ b/github/github.go
@@ -125,6 +125,9 @@ const (
 
 	// https://developer.github.com/changes/2018-09-05-project-card-events/
 	mediaTypeProjectCardDetailsPreview = "application/vnd.github.starfox-preview+json"
+
+	// https://developer.github.com/changes/2018-12-18-interactions-preview/
+	mediaTypeRepositoryInteractionsPreview = "application/vnd.github.sombra-preview+json"
 )
 
 // A Client manages communication with the GitHub API.
@@ -157,6 +160,7 @@ type Client struct {
 	Gists          *GistsService
 	Git            *GitService
 	Gitignores     *GitignoresService
+	Interactions   *InteractionsService
 	Issues         *IssuesService
 	Licenses       *LicensesService
 	Marketplace    *MarketplaceService
@@ -249,6 +253,7 @@ func NewClient(httpClient *http.Client) *Client {
 	c.Gists = (*GistsService)(&c.common)
 	c.Git = (*GitService)(&c.common)
 	c.Gitignores = (*GitignoresService)(&c.common)
+	c.Interactions = (*InteractionsService)(&c.common)
 	c.Issues = (*IssuesService)(&c.common)
 	c.Licenses = (*LicensesService)(&c.common)
 	c.Marketplace = &MarketplaceService{client: c}
diff --git a/github/interactions.go b/github/interactions.go
new file mode 100644
index 00000000..b9965491
--- /dev/null
+++ b/github/interactions.go
@@ -0,0 +1,28 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+// InteractionsService handles communication with the repository and organization related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/
+type InteractionsService service
+
+// InteractionRestriction represents the interaction restrictions for repository and organization.
+type InteractionRestriction struct {
+	// Specifies the group of GitHub users who can
+	// comment, open issues, or create pull requests for the given repository.
+	// Possible values are: "existing_users", "contributors_only" and "collaborators_only".
+	Limit *string `json:"limit,omitempty"`
+
+	// Origin specifies the type of the resource to interact with.
+	// Possible values are: "repository" and "organization".
+	Origin *string `json:"origin,omitempty"`
+
+	// ExpiresAt specifies the time after which the interaction restrictions expire.
+	// The default expiry time is 24 hours from the time restriction is created.
+	ExpiresAt *Timestamp `json:"expires_at,omitempty"`
+}
diff --git a/github/interactions_repos.go b/github/interactions_repos.go
new file mode 100644
index 00000000..a9b553b6
--- /dev/null
+++ b/github/interactions_repos.go
@@ -0,0 +1,73 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// GetRestrictions fetches the interaction restrictions for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/repos/#get-interaction-restrictions-for-a-repository
+func (s *InteractionsService) GetRestrictions(ctx context.Context, owner, repo string) (*InteractionRestriction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInteractionsPreview)
+
+	repositoryInteractions := new(InteractionRestriction)
+
+	resp, err := s.client.Do(ctx, req, repositoryInteractions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repositoryInteractions, resp, nil
+}
+
+// UpdateRestrictions adds or updates the interaction restrictions for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/repos/#add-or-update-interaction-restrictions-for-a-repository
+func (s *InteractionsService) UpdateRestrictions(ctx context.Context, owner, repo string, interaction *InteractionRestriction) (*InteractionRestriction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, interaction)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInteractionsPreview)
+
+	repositoryInteractions := new(InteractionRestriction)
+
+	resp, err := s.client.Do(ctx, req, repositoryInteractions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repositoryInteractions, resp, nil
+}
+
+// RemoveRestrictions removes the interaction restrictions for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/interactions/repos/#remove-interaction-restrictions-for-a-repository
+func (s *InteractionsService) RemoveRestrictions(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInteractionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
diff --git a/github/repos.go b/github/repos.go
index d09b5cc8..617c20db 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -179,7 +179,7 @@ func (s *RepositoriesService) List(ctx context.Context, user string, opt *Reposi
 	}
 
 	// TODO: remove custom Accept headers when APIs fully launch.
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeTopicsPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var repos []*Repository
@@ -217,7 +217,7 @@ func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *Re
 	}
 
 	// TODO: remove custom Accept headers when APIs fully launch.
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeTopicsPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var repos []*Repository
diff --git a/go.mod b/go.mod
index 1e327b41..e892bae7 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/google/go-github/v20
+module github.com/google/go-github/v21
 
 require (
 	github.com/golang/protobuf v1.2.0 // indirect


Test patch:
diff --git a/github/examples_test.go b/github/examples_test.go
index 5ef43ced..7971769c 100644
--- a/github/examples_test.go
+++ b/github/examples_test.go
@@ -12,7 +12,7 @@ import (
 	"fmt"
 	"log"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 )
 
 func ExampleClient_Markdown() {
diff --git a/github/interactions_repos_test.go b/github/interactions_repos_test.go
new file mode 100644
index 00000000..c1c88b56
--- /dev/null
+++ b/github/interactions_repos_test.go
@@ -0,0 +1,80 @@
+// Copyright 2018 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"reflect"
+	"testing"
+)
+
+func TestInteractionsService_GetRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/interaction-limits", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeRepositoryInteractionsPreview)
+		fmt.Fprint(w, `{"origin":"repository"}`)
+	})
+
+	repoInteractions, _, err := client.Interactions.GetRestrictions(context.Background(), "o", "r")
+	if err != nil {
+		t.Errorf("Interactions.GetRestrictions returned error: %v", err)
+	}
+
+	want := &InteractionRestriction{Origin: String("repository")}
+	if !reflect.DeepEqual(repoInteractions, want) {
+		t.Errorf("Interactions.GetRestrictions returned %+v, want %+v", repoInteractions, want)
+	}
+}
+
+func TestInteractionsService_UpdateRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := &InteractionRestriction{Limit: String("existing_users")}
+
+	mux.HandleFunc("/repos/o/r/interaction-limits", func(w http.ResponseWriter, r *http.Request) {
+		v := new(InteractionRestriction)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "PUT")
+		testHeader(t, r, "Accept", mediaTypeRepositoryInteractionsPreview)
+		if !reflect.DeepEqual(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+		fmt.Fprint(w, `{"origin":"repository"}`)
+	})
+
+	repoInteractions, _, err := client.Interactions.UpdateRestrictions(context.Background(), "o", "r", input)
+	if err != nil {
+		t.Errorf("Interactions.UpdateRestrictions returned error: %v", err)
+	}
+
+	want := &InteractionRestriction{Origin: String("repository")}
+	if !reflect.DeepEqual(repoInteractions, want) {
+		t.Errorf("Interactions.UpdateRestrictions returned %+v, want %+v", repoInteractions, want)
+	}
+}
+
+func TestInteractionsService_RemoveRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/interaction-limits", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		testHeader(t, r, "Accept", mediaTypeRepositoryInteractionsPreview)
+	})
+
+	_, err := client.Interactions.RemoveRestrictions(context.Background(), "o", "r")
+	if err != nil {
+		t.Errorf("Interactions.RemoveRestrictions returned error: %v", err)
+	}
+}
diff --git a/github/repos_collaborators_test.go b/github/repos_collaborators_test.go
index aefff52c..a4d3210c 100644
--- a/github/repos_collaborators_test.go
+++ b/github/repos_collaborators_test.go
@@ -35,7 +35,7 @@ func TestRepositoriesService_ListCollaborators(t *testing.T) {
 
 	want := []*User{{ID: Int64(1)}, {ID: Int64(2)}}
 	if !reflect.DeepEqual(users, want) {
-		t.Errorf("Repositori es.ListCollaborators returned %+v, want %+v", users, want)
+		t.Errorf("Repositories.ListCollaborators returned %+v, want %+v", users, want)
 	}
 }
 
diff --git a/github/repos_test.go b/github/repos_test.go
index 4109eda9..f6405187 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -19,7 +19,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeTopicsPreview}
 	mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
@@ -41,7 +41,7 @@ func TestRepositoriesService_List_specifiedUser(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeTopicsPreview}
 	mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
@@ -77,7 +77,7 @@ func TestRepositoriesService_List_specifiedUser_type(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeTopicsPreview}
 	mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
@@ -113,7 +113,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeTopicsPreview}
 	mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
diff --git a/test/fields/fields.go b/test/fields/fields.go
index 158959f0..ef73bb53 100644
--- a/test/fields/fields.go
+++ b/test/fields/fields.go
@@ -25,7 +25,7 @@ import (
 	"reflect"
 	"strings"
 
-	"github.com/google/go-github/v20/github"
+	"github.com/google/go-github/v21/github"
 	"golang.org/x/oauth2"
 )