From 98f4d6e849a36c428aaacf1019ad46b3cd717020 Mon Sep 17 00:00:00 2001 From: Tens1de Date: Mon, 7 Sep 2026 10:28:31 +0300 Subject: [PATCH 1/2] feat: Add Copilot custom agents enterprise endpoints Fixes #4524 --- github/copilot_custom_agents.go | 152 +++++++++++++++ github/copilot_custom_agents_test.go | 273 +++++++++++++++++++++++++++ github/github-accessors.go | 144 ++++++++++++++ github/github-accessors_test.go | 186 ++++++++++++++++++ github/github-iterators.go | 35 ++++ github/github-iterators_test.go | 72 +++++++ 6 files changed, 862 insertions(+) create mode 100644 github/copilot_custom_agents.go create mode 100644 github/copilot_custom_agents_test.go diff --git a/github/copilot_custom_agents.go b/github/copilot_custom_agents.go new file mode 100644 index 00000000000..d6475bbf6cd --- /dev/null +++ b/github/copilot_custom_agents.go @@ -0,0 +1,152 @@ +// Copyright 2026 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" +) + +// CopilotCustomAgent represents a custom agent defined in an enterprise source repository. +type CopilotCustomAgent struct { + Name *string `json:"name,omitempty"` + FilePath *string `json:"file_path,omitempty"` + URL *string `json:"url,omitempty"` +} + +// EnterpriseCustomAgents represents the list of custom agents for an enterprise. +type EnterpriseCustomAgents struct { + CustomAgents []*CopilotCustomAgent `json:"custom_agents"` +} + +// CopilotCustomAgentsSourceOrganization represents the organization configured as +// the custom agents source for an enterprise. +type CopilotCustomAgentsSourceOrganization struct { + ID *int64 `json:"id,omitempty"` + Login *string `json:"login,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` +} + +// CopilotCustomAgentsSourceRepository represents the repository that stores custom agent definitions. +type CopilotCustomAgentsSourceRepository struct { + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + FullName *string `json:"full_name,omitempty"` +} + +// CopilotCustomAgentsSourceRuleset represents the ruleset created to protect agent definition files. +type CopilotCustomAgentsSourceRuleset struct { + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Enforcement *string `json:"enforcement,omitempty"` +} + +// CopilotCustomAgentsSource represents the source organization and repository for +// enterprise custom agents (and optionally a protecting ruleset). +type CopilotCustomAgentsSource struct { + Organization *CopilotCustomAgentsSourceOrganization `json:"organization"` + Repository *CopilotCustomAgentsSourceRepository `json:"repository"` + Ruleset *CopilotCustomAgentsSourceRuleset `json:"ruleset,omitempty"` +} + +// SetCopilotCustomAgentsSourceRequest is the request body for setting the custom agents source. +type SetCopilotCustomAgentsSourceRequest struct { + // OrganizationID is the ID of the organization to use as the custom agents source. + OrganizationID int64 `json:"organization_id"` + // CreateRuleset controls whether to create a ruleset to protect agent definition files. + // Defaults to true when omitted. + CreateRuleset *bool `json:"create_ruleset,omitempty"` +} + +// ListEnterpriseCustomAgents gets the list of custom agents defined for an enterprise. +// +// If no source repository has been configured, CustomAgents may be nil. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-custom-agents?apiVersion=2022-11-28#get-custom-agents-for-an-enterprise +// +//meta:operation GET /enterprises/{enterprise}/copilot/custom-agents +func (s *CopilotService) ListEnterpriseCustomAgents(ctx context.Context, enterprise string, opts *ListOptions) (*EnterpriseCustomAgents, *Response, error) { + u := fmt.Sprintf("enterprises/%v/copilot/custom-agents", enterprise) + 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 agents *EnterpriseCustomAgents + resp, err := s.client.Do(req, &agents) + if err != nil { + return nil, resp, err + } + + return agents, resp, nil +} + +// GetEnterpriseCustomAgentsSource gets the organization and repository configured as +// the source for custom agent definitions in an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-custom-agents?apiVersion=2022-11-28#get-the-source-organization-for-custom-agents-in-an-enterprise +// +//meta:operation GET /enterprises/{enterprise}/copilot/custom-agents/source +func (s *CopilotService) GetEnterpriseCustomAgentsSource(ctx context.Context, enterprise string) (*CopilotCustomAgentsSource, *Response, error) { + u := fmt.Sprintf("enterprises/%v/copilot/custom-agents/source", enterprise) + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var source *CopilotCustomAgentsSource + resp, err := s.client.Do(req, &source) + if err != nil { + return nil, resp, err + } + + return source, resp, nil +} + +// SetEnterpriseCustomAgentsSource sets an organization as the source for custom agent +// definitions in an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-custom-agents?apiVersion=2022-11-28#set-the-source-organization-for-custom-agents-in-an-enterprise +// +//meta:operation PUT /enterprises/{enterprise}/copilot/custom-agents/source +func (s *CopilotService) SetEnterpriseCustomAgentsSource(ctx context.Context, enterprise string, request SetCopilotCustomAgentsSourceRequest) (*CopilotCustomAgentsSource, *Response, error) { + u := fmt.Sprintf("enterprises/%v/copilot/custom-agents/source", enterprise) + + req, err := s.client.NewRequest(ctx, "PUT", u, request) + if err != nil { + return nil, nil, err + } + + var source *CopilotCustomAgentsSource + resp, err := s.client.Do(req, &source) + if err != nil { + return nil, resp, err + } + + return source, resp, nil +} + +// DeleteEnterpriseCustomAgentsSource removes the custom agents source configuration for an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-custom-agents?apiVersion=2022-11-28#delete-the-custom-agents-source-for-an-enterprise +// +//meta:operation DELETE /enterprises/{enterprise}/copilot/custom-agents/source +func (s *CopilotService) DeleteEnterpriseCustomAgentsSource(ctx context.Context, enterprise string) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/copilot/custom-agents/source", enterprise) + + req, err := s.client.NewRequest(ctx, "DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/github/copilot_custom_agents_test.go b/github/copilot_custom_agents_test.go new file mode 100644 index 00000000000..7fa3f3a3456 --- /dev/null +++ b/github/copilot_custom_agents_test.go @@ -0,0 +1,273 @@ +// Copyright 2026 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 ( + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestCopilotService_ListEnterpriseCustomAgents(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/copilot/custom-agents", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "2", "per_page": "10"}) + fmt.Fprint(w, `{ + "custom_agents": [ + { + "name": "performance-optimizer", + "file_path": "agents/performance-optimizer.agent.md", + "url": "https://github.com/octo-org/.github-private/blob/main/agents/performance-optimizer.agent.md" + }, + { + "name": "security-reviewer", + "file_path": "agents/security-reviewer.agent.md", + "url": "https://github.com/octo-org/.github-private/blob/main/agents/security-reviewer.agent.md" + } + ] + }`) + }) + + opts := &ListOptions{Page: 2, PerPage: 10} + ctx := t.Context() + got, _, err := client.Copilot.ListEnterpriseCustomAgents(ctx, "e", opts) + if err != nil { + t.Errorf("Copilot.ListEnterpriseCustomAgents returned error: %v", err) + } + + want := &EnterpriseCustomAgents{ + CustomAgents: []*CopilotCustomAgent{ + { + Name: new("performance-optimizer"), + FilePath: new("agents/performance-optimizer.agent.md"), + URL: new("https://github.com/octo-org/.github-private/blob/main/agents/performance-optimizer.agent.md"), + }, + { + Name: new("security-reviewer"), + FilePath: new("agents/security-reviewer.agent.md"), + URL: new("https://github.com/octo-org/.github-private/blob/main/agents/security-reviewer.agent.md"), + }, + }, + } + if !cmp.Equal(got, want) { + t.Errorf("Copilot.ListEnterpriseCustomAgents returned %+v, want %+v", got, want) + } + + const methodName = "ListEnterpriseCustomAgents" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Copilot.ListEnterpriseCustomAgents(ctx, "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Copilot.ListEnterpriseCustomAgents(ctx, "e", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCopilotService_ListEnterpriseCustomAgents_NullAgents(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/copilot/custom-agents", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"custom_agents": null}`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.ListEnterpriseCustomAgents(ctx, "e", nil) + if err != nil { + t.Errorf("Copilot.ListEnterpriseCustomAgents returned error: %v", err) + } + + want := &EnterpriseCustomAgents{CustomAgents: nil} + if !cmp.Equal(got, want) { + t.Errorf("Copilot.ListEnterpriseCustomAgents returned %+v, want %+v", got, want) + } +} + +func TestCopilotService_GetEnterpriseCustomAgentsSource(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/copilot/custom-agents/source", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "organization": { + "id": 1, + "login": "octo-org" + }, + "repository": { + "id": 2, + "name": ".github-private", + "full_name": "octo-org/.github-private" + } + }`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.GetEnterpriseCustomAgentsSource(ctx, "e") + if err != nil { + t.Errorf("Copilot.GetEnterpriseCustomAgentsSource returned error: %v", err) + } + + want := &CopilotCustomAgentsSource{ + Organization: &CopilotCustomAgentsSourceOrganization{ + ID: new(int64(1)), + Login: new("octo-org"), + }, + Repository: &CopilotCustomAgentsSourceRepository{ + ID: new(int64(2)), + Name: new(".github-private"), + FullName: new("octo-org/.github-private"), + }, + } + if !cmp.Equal(got, want) { + t.Errorf("Copilot.GetEnterpriseCustomAgentsSource returned %+v, want %+v", got, want) + } + + const methodName = "GetEnterpriseCustomAgentsSource" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Copilot.GetEnterpriseCustomAgentsSource(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Copilot.GetEnterpriseCustomAgentsSource(ctx, "e") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCopilotService_GetEnterpriseCustomAgentsSource_Null(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/copilot/custom-agents/source", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"organization": null, "repository": null}`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.GetEnterpriseCustomAgentsSource(ctx, "e") + if err != nil { + t.Errorf("Copilot.GetEnterpriseCustomAgentsSource returned error: %v", err) + } + + want := &CopilotCustomAgentsSource{} + if !cmp.Equal(got, want) { + t.Errorf("Copilot.GetEnterpriseCustomAgentsSource returned %+v, want %+v", got, want) + } +} + +func TestCopilotService_SetEnterpriseCustomAgentsSource(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + input := SetCopilotCustomAgentsSourceRequest{ + OrganizationID: 123, + CreateRuleset: new(false), + } + + mux.HandleFunc("/enterprises/e/copilot/custom-agents/source", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testJSONBody(t, r, input) + fmt.Fprint(w, `{ + "organization": { + "id": 123, + "login": "octo-org", + "avatar_url": "https://github.com/images/error/octocat_happy.gif" + }, + "repository": { + "id": 2, + "name": ".github-private", + "full_name": "octo-org/.github-private" + }, + "ruleset": { + "id": 42, + "name": "Protect custom agents", + "enforcement": "active" + } + }`) + }) + + ctx := t.Context() + got, _, err := client.Copilot.SetEnterpriseCustomAgentsSource(ctx, "e", input) + if err != nil { + t.Errorf("Copilot.SetEnterpriseCustomAgentsSource returned error: %v", err) + } + + want := &CopilotCustomAgentsSource{ + Organization: &CopilotCustomAgentsSourceOrganization{ + ID: new(int64(123)), + Login: new("octo-org"), + AvatarURL: new("https://github.com/images/error/octocat_happy.gif"), + }, + Repository: &CopilotCustomAgentsSourceRepository{ + ID: new(int64(2)), + Name: new(".github-private"), + FullName: new("octo-org/.github-private"), + }, + Ruleset: &CopilotCustomAgentsSourceRuleset{ + ID: new(int64(42)), + Name: new("Protect custom agents"), + Enforcement: new("active"), + }, + } + if !cmp.Equal(got, want) { + t.Errorf("Copilot.SetEnterpriseCustomAgentsSource returned %+v, want %+v", got, want) + } + + const methodName = "SetEnterpriseCustomAgentsSource" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Copilot.SetEnterpriseCustomAgentsSource(ctx, "\n", input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Copilot.SetEnterpriseCustomAgentsSource(ctx, "e", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCopilotService_DeleteEnterpriseCustomAgentsSource(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/copilot/custom-agents/source", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + ctx := t.Context() + _, err := client.Copilot.DeleteEnterpriseCustomAgentsSource(ctx, "e") + if err != nil { + t.Errorf("Copilot.DeleteEnterpriseCustomAgentsSource returned error: %v", err) + } + + const methodName = "DeleteEnterpriseCustomAgentsSource" + testBadOptions(t, methodName, func() (err error) { + _, err = client.Copilot.DeleteEnterpriseCustomAgentsSource(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Copilot.DeleteEnterpriseCustomAgentsSource(ctx, "e") + }) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index b9ce167b413..a98a7e30293 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -9094,6 +9094,126 @@ func (c *CopilotCodeReviewRuleParameters) GetReviewOnPush() bool { return c.ReviewOnPush } +// GetFilePath returns the FilePath field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgent) GetFilePath() string { + if c == nil || c.FilePath == nil { + return "" + } + return *c.FilePath +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgent) GetName() string { + if c == nil || c.Name == nil { + return "" + } + return *c.Name +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgent) GetURL() string { + if c == nil || c.URL == nil { + return "" + } + return *c.URL +} + +// GetOrganization returns the Organization field. +func (c *CopilotCustomAgentsSource) GetOrganization() *CopilotCustomAgentsSourceOrganization { + if c == nil { + return nil + } + return c.Organization +} + +// GetRepository returns the Repository field. +func (c *CopilotCustomAgentsSource) GetRepository() *CopilotCustomAgentsSourceRepository { + if c == nil { + return nil + } + return c.Repository +} + +// GetRuleset returns the Ruleset field. +func (c *CopilotCustomAgentsSource) GetRuleset() *CopilotCustomAgentsSourceRuleset { + if c == nil { + return nil + } + return c.Ruleset +} + +// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceOrganization) GetAvatarURL() string { + if c == nil || c.AvatarURL == nil { + return "" + } + return *c.AvatarURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceOrganization) GetID() int64 { + if c == nil || c.ID == nil { + return 0 + } + return *c.ID +} + +// GetLogin returns the Login field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceOrganization) GetLogin() string { + if c == nil || c.Login == nil { + return "" + } + return *c.Login +} + +// GetFullName returns the FullName field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceRepository) GetFullName() string { + if c == nil || c.FullName == nil { + return "" + } + return *c.FullName +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceRepository) GetID() int64 { + if c == nil || c.ID == nil { + return 0 + } + return *c.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceRepository) GetName() string { + if c == nil || c.Name == nil { + return "" + } + return *c.Name +} + +// GetEnforcement returns the Enforcement field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceRuleset) GetEnforcement() string { + if c == nil || c.Enforcement == nil { + return "" + } + return *c.Enforcement +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceRuleset) GetID() int64 { + if c == nil || c.ID == nil { + return 0 + } + return *c.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (c *CopilotCustomAgentsSourceRuleset) GetName() string { + if c == nil || c.Name == nil { + return "" + } + return *c.Name +} + // GetCodeAcceptanceActivityCount returns the CodeAcceptanceActivityCount field if it's non-nil, zero value otherwise. func (c *CopilotDailyMetrics) GetCodeAcceptanceActivityCount() int { if c == nil || c.CodeAcceptanceActivityCount == nil { @@ -16622,6 +16742,14 @@ func (e *EnterpriseCreateOrUpdateBudgetResponse) GetMessage() string { return e.Message } +// GetCustomAgents returns the CustomAgents slice if it's non-nil, nil otherwise. +func (e *EnterpriseCustomAgents) GetCustomAgents() []*CopilotCustomAgent { + if e == nil || e.CustomAgents == nil { + return nil + } + return e.CustomAgents +} + // GetOrganizationID returns the OrganizationID field if it's non-nil, zero value otherwise. func (e *EnterpriseCustomPropertiesValues) GetOrganizationID() int64 { if e == nil || e.OrganizationID == nil { @@ -42214,6 +42342,22 @@ func (s *ServiceInstanceItems) GetType() string { return s.Type } +// GetCreateRuleset returns the CreateRuleset field if it's non-nil, zero value otherwise. +func (s *SetCopilotCustomAgentsSourceRequest) GetCreateRuleset() bool { + if s == nil || s.CreateRuleset == nil { + return false + } + return *s.CreateRuleset +} + +// GetOrganizationID returns the OrganizationID field. +func (s *SetCopilotCustomAgentsSourceRequest) GetOrganizationID() int64 { + if s == nil { + return 0 + } + return s.OrganizationID +} + // GetSelectedOrganizationIDs returns the SelectedOrganizationIDs slice if it's non-nil, nil otherwise. func (s *SetOrgAccessRunnerGroupRequest) GetSelectedOrganizationIDs() []int64 { if s == nil || s.SelectedOrganizationIDs == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index bc822744add..7dfb59c3496 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -11600,6 +11600,162 @@ func TestCopilotCodeReviewRuleParameters_GetReviewOnPush(tt *testing.T) { c.GetReviewOnPush() } +func TestCopilotCustomAgent_GetFilePath(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgent{FilePath: &zeroValue} + c.GetFilePath() + c = &CopilotCustomAgent{} + c.GetFilePath() + c = nil + c.GetFilePath() +} + +func TestCopilotCustomAgent_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgent{Name: &zeroValue} + c.GetName() + c = &CopilotCustomAgent{} + c.GetName() + c = nil + c.GetName() +} + +func TestCopilotCustomAgent_GetURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgent{URL: &zeroValue} + c.GetURL() + c = &CopilotCustomAgent{} + c.GetURL() + c = nil + c.GetURL() +} + +func TestCopilotCustomAgentsSource_GetOrganization(tt *testing.T) { + tt.Parallel() + c := &CopilotCustomAgentsSource{} + c.GetOrganization() + c = nil + c.GetOrganization() +} + +func TestCopilotCustomAgentsSource_GetRepository(tt *testing.T) { + tt.Parallel() + c := &CopilotCustomAgentsSource{} + c.GetRepository() + c = nil + c.GetRepository() +} + +func TestCopilotCustomAgentsSource_GetRuleset(tt *testing.T) { + tt.Parallel() + c := &CopilotCustomAgentsSource{} + c.GetRuleset() + c = nil + c.GetRuleset() +} + +func TestCopilotCustomAgentsSourceOrganization_GetAvatarURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgentsSourceOrganization{AvatarURL: &zeroValue} + c.GetAvatarURL() + c = &CopilotCustomAgentsSourceOrganization{} + c.GetAvatarURL() + c = nil + c.GetAvatarURL() +} + +func TestCopilotCustomAgentsSourceOrganization_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + c := &CopilotCustomAgentsSourceOrganization{ID: &zeroValue} + c.GetID() + c = &CopilotCustomAgentsSourceOrganization{} + c.GetID() + c = nil + c.GetID() +} + +func TestCopilotCustomAgentsSourceOrganization_GetLogin(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgentsSourceOrganization{Login: &zeroValue} + c.GetLogin() + c = &CopilotCustomAgentsSourceOrganization{} + c.GetLogin() + c = nil + c.GetLogin() +} + +func TestCopilotCustomAgentsSourceRepository_GetFullName(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgentsSourceRepository{FullName: &zeroValue} + c.GetFullName() + c = &CopilotCustomAgentsSourceRepository{} + c.GetFullName() + c = nil + c.GetFullName() +} + +func TestCopilotCustomAgentsSourceRepository_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + c := &CopilotCustomAgentsSourceRepository{ID: &zeroValue} + c.GetID() + c = &CopilotCustomAgentsSourceRepository{} + c.GetID() + c = nil + c.GetID() +} + +func TestCopilotCustomAgentsSourceRepository_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgentsSourceRepository{Name: &zeroValue} + c.GetName() + c = &CopilotCustomAgentsSourceRepository{} + c.GetName() + c = nil + c.GetName() +} + +func TestCopilotCustomAgentsSourceRuleset_GetEnforcement(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgentsSourceRuleset{Enforcement: &zeroValue} + c.GetEnforcement() + c = &CopilotCustomAgentsSourceRuleset{} + c.GetEnforcement() + c = nil + c.GetEnforcement() +} + +func TestCopilotCustomAgentsSourceRuleset_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + c := &CopilotCustomAgentsSourceRuleset{ID: &zeroValue} + c.GetID() + c = &CopilotCustomAgentsSourceRuleset{} + c.GetID() + c = nil + c.GetID() +} + +func TestCopilotCustomAgentsSourceRuleset_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CopilotCustomAgentsSourceRuleset{Name: &zeroValue} + c.GetName() + c = &CopilotCustomAgentsSourceRuleset{} + c.GetName() + c = nil + c.GetName() +} + func TestCopilotDailyMetrics_GetCodeAcceptanceActivityCount(tt *testing.T) { tt.Parallel() var zeroValue int @@ -20910,6 +21066,17 @@ func TestEnterpriseCreateOrUpdateBudgetResponse_GetMessage(tt *testing.T) { e.GetMessage() } +func TestEnterpriseCustomAgents_GetCustomAgents(tt *testing.T) { + tt.Parallel() + zeroValue := []*CopilotCustomAgent{} + e := &EnterpriseCustomAgents{CustomAgents: zeroValue} + e.GetCustomAgents() + e = &EnterpriseCustomAgents{} + e.GetCustomAgents() + e = nil + e.GetCustomAgents() +} + func TestEnterpriseCustomPropertiesValues_GetOrganizationID(tt *testing.T) { tt.Parallel() var zeroValue int64 @@ -52739,6 +52906,25 @@ func TestServiceInstanceItems_GetType(tt *testing.T) { s.GetType() } +func TestSetCopilotCustomAgentsSourceRequest_GetCreateRuleset(tt *testing.T) { + tt.Parallel() + var zeroValue bool + s := &SetCopilotCustomAgentsSourceRequest{CreateRuleset: &zeroValue} + s.GetCreateRuleset() + s = &SetCopilotCustomAgentsSourceRequest{} + s.GetCreateRuleset() + s = nil + s.GetCreateRuleset() +} + +func TestSetCopilotCustomAgentsSourceRequest_GetOrganizationID(tt *testing.T) { + tt.Parallel() + s := &SetCopilotCustomAgentsSourceRequest{} + s.GetOrganizationID() + s = nil + s.GetOrganizationID() +} + func TestSetOrgAccessRunnerGroupRequest_GetSelectedOrganizationIDs(tt *testing.T) { tt.Parallel() zeroValue := []int64{} diff --git a/github/github-iterators.go b/github/github-iterators.go index 22a485af004..17f7062eefa 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -2568,6 +2568,41 @@ func (s *CopilotService) ListCopilotSeatsIter(ctx context.Context, org string, o } } +// ListEnterpriseCustomAgentsIter returns an iterator that paginates through all results of ListEnterpriseCustomAgents. +func (s *CopilotService) ListEnterpriseCustomAgentsIter(ctx context.Context, enterprise string, opts *ListOptions) iter.Seq2[*CopilotCustomAgent, error] { + return func(yield func(*CopilotCustomAgent, error) bool) { + // Create a copy of opts to avoid mutating the caller's struct + if opts == nil { + opts = &ListOptions{} + } else { + opts = new(*opts) + } + + for { + results, resp, err := s.ListEnterpriseCustomAgents(ctx, enterprise, opts) + if err != nil { + yield(nil, err) + return + } + + var iterItems []*CopilotCustomAgent + if results != nil { + iterItems = results.CustomAgents + } + for _, item := range iterItems { + if !yield(item, nil) { + return + } + } + + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + } +} + // ListOrganizationCodingAgentRepositoriesIter returns an iterator that paginates through all results of ListOrganizationCodingAgentRepositories. func (s *CopilotService) ListOrganizationCodingAgentRepositoriesIter(ctx context.Context, org string, opts *ListOptions) iter.Seq2[*Repository, error] { return func(yield func(*Repository, error) bool) { diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index e590fba8703..70af5e50827 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -5487,6 +5487,78 @@ func TestCopilotService_ListCopilotSeatsIter(t *testing.T) { } } +func TestCopilotService_ListEnterpriseCustomAgentsIter(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + var callNum int + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + callNum++ + switch callNum { + case 1: + w.Header().Set("Link", `; rel="next"`) + fmt.Fprint(w, `{"custom_agents": [{},{},{}]}`) + case 2: + fmt.Fprint(w, `{"custom_agents": [{},{},{},{}]}`) + case 3: + fmt.Fprint(w, `{"custom_agents": [{},{}]}`) + case 4: + w.WriteHeader(http.StatusNotFound) + case 5: + fmt.Fprint(w, `{"custom_agents": [{},{}]}`) + } + }) + + iter := client.Copilot.ListEnterpriseCustomAgentsIter(t.Context(), "", nil) + var gotItems int + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 7; gotItems != want { + t.Errorf("client.Copilot.ListEnterpriseCustomAgentsIter call 1 got %v items; want %v", gotItems, want) + } + + opts := &ListOptions{} + iter = client.Copilot.ListEnterpriseCustomAgentsIter(t.Context(), "", opts) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 2; gotItems != want { + t.Errorf("client.Copilot.ListEnterpriseCustomAgentsIter call 2 got %v items; want %v", gotItems, want) + } + + iter = client.Copilot.ListEnterpriseCustomAgentsIter(t.Context(), "", nil) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err == nil { + t.Error("expected error; got nil") + } + } + if gotItems != 1 { + t.Errorf("client.Copilot.ListEnterpriseCustomAgentsIter call 3 got %v items; want 1 (an error)", gotItems) + } + + iter = client.Copilot.ListEnterpriseCustomAgentsIter(t.Context(), "", nil) + gotItems = 0 + iter(func(item *CopilotCustomAgent, err error) bool { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + return false + }) + if gotItems != 1 { + t.Errorf("client.Copilot.ListEnterpriseCustomAgentsIter call 4 got %v items; want 1 (an error)", gotItems) + } +} + func TestCopilotService_ListOrganizationCodingAgentRepositoriesIter(t *testing.T) { t.Parallel() client, mux, _ := setup(t) From b327cc8ffa974725e9627c205dad93b62bf96d5e Mon Sep 17 00:00:00 2001 From: Tens1de Date: Mon, 7 Sep 2026 11:04:50 +0300 Subject: [PATCH 2/2] fix: rename request body parameter to body for paramcheck --- github/copilot_custom_agents.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/copilot_custom_agents.go b/github/copilot_custom_agents.go index d6475bbf6cd..577497d011e 100644 --- a/github/copilot_custom_agents.go +++ b/github/copilot_custom_agents.go @@ -118,10 +118,10 @@ func (s *CopilotService) GetEnterpriseCustomAgentsSource(ctx context.Context, en // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-custom-agents?apiVersion=2022-11-28#set-the-source-organization-for-custom-agents-in-an-enterprise // //meta:operation PUT /enterprises/{enterprise}/copilot/custom-agents/source -func (s *CopilotService) SetEnterpriseCustomAgentsSource(ctx context.Context, enterprise string, request SetCopilotCustomAgentsSourceRequest) (*CopilotCustomAgentsSource, *Response, error) { +func (s *CopilotService) SetEnterpriseCustomAgentsSource(ctx context.Context, enterprise string, body SetCopilotCustomAgentsSourceRequest) (*CopilotCustomAgentsSource, *Response, error) { u := fmt.Sprintf("enterprises/%v/copilot/custom-agents/source", enterprise) - req, err := s.client.NewRequest(ctx, "PUT", u, request) + req, err := s.client.NewRequest(ctx, "PUT", u, body) if err != nil { return nil, nil, err }