From 9adf0ba7f0bca93323d50ac036b9bb5525f23354 Mon Sep 17 00:00:00 2001 From: munlicode Date: Wed, 25 Feb 2026 21:48:37 +0500 Subject: [PATCH 1/5] feat: Add Type field to Team struct --- github/copilot_test.go | 8 ++++---- github/github-accessors.go | 8 ++++++++ github/github-accessors_test.go | 11 +++++++++++ github/github-stringify_test.go | 3 ++- github/teams.go | 4 ++++ github/teams_test.go | 12 +++++++----- 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/github/copilot_test.go b/github/copilot_test.go index 823ac92043e..2565b330a64 100644 --- a/github/copilot_test.go +++ b/github/copilot_test.go @@ -207,7 +207,8 @@ func TestCopilotService_GetSeatDetailsTeam(t *testing.T) { } want := &Team{ - ID: Ptr(int64(1)), + ID: Ptr(int64(1)), + Type: Ptr("Team"), } if got, ok := seatDetails.GetTeam(); ok && !cmp.Equal(got, want) { @@ -575,6 +576,7 @@ func TestCopilotService_ListCopilotSeats(t *testing.T) { Assignee: &Team{ ID: Ptr(int64(1)), Name: Ptr("octokittens"), + Type: Ptr("Team"), }, AssigningTeam: nil, CreatedAt: &createdAt2, @@ -599,9 +601,7 @@ func TestCopilotService_ListCopilotSeats(t *testing.T) { }, } - if !cmp.Equal(got, want) { - t.Errorf("Copilot.ListCopilotSeats returned %+v, want %+v", got, want) - } + assertNoDiff(t, want, got) const methodName = "ListCopilotSeats" diff --git a/github/github-accessors.go b/github/github-accessors.go index 73ff2a4f3fa..70b20e70dc9 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -29358,6 +29358,14 @@ func (t *Team) GetSlug() string { return *t.Slug } +// GetType returns the Type field if it's non-nil, zero value otherwise. +func (t *Team) GetType() string { + if t == nil || t.Type == nil { + return "" + } + return *t.Type +} + // GetURL returns the URL field if it's non-nil, zero value otherwise. func (t *Team) GetURL() string { if t == nil || t.URL == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index ef28f61d699..c9441a749c0 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -37861,6 +37861,17 @@ func TestTeam_GetSlug(tt *testing.T) { t.GetSlug() } +func TestTeam_GetType(tt *testing.T) { + tt.Parallel() + var zeroValue string + t := &Team{Type: &zeroValue} + t.GetType() + t = &Team{} + t.GetType() + t = nil + t.GetType() +} + func TestTeam_GetURL(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index e134a127a91..edd28ddb50a 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -2251,8 +2251,9 @@ func TestTeam_String(t *testing.T) { Parent: &Team{}, LDAPDN: Ptr(""), Assignment: Ptr(""), + Type: Ptr(""), } - want := `github.Team{ID:0, NodeID:"", Name:"", Description:"", URL:"", Slug:"", Permission:"", Privacy:"", NotificationSetting:"", MembersCount:0, ReposCount:0, Organization:github.Organization{}, HTMLURL:"", MembersURL:"", RepositoriesURL:"", Parent:github.Team{}, LDAPDN:"", Assignment:""}` + want := `github.Team{ID:0, NodeID:"", Name:"", Description:"", URL:"", Slug:"", Permission:"", Privacy:"", NotificationSetting:"", MembersCount:0, ReposCount:0, Organization:github.Organization{}, HTMLURL:"", MembersURL:"", RepositoriesURL:"", Parent:github.Team{}, LDAPDN:"", Assignment:"", Type:""}` if got := v.String(); got != want { t.Errorf("Team.String = %v, want %v", got, want) } diff --git a/github/teams.go b/github/teams.go index e4d7e9c4aca..cf9a616d3fd 100644 --- a/github/teams.go +++ b/github/teams.go @@ -60,6 +60,10 @@ type Team struct { // possible values are: "direct", "indirect", "mixed". This is only populated when // calling the ListTeamsAssignedToOrgRole method. Assignment *string `json:"assignment,omitempty"` + + // Type identifies the ownership type of the team + // Possible values are: "organization", "enterprise". + Type *string `json:"type,omitempty"` } func (t Team) String() string { diff --git a/github/teams_test.go b/github/teams_test.go index 735d86c3a57..c1de4fea406 100644 --- a/github/teams_test.go +++ b/github/teams_test.go @@ -68,7 +68,7 @@ func TestTeamsService_GetTeamByID(t *testing.T) { mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`) + fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "type": "organization", "parent":null}`) }) ctx := t.Context() @@ -77,7 +77,7 @@ func TestTeamsService_GetTeamByID(t *testing.T) { t.Errorf("Teams.GetTeamByID returned error: %v", err) } - want := &Team{ID: Ptr(int64(1)), Name: Ptr("n"), Description: Ptr("d"), URL: Ptr("u"), Slug: Ptr("s"), Permission: Ptr("p"), LDAPDN: Ptr("cn=n,ou=groups,dc=example,dc=com")} + want := &Team{ID: Ptr(int64(1)), Name: Ptr("n"), Description: Ptr("d"), URL: Ptr("u"), Slug: Ptr("s"), Permission: Ptr("p"), LDAPDN: Ptr("cn=n,ou=groups,dc=example,dc=com"), Type: Ptr("organization")} if !cmp.Equal(team, want) { t.Errorf("Teams.GetTeamByID returned %+v, want %+v", team, want) } @@ -125,7 +125,7 @@ func TestTeamsService_GetTeamBySlug(t *testing.T) { mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`) + fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "type": "organization", "parent":null}`) }) ctx := t.Context() @@ -134,7 +134,7 @@ func TestTeamsService_GetTeamBySlug(t *testing.T) { t.Errorf("Teams.GetTeamBySlug returned error: %v", err) } - want := &Team{ID: Ptr(int64(1)), Name: Ptr("n"), Description: Ptr("d"), URL: Ptr("u"), Slug: Ptr("s"), Permission: Ptr("p"), LDAPDN: Ptr("cn=n,ou=groups,dc=example,dc=com")} + want := &Team{ID: Ptr(int64(1)), Name: Ptr("n"), Description: Ptr("d"), URL: Ptr("u"), Slug: Ptr("s"), Permission: Ptr("p"), LDAPDN: Ptr("cn=n,ou=groups,dc=example,dc=com"), Type: Ptr("organization")} if !cmp.Equal(team, want) { t.Errorf("Teams.GetTeamBySlug returned %+v, want %+v", team, want) } @@ -1650,6 +1650,7 @@ func TestTeams_Marshal(t *testing.T) { ReposCount: Ptr(1), }, LDAPDN: Ptr("l"), + Type: Ptr("t"), } want := `{ @@ -1689,7 +1690,8 @@ func TestTeams_Marshal(t *testing.T) { "members_count": 1, "repos_count": 1 }, - "ldap_dn": "l" + "ldap_dn": "l", + "type": "t" }` testJSONMarshal(t, u, want) From 2fb056649299e20431c73f5127802325aa251440 Mon Sep 17 00:00:00 2001 From: munlicode Date: Sun, 8 Mar 2026 17:51:41 +0500 Subject: [PATCH 2/5] feat: Add support for listing organization fine-grained permissions --- github/github-accessors.go | 16 ++++++++++++ github/github-accessors_test.go | 22 ++++++++++++++++ github/orgs_organization_roles.go | 34 +++++++++++++++++++++++++ github/orgs_organization_roles_test.go | 35 ++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index 70b20e70dc9..a2d82426524 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -17286,6 +17286,22 @@ func (o *OrganizationEvent) GetSender() *User { return o.Sender } +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (o *OrganizationFineGrainedPermission) GetDescription() string { + if o == nil || o.Description == nil { + return "" + } + return *o.Description +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (o *OrganizationFineGrainedPermission) GetName() string { + if o == nil || o.Name == nil { + return "" + } + return *o.Name +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (o *OrganizationInstallations) GetTotalCount() int { if o == nil || o.TotalCount == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index c9441a749c0..65250f7515e 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -22507,6 +22507,28 @@ func TestOrganizationEvent_GetSender(tt *testing.T) { o.GetSender() } +func TestOrganizationFineGrainedPermission_GetDescription(tt *testing.T) { + tt.Parallel() + var zeroValue string + o := &OrganizationFineGrainedPermission{Description: &zeroValue} + o.GetDescription() + o = &OrganizationFineGrainedPermission{} + o.GetDescription() + o = nil + o.GetDescription() +} + +func TestOrganizationFineGrainedPermission_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + o := &OrganizationFineGrainedPermission{Name: &zeroValue} + o.GetName() + o = &OrganizationFineGrainedPermission{} + o.GetName() + o = nil + o.GetName() +} + func TestOrganizationInstallations_GetTotalCount(tt *testing.T) { tt.Parallel() var zeroValue int diff --git a/github/orgs_organization_roles.go b/github/orgs_organization_roles.go index 0954b92d41b..3ba498e9d45 100644 --- a/github/orgs_organization_roles.go +++ b/github/orgs_organization_roles.go @@ -37,6 +37,12 @@ type CreateOrUpdateOrgRoleOptions struct { BaseRole *string `json:"base_role,omitempty"` } +// OrganizationFineGrainedPermission represents a fine-grained permission that protects organization resources. +type OrganizationFineGrainedPermission struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` +} + // ListRoles lists the custom roles available in this organization. // In order to see custom roles in an organization, the authenticated user must be an organization owner. // @@ -293,3 +299,31 @@ func (s *OrganizationsService) ListUsersAssignedToOrgRole(ctx context.Context, o return users, resp, nil } + +// ListFineGrainedPermissions lists the fine-grained permissions that can be used in custom organization roles for an organization. +// +// To use this endpoint, the authenticated user must be one of: +// - An administrator for the organization. +// - A user, or a user on a team, with the fine-grained permissions of `read_organization_custom_org_role` in the organization. +// +// OAuth app tokens and personal access tokens (classic) need the `admin:org` scope to use this endpoint. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/orgs/organization-roles#list-organization-fine-grained-permissions-for-an-organization +// +//meta:operation GET /orgs/{org}/organization-fine-grained-permissions +func (s *OrganizationsService) ListFineGrainedPermissions(ctx context.Context, org string) ([]*OrganizationFineGrainedPermission, *Response, error) { + u := fmt.Sprintf("orgs/%v/organization-fine-grained-permissions", org) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var permissions []*OrganizationFineGrainedPermission + resp, err := s.client.Do(ctx, req, &permissions) + if err != nil { + return nil, resp, err + } + + return permissions, resp, nil +} diff --git a/github/orgs_organization_roles_test.go b/github/orgs_organization_roles_test.go index 1ae9b9ff111..3e845c03571 100644 --- a/github/orgs_organization_roles_test.go +++ b/github/orgs_organization_roles_test.go @@ -495,3 +495,38 @@ func TestOrganizationsService_ListUsersAssignedToOrgRole(t *testing.T) { return resp, err }) } + +func TestOrganizationsService_ListFineGrainedPermissions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/organization-fine-grained-permissions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{"name":"p1", "description":"d1"}]`) + }) + + ctx := t.Context() + permissions, _, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if err != nil { + t.Errorf("Organizations.ListFineGrainedPermissions returned error: %v", err) + } + + want := []*OrganizationFineGrainedPermission{{Name: Ptr("p1"), Description: Ptr("d1")}} + if !cmp.Equal(permissions, want) { + t.Errorf("Organizations.ListFineGrainedPermissions returned %+v, want %+v", permissions, want) + } + + const methodName = "ListFineGrainedPermissions" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Organizations.ListFineGrainedPermissions(ctx, "\no") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From c7a3f38ccabf52f3de98c748a663cb75113108b5 Mon Sep 17 00:00:00 2001 From: munlicode Date: Sun, 8 Mar 2026 17:51:41 +0500 Subject: [PATCH 3/5] feat: Add support for listing organization fine-grained permissions --- github/github-accessors.go | 16 ++++++++++++ github/github-accessors_test.go | 22 ++++++++++++++++ github/orgs_organization_roles.go | 34 +++++++++++++++++++++++++ github/orgs_organization_roles_test.go | 35 ++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index 70b20e70dc9..a2d82426524 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -17286,6 +17286,22 @@ func (o *OrganizationEvent) GetSender() *User { return o.Sender } +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (o *OrganizationFineGrainedPermission) GetDescription() string { + if o == nil || o.Description == nil { + return "" + } + return *o.Description +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (o *OrganizationFineGrainedPermission) GetName() string { + if o == nil || o.Name == nil { + return "" + } + return *o.Name +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (o *OrganizationInstallations) GetTotalCount() int { if o == nil || o.TotalCount == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index c9441a749c0..65250f7515e 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -22507,6 +22507,28 @@ func TestOrganizationEvent_GetSender(tt *testing.T) { o.GetSender() } +func TestOrganizationFineGrainedPermission_GetDescription(tt *testing.T) { + tt.Parallel() + var zeroValue string + o := &OrganizationFineGrainedPermission{Description: &zeroValue} + o.GetDescription() + o = &OrganizationFineGrainedPermission{} + o.GetDescription() + o = nil + o.GetDescription() +} + +func TestOrganizationFineGrainedPermission_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + o := &OrganizationFineGrainedPermission{Name: &zeroValue} + o.GetName() + o = &OrganizationFineGrainedPermission{} + o.GetName() + o = nil + o.GetName() +} + func TestOrganizationInstallations_GetTotalCount(tt *testing.T) { tt.Parallel() var zeroValue int diff --git a/github/orgs_organization_roles.go b/github/orgs_organization_roles.go index 0954b92d41b..3ba498e9d45 100644 --- a/github/orgs_organization_roles.go +++ b/github/orgs_organization_roles.go @@ -37,6 +37,12 @@ type CreateOrUpdateOrgRoleOptions struct { BaseRole *string `json:"base_role,omitempty"` } +// OrganizationFineGrainedPermission represents a fine-grained permission that protects organization resources. +type OrganizationFineGrainedPermission struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` +} + // ListRoles lists the custom roles available in this organization. // In order to see custom roles in an organization, the authenticated user must be an organization owner. // @@ -293,3 +299,31 @@ func (s *OrganizationsService) ListUsersAssignedToOrgRole(ctx context.Context, o return users, resp, nil } + +// ListFineGrainedPermissions lists the fine-grained permissions that can be used in custom organization roles for an organization. +// +// To use this endpoint, the authenticated user must be one of: +// - An administrator for the organization. +// - A user, or a user on a team, with the fine-grained permissions of `read_organization_custom_org_role` in the organization. +// +// OAuth app tokens and personal access tokens (classic) need the `admin:org` scope to use this endpoint. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/orgs/organization-roles#list-organization-fine-grained-permissions-for-an-organization +// +//meta:operation GET /orgs/{org}/organization-fine-grained-permissions +func (s *OrganizationsService) ListFineGrainedPermissions(ctx context.Context, org string) ([]*OrganizationFineGrainedPermission, *Response, error) { + u := fmt.Sprintf("orgs/%v/organization-fine-grained-permissions", org) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var permissions []*OrganizationFineGrainedPermission + resp, err := s.client.Do(ctx, req, &permissions) + if err != nil { + return nil, resp, err + } + + return permissions, resp, nil +} diff --git a/github/orgs_organization_roles_test.go b/github/orgs_organization_roles_test.go index 1ae9b9ff111..3e845c03571 100644 --- a/github/orgs_organization_roles_test.go +++ b/github/orgs_organization_roles_test.go @@ -495,3 +495,38 @@ func TestOrganizationsService_ListUsersAssignedToOrgRole(t *testing.T) { return resp, err }) } + +func TestOrganizationsService_ListFineGrainedPermissions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/organization-fine-grained-permissions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{"name":"p1", "description":"d1"}]`) + }) + + ctx := t.Context() + permissions, _, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if err != nil { + t.Errorf("Organizations.ListFineGrainedPermissions returned error: %v", err) + } + + want := []*OrganizationFineGrainedPermission{{Name: Ptr("p1"), Description: Ptr("d1")}} + if !cmp.Equal(permissions, want) { + t.Errorf("Organizations.ListFineGrainedPermissions returned %+v, want %+v", permissions, want) + } + + const methodName = "ListFineGrainedPermissions" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Organizations.ListFineGrainedPermissions(ctx, "\no") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 8d331a78cda33445cc160ad582346f0163912f0e Mon Sep 17 00:00:00 2001 From: munlicode Date: Sun, 8 Mar 2026 18:09:33 +0500 Subject: [PATCH 4/5] feat: Add support for listing organization fine-grained permissions --- github/github-accessors.go | 16 ++++++++++++ github/github-accessors_test.go | 22 ++++++++++++++++ github/orgs_organization_roles.go | 34 +++++++++++++++++++++++++ github/orgs_organization_roles_test.go | 35 ++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index aa52b9ae260..2b4959d7353 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -17302,6 +17302,22 @@ func (o *OrganizationEvent) GetSender() *User { return o.Sender } +// GetDescription returns the Description field if it's non-nil, zero value otherwise. +func (o *OrganizationFineGrainedPermission) GetDescription() string { + if o == nil || o.Description == nil { + return "" + } + return *o.Description +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (o *OrganizationFineGrainedPermission) GetName() string { + if o == nil || o.Name == nil { + return "" + } + return *o.Name +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (o *OrganizationInstallations) GetTotalCount() int { if o == nil || o.TotalCount == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 037406b83d6..2434752c415 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -22529,6 +22529,28 @@ func TestOrganizationEvent_GetSender(tt *testing.T) { o.GetSender() } +func TestOrganizationFineGrainedPermission_GetDescription(tt *testing.T) { + tt.Parallel() + var zeroValue string + o := &OrganizationFineGrainedPermission{Description: &zeroValue} + o.GetDescription() + o = &OrganizationFineGrainedPermission{} + o.GetDescription() + o = nil + o.GetDescription() +} + +func TestOrganizationFineGrainedPermission_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + o := &OrganizationFineGrainedPermission{Name: &zeroValue} + o.GetName() + o = &OrganizationFineGrainedPermission{} + o.GetName() + o = nil + o.GetName() +} + func TestOrganizationInstallations_GetTotalCount(tt *testing.T) { tt.Parallel() var zeroValue int diff --git a/github/orgs_organization_roles.go b/github/orgs_organization_roles.go index 0954b92d41b..3ba498e9d45 100644 --- a/github/orgs_organization_roles.go +++ b/github/orgs_organization_roles.go @@ -37,6 +37,12 @@ type CreateOrUpdateOrgRoleOptions struct { BaseRole *string `json:"base_role,omitempty"` } +// OrganizationFineGrainedPermission represents a fine-grained permission that protects organization resources. +type OrganizationFineGrainedPermission struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` +} + // ListRoles lists the custom roles available in this organization. // In order to see custom roles in an organization, the authenticated user must be an organization owner. // @@ -293,3 +299,31 @@ func (s *OrganizationsService) ListUsersAssignedToOrgRole(ctx context.Context, o return users, resp, nil } + +// ListFineGrainedPermissions lists the fine-grained permissions that can be used in custom organization roles for an organization. +// +// To use this endpoint, the authenticated user must be one of: +// - An administrator for the organization. +// - A user, or a user on a team, with the fine-grained permissions of `read_organization_custom_org_role` in the organization. +// +// OAuth app tokens and personal access tokens (classic) need the `admin:org` scope to use this endpoint. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/orgs/organization-roles#list-organization-fine-grained-permissions-for-an-organization +// +//meta:operation GET /orgs/{org}/organization-fine-grained-permissions +func (s *OrganizationsService) ListFineGrainedPermissions(ctx context.Context, org string) ([]*OrganizationFineGrainedPermission, *Response, error) { + u := fmt.Sprintf("orgs/%v/organization-fine-grained-permissions", org) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var permissions []*OrganizationFineGrainedPermission + resp, err := s.client.Do(ctx, req, &permissions) + if err != nil { + return nil, resp, err + } + + return permissions, resp, nil +} diff --git a/github/orgs_organization_roles_test.go b/github/orgs_organization_roles_test.go index 1ae9b9ff111..3e845c03571 100644 --- a/github/orgs_organization_roles_test.go +++ b/github/orgs_organization_roles_test.go @@ -495,3 +495,38 @@ func TestOrganizationsService_ListUsersAssignedToOrgRole(t *testing.T) { return resp, err }) } + +func TestOrganizationsService_ListFineGrainedPermissions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/organization-fine-grained-permissions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{"name":"p1", "description":"d1"}]`) + }) + + ctx := t.Context() + permissions, _, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if err != nil { + t.Errorf("Organizations.ListFineGrainedPermissions returned error: %v", err) + } + + want := []*OrganizationFineGrainedPermission{{Name: Ptr("p1"), Description: Ptr("d1")}} + if !cmp.Equal(permissions, want) { + t.Errorf("Organizations.ListFineGrainedPermissions returned %+v, want %+v", permissions, want) + } + + const methodName = "ListFineGrainedPermissions" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Organizations.ListFineGrainedPermissions(ctx, "\no") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.ListFineGrainedPermissions(ctx, "o") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 18684fce4510dcaadf27cd007d9747df199e27f4 Mon Sep 17 00:00:00 2001 From: munlicode Date: Mon, 9 Mar 2026 16:07:29 +0500 Subject: [PATCH 5/5] fix: Set `name` and `description` strings required to follow documentation --- github/github-accessors.go | 16 ---------------- github/github-accessors_test.go | 22 ---------------------- github/orgs_organization_roles.go | 4 ++-- github/orgs_organization_roles_test.go | 2 +- 4 files changed, 3 insertions(+), 41 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 2b4959d7353..aa52b9ae260 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -17302,22 +17302,6 @@ func (o *OrganizationEvent) GetSender() *User { return o.Sender } -// GetDescription returns the Description field if it's non-nil, zero value otherwise. -func (o *OrganizationFineGrainedPermission) GetDescription() string { - if o == nil || o.Description == nil { - return "" - } - return *o.Description -} - -// GetName returns the Name field if it's non-nil, zero value otherwise. -func (o *OrganizationFineGrainedPermission) GetName() string { - if o == nil || o.Name == nil { - return "" - } - return *o.Name -} - // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (o *OrganizationInstallations) GetTotalCount() int { if o == nil || o.TotalCount == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 2434752c415..037406b83d6 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -22529,28 +22529,6 @@ func TestOrganizationEvent_GetSender(tt *testing.T) { o.GetSender() } -func TestOrganizationFineGrainedPermission_GetDescription(tt *testing.T) { - tt.Parallel() - var zeroValue string - o := &OrganizationFineGrainedPermission{Description: &zeroValue} - o.GetDescription() - o = &OrganizationFineGrainedPermission{} - o.GetDescription() - o = nil - o.GetDescription() -} - -func TestOrganizationFineGrainedPermission_GetName(tt *testing.T) { - tt.Parallel() - var zeroValue string - o := &OrganizationFineGrainedPermission{Name: &zeroValue} - o.GetName() - o = &OrganizationFineGrainedPermission{} - o.GetName() - o = nil - o.GetName() -} - func TestOrganizationInstallations_GetTotalCount(tt *testing.T) { tt.Parallel() var zeroValue int diff --git a/github/orgs_organization_roles.go b/github/orgs_organization_roles.go index 3ba498e9d45..a957c0e88cc 100644 --- a/github/orgs_organization_roles.go +++ b/github/orgs_organization_roles.go @@ -39,8 +39,8 @@ type CreateOrUpdateOrgRoleOptions struct { // OrganizationFineGrainedPermission represents a fine-grained permission that protects organization resources. type OrganizationFineGrainedPermission struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` + Name string `json:"name"` + Description string `json:"description"` } // ListRoles lists the custom roles available in this organization. diff --git a/github/orgs_organization_roles_test.go b/github/orgs_organization_roles_test.go index 3e845c03571..cedde893827 100644 --- a/github/orgs_organization_roles_test.go +++ b/github/orgs_organization_roles_test.go @@ -511,7 +511,7 @@ func TestOrganizationsService_ListFineGrainedPermissions(t *testing.T) { t.Errorf("Organizations.ListFineGrainedPermissions returned error: %v", err) } - want := []*OrganizationFineGrainedPermission{{Name: Ptr("p1"), Description: Ptr("d1")}} + want := []*OrganizationFineGrainedPermission{{Name: "p1", Description: "d1"}} if !cmp.Equal(permissions, want) { t.Errorf("Organizations.ListFineGrainedPermissions returned %+v, want %+v", permissions, want) }