From 3a5cc2b973d89d609aa142da7d63a69dff3a7654 Mon Sep 17 00:00:00 2001 From: Nithish S Date: Sat, 15 Nov 2025 23:22:44 -0800 Subject: [PATCH 1/7] feat: add enterprise app installation repository endpoints; --- github/enterprise_apps.go | 122 ++++++++++++++++++++++++++ github/enterprise_apps_test.go | 152 +++++++++++++++++++++++++++++++++ github/github.go | 2 + 3 files changed, 276 insertions(+) create mode 100644 github/enterprise_apps.go create mode 100644 github/enterprise_apps_test.go diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go new file mode 100644 index 00000000000..b7fd815563e --- /dev/null +++ b/github/enterprise_apps.go @@ -0,0 +1,122 @@ +// Copyright 2025 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" +) + +// EnterpriseAppsService handles communication with the enterprise apps related +// methods of the GitHub API. +// +// GitHub API docs: https://docs.github.com/en/rest/reference/enterprise-admin#apps +type EnterpriseAppsService service + +// EnterpriseInstallationRepositoriesOptions specifies the parameters for +// EnterpriseAppsService.AddRepositoriesToInstallation and +// EnterpriseAppsService.RemoveRepositoriesFromInstallation. +type EnterpriseInstallationRepositoriesOptions struct { + SelectedRepositoryIDs []int64 `json:"selected_repository_ids"` +} + +// EnterpriseInstallationRepositoriesToggleOptions specifies the parameters for +// EnterpriseAppsService.ToggleInstallationRepositories. +type EnterpriseInstallationRepositoriesToggleOptions struct { + RepositorySelection *string `json:"repository_selection,omitempty"` // Can be "all" or "selected" + SelectedRepositoryIDs []int64 `json:"selected_repository_ids,omitempty"` +} + +// ListRepositoriesForOrgInstallation 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#list-repositories-accessible-to-the-app-installation-for-an-organization +// +//meta:operation GET /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories +func (s *EnterpriseAppsService) ListRepositoriesForOrgInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) (*ListRepositories, *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("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var r *ListRepositories + resp, err := s.client.Do(ctx, req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// ToggleInstallationRepositories 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#toggle-installation-repository-access-between-selected-and-all-repositories +// +//meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories +func (s *EnterpriseAppsService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesToggleOptions) (*ListRepositories, *Response, error) { + u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) + req, err := s.client.NewRequest("PATCH", u, opts) + if err != nil { + return nil, nil, err + } + + var r *ListRepositories + resp, err := s.client.Do(ctx, req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// AddRepositoriesToInstallation grants repository access for a GitHub App installation. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#grant-repository-access-to-an-organization-installation +// +//meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/add +func (s *EnterpriseAppsService) AddRepositoriesToInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { + u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/add", enterprise, org, installationID) + req, err := s.client.NewRequest("PATCH", u, opts) + if err != nil { + return nil, nil, err + } + + var r *ListRepositories + resp, err := s.client.Do(ctx, req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// RemoveRepositoriesFromInstallation revokes repository access from a GitHub App installation. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#remove-repository-access-from-an-organization-installation +// +//meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/remove +func (s *EnterpriseAppsService) RemoveRepositoriesFromInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { + u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/remove", enterprise, org, installationID) + req, err := s.client.NewRequest("PATCH", u, opts) + if err != nil { + return nil, nil, err + } + + var r *ListRepositories + resp, err := s.client.Do(ctx, req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go new file mode 100644 index 00000000000..19199ff17a7 --- /dev/null +++ b/github/enterprise_apps_test.go @@ -0,0 +1,152 @@ +// Copyright 2025 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" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(t *testing.T) { + 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, `{"total_count":1, "repositories":[{"id":1}]}`) + }) + + ctx := context.Background() + repos, _, err := client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1}) + if err != nil { + t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned error: %v", err) + } + + want := &ListRepositories{TotalCount: Ptr(1), Repositories: []*Repository{{ID: Ptr(int64(1))}}} + if diff := cmp.Diff(repos, want); diff != "" { + t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%s", diff) + } + + const methodName = "ListRepositoriesForOrgInstallation" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "\n", "\n", -1, &ListOptions{}) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{}) + return resp, err + }) +} + +func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { + client, mux, _ := setup(t) + + input := &EnterpriseInstallationRepositoriesToggleOptions{ + RepositorySelection: String("selected"), + SelectedRepositoryIDs: []int64{1, 2}, + } + + mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testBody(t, r, `{"repository_selection":"selected","selected_repository_ids":[1,2]}`+"\n") + fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) + }) + + ctx := context.Background() + repos, _, err := client.EnterpriseApps.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + if err != nil { + t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned error: %v", err) + } + + want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} + if diff := cmp.Diff(repos, want); diff != "" { + t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned diff (-want +got):\n%s", diff) + } + + const methodName = "ToggleInstallationRepositories" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.EnterpriseApps.ToggleInstallationRepositories(ctx, "\n", "\n", -1, input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.EnterpriseApps.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + return resp, err + }) +} + +func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { + client, mux, _ := setup(t) + + input := &EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + + mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/add", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testBody(t, r, `{"selected_repository_ids":[1,2]}`+"\n") + fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) + }) + + ctx := context.Background() + repos, _, err := client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) + if err != nil { + t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned error: %v", err) + } + + want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} + if diff := cmp.Diff(repos, want); diff != "" { + t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned diff (-want +got):\n%s", diff) + } + + const methodName = "AddRepositoriesToInstallation" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "\n", "\n", -1, input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) + return resp, err + }) +} + +func TestEnterpriseAppsService_RemoveRepositoriesFromInstallation(t *testing.T) { + client, mux, _ := setup(t) + + input := &EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + + mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/remove", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testBody(t, r, `{"selected_repository_ids":[1,2]}`+"\n") + fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) + }) + + ctx := context.Background() + repos, _, err := client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) + if err != nil { + t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned error: %v", err) + } + + want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} + if diff := cmp.Diff(repos, want); diff != "" { + t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned diff (-want +got):\n%s", diff) + } + + const methodName = "RemoveRepositoriesFromInstallation" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "\n", "\n", -1, input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) + return resp, err + }) +} diff --git a/github/github.go b/github/github.go index eba55176108..80e661aef45 100644 --- a/github/github.go +++ b/github/github.go @@ -207,6 +207,7 @@ type Client struct { DependencyGraph *DependencyGraphService Emojis *EmojisService Enterprise *EnterpriseService + EnterpriseApps *EnterpriseAppsService Gists *GistsService Git *GitService Gitignores *GitignoresService @@ -449,6 +450,7 @@ func (c *Client) initialize() { c.DependencyGraph = (*DependencyGraphService)(&c.common) c.Emojis = (*EmojisService)(&c.common) c.Enterprise = (*EnterpriseService)(&c.common) + c.EnterpriseApps = (*EnterpriseAppsService)(&c.common) c.Gists = (*GistsService)(&c.common) c.Git = (*GitService)(&c.common) c.Gitignores = (*GitignoresService)(&c.common) From aa48a27383e91223b551629b50976a5a99aa0b3a Mon Sep 17 00:00:00 2001 From: Nithish S Date: Sat, 15 Nov 2025 23:44:31 -0800 Subject: [PATCH 2/7] fix: resolve linter issues from script/lint.sh --- github/enterprise_apps.go | 2 +- github/enterprise_apps_test.go | 21 ++++++++++++--------- github/github-accessors.go | 8 ++++++++ github/github-accessors_test.go | 11 +++++++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go index b7fd815563e..3353e71916f 100644 --- a/github/enterprise_apps.go +++ b/github/enterprise_apps.go @@ -33,7 +33,7 @@ type EnterpriseInstallationRepositoriesToggleOptions struct { // ListRepositoriesForOrgInstallation 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#list-repositories-accessible-to-the-app-installation-for-an-organization +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#get-the-repositories-accessible-to-a-given-github-app-installation // //meta:operation GET /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories func (s *EnterpriseAppsService) ListRepositoriesForOrgInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) (*ListRepositories, *Response, error) { diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go index 19199ff17a7..e05720e7591 100644 --- a/github/enterprise_apps_test.go +++ b/github/enterprise_apps_test.go @@ -6,7 +6,6 @@ package github import ( - "context" "fmt" "net/http" "testing" @@ -15,6 +14,7 @@ import ( ) func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(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) { @@ -23,7 +23,7 @@ func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(t *testing.T) fmt.Fprint(w, `{"total_count":1, "repositories":[{"id":1}]}`) }) - ctx := context.Background() + ctx := t.Context() repos, _, err := client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1}) if err != nil { t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned error: %v", err) @@ -31,7 +31,7 @@ func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(t *testing.T) want := &ListRepositories{TotalCount: Ptr(1), Repositories: []*Repository{{ID: Ptr(int64(1))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%s", diff) + t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%v", diff) } const methodName = "ListRepositoriesForOrgInstallation" @@ -47,6 +47,7 @@ func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(t *testing.T) } func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { + t.Parallel() client, mux, _ := setup(t) input := &EnterpriseInstallationRepositoriesToggleOptions{ @@ -60,7 +61,7 @@ func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) }) - ctx := context.Background() + ctx := t.Context() repos, _, err := client.EnterpriseApps.ToggleInstallationRepositories(ctx, "e", "o", 1, input) if err != nil { t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned error: %v", err) @@ -68,7 +69,7 @@ func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned diff (-want +got):\n%s", diff) + t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned diff (-want +got):\n%v", diff) } const methodName = "ToggleInstallationRepositories" @@ -84,6 +85,7 @@ func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { } func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { + t.Parallel() client, mux, _ := setup(t) input := &EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} @@ -94,7 +96,7 @@ func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) }) - ctx := context.Background() + ctx := t.Context() repos, _, err := client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) if err != nil { t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned error: %v", err) @@ -102,7 +104,7 @@ func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned diff (-want +got):\n%s", diff) + t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned diff (-want +got):\n%v", diff) } const methodName = "AddRepositoriesToInstallation" @@ -118,6 +120,7 @@ func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { } func TestEnterpriseAppsService_RemoveRepositoriesFromInstallation(t *testing.T) { + t.Parallel() client, mux, _ := setup(t) input := &EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} @@ -128,7 +131,7 @@ func TestEnterpriseAppsService_RemoveRepositoriesFromInstallation(t *testing.T) fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) }) - ctx := context.Background() + ctx := t.Context() repos, _, err := client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) if err != nil { t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned error: %v", err) @@ -136,7 +139,7 @@ func TestEnterpriseAppsService_RemoveRepositoriesFromInstallation(t *testing.T) want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned diff (-want +got):\n%s", diff) + t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned diff (-want +got):\n%v", diff) } const methodName = "RemoveRepositoriesFromInstallation" diff --git a/github/github-accessors.go b/github/github-accessors.go index b95be28e733..e060c582bea 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9254,6 +9254,14 @@ func (e *EnterpriseCustomPropertiesValues) GetOrganizationLogin() string { return *e.OrganizationLogin } +// GetRepositorySelection returns the RepositorySelection field if it's non-nil, zero value otherwise. +func (e *EnterpriseInstallationRepositoriesToggleOptions) GetRepositorySelection() string { + if e == nil || e.RepositorySelection == nil { + return "" + } + return *e.RepositorySelection +} + // GetEnterpriseServerUser returns the EnterpriseServerUser field if it's non-nil, zero value otherwise. func (e *EnterpriseLicensedUsers) GetEnterpriseServerUser() bool { if e == nil || e.EnterpriseServerUser == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 9abcb49dcde..9a853f94e12 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -11985,6 +11985,17 @@ func TestEnterpriseCustomPropertiesValues_GetOrganizationLogin(tt *testing.T) { e.GetOrganizationLogin() } +func TestEnterpriseInstallationRepositoriesToggleOptions_GetRepositorySelection(tt *testing.T) { + tt.Parallel() + var zeroValue string + e := &EnterpriseInstallationRepositoriesToggleOptions{RepositorySelection: &zeroValue} + e.GetRepositorySelection() + e = &EnterpriseInstallationRepositoriesToggleOptions{} + e.GetRepositorySelection() + e = nil + e.GetRepositorySelection() +} + func TestEnterpriseLicensedUsers_GetEnterpriseServerUser(tt *testing.T) { tt.Parallel() var zeroValue bool From 3b1b3c4948f9a3e00004ce3b3ca425d09677197e Mon Sep 17 00:00:00 2001 From: Nithish S Date: Sun, 16 Nov 2025 04:33:13 -0800 Subject: [PATCH 3/7] fix: address code review feadback - Use EnterpriseService instead of creating new service - Add EnterpriseInstallationRepositoriesOptions for consistency - Update method signatures to Required --- github/enterprise_apps.go | 20 +++++-------- github/enterprise_apps_test.go | 52 +++++++++++++++++----------------- github/github.go | 2 -- 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go index 3353e71916f..2e43a142305 100644 --- a/github/enterprise_apps.go +++ b/github/enterprise_apps.go @@ -10,21 +10,15 @@ import ( "fmt" ) -// EnterpriseAppsService handles communication with the enterprise apps related -// methods of the GitHub API. -// -// GitHub API docs: https://docs.github.com/en/rest/reference/enterprise-admin#apps -type EnterpriseAppsService service - // EnterpriseInstallationRepositoriesOptions specifies the parameters for -// EnterpriseAppsService.AddRepositoriesToInstallation and -// EnterpriseAppsService.RemoveRepositoriesFromInstallation. +// EnterpriseService.AddRepositoriesToInstallation and +// EnterpriseService.RemoveRepositoriesFromInstallation. type EnterpriseInstallationRepositoriesOptions struct { SelectedRepositoryIDs []int64 `json:"selected_repository_ids"` } // EnterpriseInstallationRepositoriesToggleOptions specifies the parameters for -// EnterpriseAppsService.ToggleInstallationRepositories. +// EnterpriseService.ToggleInstallationRepositories. type EnterpriseInstallationRepositoriesToggleOptions struct { RepositorySelection *string `json:"repository_selection,omitempty"` // Can be "all" or "selected" SelectedRepositoryIDs []int64 `json:"selected_repository_ids,omitempty"` @@ -36,7 +30,7 @@ type EnterpriseInstallationRepositoriesToggleOptions struct { // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#get-the-repositories-accessible-to-a-given-github-app-installation // //meta:operation GET /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories -func (s *EnterpriseAppsService) ListRepositoriesForOrgInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) ListRepositoriesForOrgInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) (*ListRepositories, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) u, err := addOptions(u, opts) if err != nil { @@ -63,7 +57,7 @@ func (s *EnterpriseAppsService) ListRepositoriesForOrgInstallation(ctx context.C // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#toggle-installation-repository-access-between-selected-and-all-repositories // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories -func (s *EnterpriseAppsService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesToggleOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesToggleOptions) (*ListRepositories, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { @@ -84,7 +78,7 @@ func (s *EnterpriseAppsService) ToggleInstallationRepositories(ctx context.Conte // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#grant-repository-access-to-an-organization-installation // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/add -func (s *EnterpriseAppsService) AddRepositoriesToInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) AddRepositoriesToInstallation(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/add", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { @@ -105,7 +99,7 @@ func (s *EnterpriseAppsService) AddRepositoriesToInstallation(ctx context.Contex // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#remove-repository-access-from-an-organization-installation // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/remove -func (s *EnterpriseAppsService) RemoveRepositoriesFromInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) RemoveRepositoriesFromInstallation(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/remove", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go index e05720e7591..29a58e0439d 100644 --- a/github/enterprise_apps_test.go +++ b/github/enterprise_apps_test.go @@ -13,7 +13,7 @@ import ( "github.com/google/go-cmp/cmp" ) -func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(t *testing.T) { +func TestEnterpriseService_ListRepositoriesForOrgInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -24,29 +24,29 @@ func TestEnterpriseAppsService_ListRepositoriesForOrgInstallation(t *testing.T) }) ctx := t.Context() - repos, _, err := client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1}) + repos, _, err := client.Enterprise.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1}) if err != nil { - t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned error: %v", err) + t.Errorf("Enterprise.ListRepositoriesForOrgInstallation returned error: %v", err) } want := &ListRepositories{TotalCount: Ptr(1), Repositories: []*Repository{{ID: Ptr(int64(1))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%v", diff) } const methodName = "ListRepositoriesForOrgInstallation" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "\n", "\n", -1, &ListOptions{}) + _, _, err = client.Enterprise.ListRepositoriesForOrgInstallation(ctx, "\n", "\n", -1, &ListOptions{}) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.EnterpriseApps.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{}) + _, resp, err := client.Enterprise.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{}) return resp, err }) } -func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { +func TestEnterpriseService_ToggleInstallationRepositories(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -62,33 +62,33 @@ func TestEnterpriseAppsService_ToggleInstallationRepositories(t *testing.T) { }) ctx := t.Context() - repos, _, err := client.EnterpriseApps.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + repos, _, err := client.Enterprise.ToggleInstallationRepositories(ctx, "e", "o", 1, input) if err != nil { - t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned error: %v", err) + t.Errorf("Enterprise.ToggleInstallationRepositories returned error: %v", err) } want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.ToggleInstallationRepositories returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.ToggleInstallationRepositories returned diff (-want +got):\n%v", diff) } const methodName = "ToggleInstallationRepositories" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.EnterpriseApps.ToggleInstallationRepositories(ctx, "\n", "\n", -1, input) + _, _, err = client.Enterprise.ToggleInstallationRepositories(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.EnterpriseApps.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + _, resp, err := client.Enterprise.ToggleInstallationRepositories(ctx, "e", "o", 1, input) return resp, err }) } -func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { +func TestEnterpriseService_AddRepositoriesToInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + input := EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/add", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") @@ -97,33 +97,33 @@ func TestEnterpriseAppsService_AddRepositoriesToInstallation(t *testing.T) { }) ctx := t.Context() - repos, _, err := client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) + repos, _, err := client.Enterprise.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) if err != nil { - t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned error: %v", err) + t.Errorf("Enterprise.AddRepositoriesToInstallation returned error: %v", err) } want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.AddRepositoriesToInstallation returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.AddRepositoriesToInstallation returned diff (-want +got):\n%v", diff) } const methodName = "AddRepositoriesToInstallation" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "\n", "\n", -1, input) + _, _, err = client.Enterprise.AddRepositoriesToInstallation(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.EnterpriseApps.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) + _, resp, err := client.Enterprise.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) return resp, err }) } -func TestEnterpriseAppsService_RemoveRepositoriesFromInstallation(t *testing.T) { +func TestEnterpriseService_RemoveRepositoriesFromInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + input := EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/remove", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") @@ -132,24 +132,24 @@ func TestEnterpriseAppsService_RemoveRepositoriesFromInstallation(t *testing.T) }) ctx := t.Context() - repos, _, err := client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) + repos, _, err := client.Enterprise.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) if err != nil { - t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned error: %v", err) + t.Errorf("Enterprise.RemoveRepositoriesFromInstallation returned error: %v", err) } want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("EnterpriseApps.RemoveRepositoriesFromInstallation returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.RemoveRepositoriesFromInstallation returned diff (-want +got):\n%v", diff) } const methodName = "RemoveRepositoriesFromInstallation" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "\n", "\n", -1, input) + _, _, err = client.Enterprise.RemoveRepositoriesFromInstallation(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.EnterpriseApps.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) + _, resp, err := client.Enterprise.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) return resp, err }) } diff --git a/github/github.go b/github/github.go index 80e661aef45..eba55176108 100644 --- a/github/github.go +++ b/github/github.go @@ -207,7 +207,6 @@ type Client struct { DependencyGraph *DependencyGraphService Emojis *EmojisService Enterprise *EnterpriseService - EnterpriseApps *EnterpriseAppsService Gists *GistsService Git *GitService Gitignores *GitignoresService @@ -450,7 +449,6 @@ func (c *Client) initialize() { c.DependencyGraph = (*DependencyGraphService)(&c.common) c.Emojis = (*EmojisService)(&c.common) c.Enterprise = (*EnterpriseService)(&c.common) - c.EnterpriseApps = (*EnterpriseAppsService)(&c.common) c.Gists = (*GistsService)(&c.common) c.Git = (*GitService)(&c.common) c.Gitignores = (*GitignoresService)(&c.common) From fc00e8eecf3d1c20c79960e4469dbaab5bf0c650 Mon Sep 17 00:00:00 2001 From: Nithish S Date: Sat, 22 Nov 2025 18:55:58 -0800 Subject: [PATCH 4/7] feat: add `AccessibleRepository` struct and update `ListRepositoriesForOrgInstallation` to return a slice of it --- github/enterprise_apps.go | 8 +++++--- github/enterprise_apps_test.go | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go index 2e43a142305..99e3a8bdda3 100644 --- a/github/enterprise_apps.go +++ b/github/enterprise_apps.go @@ -24,13 +24,15 @@ type EnterpriseInstallationRepositoriesToggleOptions struct { SelectedRepositoryIDs []int64 `json:"selected_repository_ids,omitempty"` } + + // ListRepositoriesForOrgInstallation 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#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) ListRepositoriesForOrgInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) ListRepositoriesForOrgInstallation(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 { @@ -42,7 +44,7 @@ func (s *EnterpriseService) ListRepositoriesForOrgInstallation(ctx context.Conte return nil, nil, err } - var r *ListRepositories + var r []*AccessibleRepository resp, err := s.client.Do(ctx, req, &r) if err != nil { return nil, resp, err @@ -57,7 +59,7 @@ func (s *EnterpriseService) ListRepositoriesForOrgInstallation(ctx context.Conte // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#toggle-installation-repository-access-between-selected-and-all-repositories // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories -func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts *EnterpriseInstallationRepositoriesToggleOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesToggleOptions) (*ListRepositories, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go index 29a58e0439d..9d4431368db 100644 --- a/github/enterprise_apps_test.go +++ b/github/enterprise_apps_test.go @@ -20,7 +20,7 @@ func TestEnterpriseService_ListRepositoriesForOrgInstallation(t *testing.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, `{"total_count":1, "repositories":[{"id":1}]}`) + fmt.Fprint(w, `[{"id":1}]`) }) ctx := t.Context() @@ -29,7 +29,7 @@ func TestEnterpriseService_ListRepositoriesForOrgInstallation(t *testing.T) { t.Errorf("Enterprise.ListRepositoriesForOrgInstallation returned error: %v", err) } - want := &ListRepositories{TotalCount: Ptr(1), Repositories: []*Repository{{ID: Ptr(int64(1))}}} + want := []*AccessibleRepository{{ID: 1}} if diff := cmp.Diff(repos, want); diff != "" { t.Errorf("Enterprise.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%v", diff) } @@ -50,7 +50,7 @@ func TestEnterpriseService_ToggleInstallationRepositories(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &EnterpriseInstallationRepositoriesToggleOptions{ + input := EnterpriseInstallationRepositoriesToggleOptions{ RepositorySelection: String("selected"), SelectedRepositoryIDs: []int64{1, 2}, } From 1e52265f14d805ad31deacf99904ee947fee9056 Mon Sep 17 00:00:00 2001 From: Nithish S Date: Sat, 22 Nov 2025 20:36:11 -0800 Subject: [PATCH 5/7] fix: update ToggleInstallationRepositories to return Installation instead of ListRepositories and adjust its test expectations. --- github/enterprise_apps.go | 6 ++---- github/enterprise_apps_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go index 99e3a8bdda3..b89035cf71e 100644 --- a/github/enterprise_apps.go +++ b/github/enterprise_apps.go @@ -24,8 +24,6 @@ type EnterpriseInstallationRepositoriesToggleOptions struct { SelectedRepositoryIDs []int64 `json:"selected_repository_ids,omitempty"` } - - // ListRepositoriesForOrgInstallation lists the repositories that an enterprise app installation // has access to on an organization. // @@ -59,14 +57,14 @@ func (s *EnterpriseService) ListRepositoriesForOrgInstallation(ctx context.Conte // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#toggle-installation-repository-access-between-selected-and-all-repositories // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories -func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesToggleOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesToggleOptions) (*Installation, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } - var r *ListRepositories + var r *Installation resp, err := s.client.Do(ctx, req, &r) if err != nil { return nil, resp, err diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go index 9d4431368db..06211ddaf7b 100644 --- a/github/enterprise_apps_test.go +++ b/github/enterprise_apps_test.go @@ -58,17 +58,17 @@ func TestEnterpriseService_ToggleInstallationRepositories(t *testing.T) { mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") testBody(t, r, `{"repository_selection":"selected","selected_repository_ids":[1,2]}`+"\n") - fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) + fmt.Fprint(w, `{"id":1, "repository_selection":"selected"}`) }) ctx := t.Context() - repos, _, err := client.Enterprise.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + inst, _, err := client.Enterprise.ToggleInstallationRepositories(ctx, "e", "o", 1, input) if err != nil { t.Errorf("Enterprise.ToggleInstallationRepositories returned error: %v", err) } - want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} - if diff := cmp.Diff(repos, want); diff != "" { + want := &Installation{ID: Ptr(int64(1)), RepositorySelection: Ptr("selected")} + if diff := cmp.Diff(inst, want); diff != "" { t.Errorf("Enterprise.ToggleInstallationRepositories returned diff (-want +got):\n%v", diff) } From 9b5e78ad1b581d304c79cd501f6330a21ff99422 Mon Sep 17 00:00:00 2001 From: Nithish S Date: Wed, 26 Nov 2025 17:04:33 -0800 Subject: [PATCH 6/7] feat: Add enterprise app installation repository management APIs --- github/enterprise_apps.go | 34 ++++++++-------- github/enterprise_apps_test.go | 70 ++++++++++++++++----------------- github/github-accessors.go | 16 ++++---- github/github-accessors_test.go | 22 +++++------ 4 files changed, 71 insertions(+), 71 deletions(-) diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go index b89035cf71e..92e9d3a5a22 100644 --- a/github/enterprise_apps.go +++ b/github/enterprise_apps.go @@ -10,27 +10,27 @@ import ( "fmt" ) -// EnterpriseInstallationRepositoriesOptions specifies the parameters for -// EnterpriseService.AddRepositoriesToInstallation and -// EnterpriseService.RemoveRepositoriesFromInstallation. -type EnterpriseInstallationRepositoriesOptions struct { +// AppInstallationRepositoriesOptions specifies the parameters for +// EnterpriseService.AddRepositoriesToAppInstallation and +// EnterpriseService.RemoveRepositoriesFromAppInstallation. +type AppInstallationRepositoriesOptions struct { SelectedRepositoryIDs []int64 `json:"selected_repository_ids"` } -// EnterpriseInstallationRepositoriesToggleOptions specifies the parameters for -// EnterpriseService.ToggleInstallationRepositories. -type EnterpriseInstallationRepositoriesToggleOptions struct { +// UpdateAppInstallationRepositoriesOptions specifies the parameters for +// EnterpriseService.UpdateAppInstallationRepositories. +type UpdateAppInstallationRepositoriesOptions struct { RepositorySelection *string `json:"repository_selection,omitempty"` // Can be "all" or "selected" SelectedRepositoryIDs []int64 `json:"selected_repository_ids,omitempty"` } -// ListRepositoriesForOrgInstallation lists the repositories that an enterprise app installation +// 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#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) ListRepositoriesForOrgInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *ListOptions) ([]*AccessibleRepository, *Response, error) { +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 { @@ -51,13 +51,13 @@ func (s *EnterpriseService) ListRepositoriesForOrgInstallation(ctx context.Conte return r, resp, nil } -// ToggleInstallationRepositories changes a GitHub App installation's repository access +// 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#toggle-installation-repository-access-between-selected-and-all-repositories // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories -func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesToggleOptions) (*Installation, *Response, error) { +func (s *EnterpriseService) UpdateAppInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts *UpdateAppInstallationRepositoriesOptions) (*Installation, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { @@ -73,19 +73,19 @@ func (s *EnterpriseService) ToggleInstallationRepositories(ctx context.Context, return r, resp, nil } -// AddRepositoriesToInstallation grants repository access for a GitHub App installation. +// AddRepositoriesToAppInstallation grants repository access for a GitHub App installation. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#grant-repository-access-to-an-organization-installation // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/add -func (s *EnterpriseService) AddRepositoriesToInstallation(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) AddRepositoriesToAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *AppInstallationRepositoriesOptions) ([]*AccessibleRepository, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/add", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } - var r *ListRepositories + var r []*AccessibleRepository resp, err := s.client.Do(ctx, req, &r) if err != nil { return nil, resp, err @@ -94,19 +94,19 @@ func (s *EnterpriseService) AddRepositoriesToInstallation(ctx context.Context, e return r, resp, nil } -// RemoveRepositoriesFromInstallation revokes repository access from a GitHub App installation. +// RemoveRepositoriesFromAppInstallation revokes repository access from a GitHub App installation. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#remove-repository-access-from-an-organization-installation // //meta:operation PATCH /enterprises/{enterprise}/apps/organizations/{org}/installations/{installation_id}/repositories/remove -func (s *EnterpriseService) RemoveRepositoriesFromInstallation(ctx context.Context, enterprise, org string, installationID int64, opts EnterpriseInstallationRepositoriesOptions) (*ListRepositories, *Response, error) { +func (s *EnterpriseService) RemoveRepositoriesFromAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts *AppInstallationRepositoriesOptions) ([]*AccessibleRepository, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/remove", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } - var r *ListRepositories + var r []*AccessibleRepository resp, err := s.client.Do(ctx, req, &r) if err != nil { return nil, resp, err diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go index 06211ddaf7b..9d94423384c 100644 --- a/github/enterprise_apps_test.go +++ b/github/enterprise_apps_test.go @@ -13,7 +13,7 @@ import ( "github.com/google/go-cmp/cmp" ) -func TestEnterpriseService_ListRepositoriesForOrgInstallation(t *testing.T) { +func TestEnterpriseService_ListRepositoriesForOrgAppInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -24,33 +24,33 @@ func TestEnterpriseService_ListRepositoriesForOrgInstallation(t *testing.T) { }) ctx := t.Context() - repos, _, err := client.Enterprise.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1}) + repos, _, err := client.Enterprise.ListRepositoriesForOrgAppInstallation(ctx, "e", "o", 1, &ListOptions{Page: 1}) if err != nil { - t.Errorf("Enterprise.ListRepositoriesForOrgInstallation returned error: %v", err) + t.Errorf("Enterprise.ListRepositoriesForOrgAppInstallation returned error: %v", err) } want := []*AccessibleRepository{{ID: 1}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("Enterprise.ListRepositoriesForOrgInstallation returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.ListRepositoriesForOrgAppInstallation returned diff (-want +got):\n%v", diff) } - const methodName = "ListRepositoriesForOrgInstallation" + const methodName = "ListRepositoriesForOrgAppInstallation" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Enterprise.ListRepositoriesForOrgInstallation(ctx, "\n", "\n", -1, &ListOptions{}) + _, _, err = client.Enterprise.ListRepositoriesForOrgAppInstallation(ctx, "\n", "\n", -1, &ListOptions{}) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.Enterprise.ListRepositoriesForOrgInstallation(ctx, "e", "o", 1, &ListOptions{}) + _, resp, err := client.Enterprise.ListRepositoriesForOrgAppInstallation(ctx, "e", "o", 1, &ListOptions{}) return resp, err }) } -func TestEnterpriseService_ToggleInstallationRepositories(t *testing.T) { +func TestEnterpriseService_UpdateAppInstallationRepositories(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := EnterpriseInstallationRepositoriesToggleOptions{ + input := &UpdateAppInstallationRepositoriesOptions{ RepositorySelection: String("selected"), SelectedRepositoryIDs: []int64{1, 2}, } @@ -62,94 +62,94 @@ func TestEnterpriseService_ToggleInstallationRepositories(t *testing.T) { }) ctx := t.Context() - inst, _, err := client.Enterprise.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + inst, _, err := client.Enterprise.UpdateAppInstallationRepositories(ctx, "e", "o", 1, input) if err != nil { - t.Errorf("Enterprise.ToggleInstallationRepositories returned error: %v", err) + 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.ToggleInstallationRepositories returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.UpdateAppInstallationRepositories returned diff (-want +got):\n%v", diff) } - const methodName = "ToggleInstallationRepositories" + const methodName = "UpdateAppInstallationRepositories" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Enterprise.ToggleInstallationRepositories(ctx, "\n", "\n", -1, input) + _, _, err = client.Enterprise.UpdateAppInstallationRepositories(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.Enterprise.ToggleInstallationRepositories(ctx, "e", "o", 1, input) + _, resp, err := client.Enterprise.UpdateAppInstallationRepositories(ctx, "e", "o", 1, input) return resp, err }) } -func TestEnterpriseService_AddRepositoriesToInstallation(t *testing.T) { +func TestEnterpriseService_AddRepositoriesToAppInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + input := &AppInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/add", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") testBody(t, r, `{"selected_repository_ids":[1,2]}`+"\n") - fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) + fmt.Fprint(w, `[{"id":1},{"id":2}]`) }) ctx := t.Context() - repos, _, err := client.Enterprise.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) + repos, _, err := client.Enterprise.AddRepositoriesToAppInstallation(ctx, "e", "o", 1, input) if err != nil { - t.Errorf("Enterprise.AddRepositoriesToInstallation returned error: %v", err) + t.Errorf("Enterprise.AddRepositoriesToAppInstallation returned error: %v", err) } - want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} + want := []*AccessibleRepository{{ID: 1}, {ID: 2}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("Enterprise.AddRepositoriesToInstallation returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.AddRepositoriesToAppInstallation returned diff (-want +got):\n%v", diff) } - const methodName = "AddRepositoriesToInstallation" + const methodName = "AddRepositoriesToAppInstallation" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Enterprise.AddRepositoriesToInstallation(ctx, "\n", "\n", -1, input) + _, _, err = client.Enterprise.AddRepositoriesToAppInstallation(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.Enterprise.AddRepositoriesToInstallation(ctx, "e", "o", 1, input) + _, resp, err := client.Enterprise.AddRepositoriesToAppInstallation(ctx, "e", "o", 1, input) return resp, err }) } -func TestEnterpriseService_RemoveRepositoriesFromInstallation(t *testing.T) { +func TestEnterpriseService_RemoveRepositoriesFromAppInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := EnterpriseInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + input := &AppInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/remove", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") testBody(t, r, `{"selected_repository_ids":[1,2]}`+"\n") - fmt.Fprint(w, `{"total_count":2, "repositories":[{"id":1},{"id":2}]}`) + fmt.Fprint(w, `[{"id":1},{"id":2}]`) }) ctx := t.Context() - repos, _, err := client.Enterprise.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) + repos, _, err := client.Enterprise.RemoveRepositoriesFromAppInstallation(ctx, "e", "o", 1, input) if err != nil { - t.Errorf("Enterprise.RemoveRepositoriesFromInstallation returned error: %v", err) + t.Errorf("Enterprise.RemoveRepositoriesFromAppInstallation returned error: %v", err) } - want := &ListRepositories{TotalCount: Ptr(2), Repositories: []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} + want := []*AccessibleRepository{{ID: 1}, {ID: 2}} if diff := cmp.Diff(repos, want); diff != "" { - t.Errorf("Enterprise.RemoveRepositoriesFromInstallation returned diff (-want +got):\n%v", diff) + t.Errorf("Enterprise.RemoveRepositoriesFromAppInstallation returned diff (-want +got):\n%v", diff) } - const methodName = "RemoveRepositoriesFromInstallation" + const methodName = "RemoveRepositoriesFromAppInstallation" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Enterprise.RemoveRepositoriesFromInstallation(ctx, "\n", "\n", -1, input) + _, _, err = client.Enterprise.RemoveRepositoriesFromAppInstallation(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - _, resp, err := client.Enterprise.RemoveRepositoriesFromInstallation(ctx, "e", "o", 1, input) + _, resp, err := client.Enterprise.RemoveRepositoriesFromAppInstallation(ctx, "e", "o", 1, input) return resp, err }) } diff --git a/github/github-accessors.go b/github/github-accessors.go index e060c582bea..bef89aad127 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9254,14 +9254,6 @@ func (e *EnterpriseCustomPropertiesValues) GetOrganizationLogin() string { return *e.OrganizationLogin } -// GetRepositorySelection returns the RepositorySelection field if it's non-nil, zero value otherwise. -func (e *EnterpriseInstallationRepositoriesToggleOptions) GetRepositorySelection() string { - if e == nil || e.RepositorySelection == nil { - return "" - } - return *e.RepositorySelection -} - // GetEnterpriseServerUser returns the EnterpriseServerUser field if it's non-nil, zero value otherwise. func (e *EnterpriseLicensedUsers) GetEnterpriseServerUser() bool { if e == nil || e.EnterpriseServerUser == nil { @@ -29470,6 +29462,14 @@ func (t *TreeEntry) GetURL() string { return *t.URL } +// GetRepositorySelection returns the RepositorySelection field if it's non-nil, zero value otherwise. +func (u *UpdateAppInstallationRepositoriesOptions) GetRepositorySelection() string { + if u == nil || u.RepositorySelection == nil { + return "" + } + return *u.RepositorySelection +} + // GetPath returns the Path field if it's non-nil, zero value otherwise. func (u *UpdateAttributeForSCIMUserOperations) GetPath() string { if u == nil || u.Path == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 9a853f94e12..f2dab20e030 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -11985,17 +11985,6 @@ func TestEnterpriseCustomPropertiesValues_GetOrganizationLogin(tt *testing.T) { e.GetOrganizationLogin() } -func TestEnterpriseInstallationRepositoriesToggleOptions_GetRepositorySelection(tt *testing.T) { - tt.Parallel() - var zeroValue string - e := &EnterpriseInstallationRepositoriesToggleOptions{RepositorySelection: &zeroValue} - e.GetRepositorySelection() - e = &EnterpriseInstallationRepositoriesToggleOptions{} - e.GetRepositorySelection() - e = nil - e.GetRepositorySelection() -} - func TestEnterpriseLicensedUsers_GetEnterpriseServerUser(tt *testing.T) { tt.Parallel() var zeroValue bool @@ -37979,6 +37968,17 @@ func TestTreeEntry_GetURL(tt *testing.T) { t.GetURL() } +func TestUpdateAppInstallationRepositoriesOptions_GetRepositorySelection(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UpdateAppInstallationRepositoriesOptions{RepositorySelection: &zeroValue} + u.GetRepositorySelection() + u = &UpdateAppInstallationRepositoriesOptions{} + u.GetRepositorySelection() + u = nil + u.GetRepositorySelection() +} + func TestUpdateAttributeForSCIMUserOperations_GetPath(tt *testing.T) { tt.Parallel() var zeroValue string From 5d9326e116f6aa44b501f94221dd48827bf00fd9 Mon Sep 17 00:00:00 2001 From: Nithish S Date: Fri, 28 Nov 2025 22:23:39 -0800 Subject: [PATCH 7/7] refactor: change options parameters from pointer to value in enterprise app repository functions and tests --- github/enterprise_apps.go | 6 +++--- github/enterprise_apps_test.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/github/enterprise_apps.go b/github/enterprise_apps.go index 92e9d3a5a22..3fc0df7436d 100644 --- a/github/enterprise_apps.go +++ b/github/enterprise_apps.go @@ -57,7 +57,7 @@ func (s *EnterpriseService) ListRepositoriesForOrgAppInstallation(ctx context.Co // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#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 *UpdateAppInstallationRepositoriesOptions) (*Installation, *Response, error) { +func (s *EnterpriseService) UpdateAppInstallationRepositories(ctx context.Context, enterprise, org string, installationID int64, opts UpdateAppInstallationRepositoriesOptions) (*Installation, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { @@ -78,7 +78,7 @@ func (s *EnterpriseService) UpdateAppInstallationRepositories(ctx context.Contex // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#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 *AppInstallationRepositoriesOptions) ([]*AccessibleRepository, *Response, error) { +func (s *EnterpriseService) AddRepositoriesToAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts AppInstallationRepositoriesOptions) ([]*AccessibleRepository, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/add", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { @@ -99,7 +99,7 @@ func (s *EnterpriseService) AddRepositoriesToAppInstallation(ctx context.Context // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/organization-installations#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 *AppInstallationRepositoriesOptions) ([]*AccessibleRepository, *Response, error) { +func (s *EnterpriseService) RemoveRepositoriesFromAppInstallation(ctx context.Context, enterprise, org string, installationID int64, opts AppInstallationRepositoriesOptions) ([]*AccessibleRepository, *Response, error) { u := fmt.Sprintf("enterprises/%v/apps/organizations/%v/installations/%v/repositories/remove", enterprise, org, installationID) req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { diff --git a/github/enterprise_apps_test.go b/github/enterprise_apps_test.go index 9d94423384c..5b53b28d8b6 100644 --- a/github/enterprise_apps_test.go +++ b/github/enterprise_apps_test.go @@ -50,7 +50,7 @@ func TestEnterpriseService_UpdateAppInstallationRepositories(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &UpdateAppInstallationRepositoriesOptions{ + input := UpdateAppInstallationRepositoriesOptions{ RepositorySelection: String("selected"), SelectedRepositoryIDs: []int64{1, 2}, } @@ -88,7 +88,7 @@ func TestEnterpriseService_AddRepositoriesToAppInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &AppInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + input := AppInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/add", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") @@ -123,7 +123,7 @@ func TestEnterpriseService_RemoveRepositoriesFromAppInstallation(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &AppInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} + input := AppInstallationRepositoriesOptions{SelectedRepositoryIDs: []int64{1, 2}} mux.HandleFunc("/enterprises/e/apps/organizations/o/installations/1/repositories/remove", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH")