Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions github/enterprise_app_installation.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,112 @@ func (s *EnterpriseService) UninstallApp(ctx context.Context, enterprise, org st

return resp, nil
}

// AppInstallationRepositoriesRequest specifies the parameters for
// EnterpriseService.AddRepositoriesToAppInstallation and
// EnterpriseService.RemoveRepositoriesFromAppInstallation.
type AppInstallationRepositoriesRequest struct {
// Repository names to add to or remove from the installation.
Repositories []string `json:"repositories"`
}

// UpdateAppInstallationRepositoriesRequest specifies the parameters for
// EnterpriseService.UpdateAppInstallationRepositories.
type UpdateAppInstallationRepositoriesRequest struct {
// Can be "all" or "selected".
RepositorySelection *string `json:"repository_selection,omitempty"`
// Repository names to grant the installation access to. Only required
// when RepositorySelection is "selected".
Repositories []string `json:"repositories,omitempty"`
}

// ListRepositoriesForOrgAppInstallation lists the repositories that an enterprise app installation
// has access to on an organization.
//
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations?apiVersion=2022-11-28#get-the-repositories-accessible-to-a-given-github-app-installation
//
//meta:operation GET /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories
func (s *EnterpriseService) ListRepositoriesForOrgAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) ([]*AccessibleRepository, *Response, error) {
u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest(ctx, "GET", u, nil)
if err != nil {
return nil, nil, err
}

var r []*AccessibleRepository
resp, err := s.client.Do(req, &r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// UpdateAppInstallationRepositories changes a GitHub App installation's repository access
// between all repositories and a selected set.
//
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations?apiVersion=2022-11-28#toggle-installation-repository-access-between-selected-and-all-repositories
//
//meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories
func (s *EnterpriseService) UpdateAppInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts UpdateAppInstallationRepositoriesRequest) (*Installation, *Response, error) {
u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID)
req, err := s.client.NewRequest(ctx, "PATCH", u, opts)
if err != nil {
return nil, nil, err
}

var r *Installation
resp, err := s.client.Do(req, &r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// AddRepositoriesToAppInstallation grants repository access for a GitHub App installation.
//
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations?apiVersion=2022-11-28#grant-repository-access-to-an-organization-installation
//
//meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/add
func (s *EnterpriseService) AddRepositoriesToAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts AppInstallationRepositoriesRequest) ([]*AccessibleRepository, *Response, error) {
u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/add", enterprise, org, installationID)
req, err := s.client.NewRequest(ctx, "PATCH", u, opts)
if err != nil {
return nil, nil, err
}

var r []*AccessibleRepository
resp, err := s.client.Do(req, &r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// RemoveRepositoriesFromAppInstallation revokes repository access from a GitHub App installation.
//
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations?apiVersion=2022-11-28#remove-repository-access-from-an-organization-installation
//
//meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/remove
func (s *EnterpriseService) RemoveRepositoriesFromAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts AppInstallationRepositoriesRequest) ([]*AccessibleRepository, *Response, error) {
u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/remove", enterprise, org, installationID)
req, err := s.client.NewRequest(ctx, "PATCH", u, opts)
if err != nil {
return nil, nil, err
}

var r []*AccessibleRepository
resp, err := s.client.Do(req, &r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}
141 changes: 141 additions & 0 deletions github/enterprise_app_installation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,144 @@ func TestEnterpriseService_UninstallApp(t *testing.T) {
return client.Enterprise.UninstallApp(ctx, "e", "org1", 123)
})
}

func TestEnterpriseService_ListRepositoriesForOrgAppInstallation(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "1"})
fmt.Fprint(w, `[{"id":1}]`)
})

ctx := t.Context()
repos, _, err := client.Enterprise.ListRepositoriesForOrgAppInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1})
if err != nil {
t.Errorf("Enterprise.ListRepositoriesForOrgAppInstallation returned error: %v", err)
}

want := []*AccessibleRepository{{ID: 1}}
if diff := cmp.Diff(repos, want); diff != "" {
t.Errorf("Enterprise.ListRepositoriesForOrgAppInstallation returned diff (-want +got):\n%v", diff)
}

const methodName = "ListRepositoriesForOrgAppInstallation"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Enterprise.ListRepositoriesForOrgAppInstallation(ctx, "\n", "\n", -1, &ListOptions{})
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
_, resp, err := client.Enterprise.ListRepositoriesForOrgAppInstallation(ctx, "e", "o", 1, &ListOptions{})
return resp, err
})
}

func TestEnterpriseService_UpdateAppInstallationRepositories(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := UpdateAppInstallationRepositoriesRequest{
RepositorySelection: Ptr("selected"),
Repositories: []string{"hello-world", "hello-world-2"},
}

mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testJSONBody(t, r, input)
fmt.Fprint(w, `{"id":1, "repository_selection":"selected"}`)
})

ctx := t.Context()
inst, _, err := client.Enterprise.UpdateAppInstallationRepositories(ctx, "e", "o", 1, input)
if err != nil {
t.Errorf("Enterprise.UpdateAppInstallationRepositories returned error: %v", err)
}

want := &Installation{ID: Ptr(int64(1)), RepositorySelection: Ptr("selected")}
if diff := cmp.Diff(inst, want); diff != "" {
t.Errorf("Enterprise.UpdateAppInstallationRepositories returned diff (-want +got):\n%v", diff)
}

const methodName = "UpdateAppInstallationRepositories"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Enterprise.UpdateAppInstallationRepositories(ctx, "\n", "\n", -1, input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
_, resp, err := client.Enterprise.UpdateAppInstallationRepositories(ctx, "e", "o", 1, input)
return resp, err
})
}

func TestEnterpriseService_AddRepositoriesToAppInstallation(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := AppInstallationRepositoriesRequest{Repositories: []string{"hello-world", "hello-world-2"}}

mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/add", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testJSONBody(t, r, input)
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
})

ctx := t.Context()
repos, _, err := client.Enterprise.AddRepositoriesToAppInstallation(ctx, "e", "o", 1, input)
if err != nil {
t.Errorf("Enterprise.AddRepositoriesToAppInstallation returned error: %v", err)
}

want := []*AccessibleRepository{{ID: 1}, {ID: 2}}
if diff := cmp.Diff(repos, want); diff != "" {
t.Errorf("Enterprise.AddRepositoriesToAppInstallation returned diff (-want +got):\n%v", diff)
}

const methodName = "AddRepositoriesToAppInstallation"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Enterprise.AddRepositoriesToAppInstallation(ctx, "\n", "\n", -1, input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
_, resp, err := client.Enterprise.AddRepositoriesToAppInstallation(ctx, "e", "o", 1, input)
return resp, err
})
}

func TestEnterpriseService_RemoveRepositoriesFromAppInstallation(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := AppInstallationRepositoriesRequest{Repositories: []string{"hello-world", "hello-world-2"}}

mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/remove", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testJSONBody(t, r, input)
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
})

ctx := t.Context()
repos, _, err := client.Enterprise.RemoveRepositoriesFromAppInstallation(ctx, "e", "o", 1, input)
if err != nil {
t.Errorf("Enterprise.RemoveRepositoriesFromAppInstallation returned error: %v", err)
}

want := []*AccessibleRepository{{ID: 1}, {ID: 2}}
if diff := cmp.Diff(repos, want); diff != "" {
t.Errorf("Enterprise.RemoveRepositoriesFromAppInstallation returned diff (-want +got):\n%v", diff)
}

const methodName = "RemoveRepositoriesFromAppInstallation"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Enterprise.RemoveRepositoriesFromAppInstallation(ctx, "\n", "\n", -1, input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
_, resp, err := client.Enterprise.RemoveRepositoriesFromAppInstallation(ctx, "e", "o", 1, input)
return resp, err
})
}
116 changes: 0 additions & 116 deletions github/enterprise_apps.go

This file was deleted.

Loading
Loading