From 4dec331e4bfdb73aa2bd79495bc6efc295fe473b Mon Sep 17 00:00:00 2001 From: subencheng Date: Thu, 28 May 2026 12:41:10 -0700 Subject: [PATCH 1/5] make public builder --- pkg/connector/api_token.go | 2 +- pkg/connector/connector.go | 18 +++++++++--------- pkg/connector/enterprise_role.go | 2 +- pkg/connector/invitation.go | 4 ++-- pkg/connector/invitation_test.go | 2 +- pkg/connector/license.go | 2 +- pkg/connector/org.go | 2 +- pkg/connector/org_role.go | 2 +- pkg/connector/org_role_test.go | 4 ++-- pkg/connector/org_test.go | 2 +- pkg/connector/repository.go | 2 +- pkg/connector/repository_test.go | 2 +- pkg/connector/team.go | 2 +- pkg/connector/team_test.go | 2 +- pkg/connector/user.go | 2 +- pkg/connector/user_test.go | 2 +- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/pkg/connector/api_token.go b/pkg/connector/api_token.go index 6b3d0319..a1e5b46a 100644 --- a/pkg/connector/api_token.go +++ b/pkg/connector/api_token.go @@ -128,7 +128,7 @@ func (o *apiTokenResourceType) List( }, nil } -func apiTokenBuilder(client *github.Client, orgCache *orgNameCache) *apiTokenResourceType { +func APITokenBuilder(client *github.Client, orgCache *orgNameCache) *apiTokenResourceType { return &apiTokenResourceType{ resourceType: resourceTypeApiToken, client: client, diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 941c4989..7705b46c 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -117,12 +117,12 @@ type GitHub struct { func (gh *GitHub) ResourceSyncers(ctx context.Context) []connectorbuilder.ResourceSyncerV2 { resourceSyncers := []connectorbuilder.ResourceSyncerV2{ - orgBuilder(gh.client, gh.appClient, gh.orgCache, gh.orgs, gh.syncSecrets), - teamBuilder(gh.client, gh.orgCache, gh.directCollaboratorsOnly), - userBuilder(gh.client, gh.graphqlClient, gh.orgCache, gh.orgs, gh.customClient, gh.enterprises), - repositoryBuilder(gh.client, gh.orgCache, gh.omitArchivedRepositories, gh.directCollaboratorsOnly), - orgRoleBuilder(gh.client, gh.orgCache), - invitationBuilder(invitationBuilderParams{ + OrgBuilder(gh.client, gh.appClient, gh.orgCache, gh.orgs, gh.syncSecrets), + TeamBuilder(gh.client, gh.orgCache, gh.directCollaboratorsOnly), + UserBuilder(gh.client, gh.graphqlClient, gh.orgCache, gh.orgs, gh.customClient, gh.enterprises), + RepositoryBuilder(gh.client, gh.orgCache, gh.omitArchivedRepositories, gh.directCollaboratorsOnly), + OrgRoleBuilder(gh.client, gh.orgCache), + InvitationBuilder(InvitationBuilderParams{ client: gh.client, orgCache: gh.orgCache, orgs: gh.orgs, @@ -130,13 +130,13 @@ func (gh *GitHub) ResourceSyncers(ctx context.Context) []connectorbuilder.Resour } if gh.syncSecrets { - resourceSyncers = append(resourceSyncers, apiTokenBuilder(gh.client, gh.orgCache)) + resourceSyncers = append(resourceSyncers, APITokenBuilder(gh.client, gh.orgCache)) } if len(gh.enterprises) > 0 { resourceSyncers = append(resourceSyncers, - enterpriseRoleBuilder(gh.client, gh.appClient, gh.customClient, gh.enterprises), - licenseBuilder(gh.customClient, gh.enterprises), + EnterpriseRoleBuilder(gh.client, gh.appClient, gh.customClient, gh.enterprises), + LicenseBuilder(gh.customClient, gh.enterprises), ) } return resourceSyncers diff --git a/pkg/connector/enterprise_role.go b/pkg/connector/enterprise_role.go index b8474c22..a6e79aab 100644 --- a/pkg/connector/enterprise_role.go +++ b/pkg/connector/enterprise_role.go @@ -176,7 +176,7 @@ func (o *enterpriseRoleResourceType) Grants( return ret, &resourceSdk.SyncOpResults{}, nil } -func enterpriseRoleBuilder(client *github.Client, appClient *github.Client, customClient *customclient.Client, enterprises []string) *enterpriseRoleResourceType { +func EnterpriseRoleBuilder(client *github.Client, appClient *github.Client, customClient *customclient.Client, enterprises []string) *enterpriseRoleResourceType { return &enterpriseRoleResourceType{ resourceType: resourceTypeEnterpriseRole, client: client, diff --git a/pkg/connector/invitation.go b/pkg/connector/invitation.go index 95212ad8..52df44a2 100644 --- a/pkg/connector/invitation.go +++ b/pkg/connector/invitation.go @@ -520,13 +520,13 @@ func containsLower(s, substr string) bool { return strings.Contains(strings.ToLower(s), substr) } -type invitationBuilderParams struct { +type InvitationBuilderParams struct { client *github.Client orgCache *orgNameCache orgs []string } -func invitationBuilder(p invitationBuilderParams) *invitationResourceType { +func InvitationBuilder(p InvitationBuilderParams) *invitationResourceType { return &invitationResourceType{ client: p.client, orgCache: p.orgCache, diff --git a/pkg/connector/invitation_test.go b/pkg/connector/invitation_test.go index ec3af16f..e466366e 100644 --- a/pkg/connector/invitation_test.go +++ b/pkg/connector/invitation_test.go @@ -154,7 +154,7 @@ func TestInvitationListPagination(t *testing.T) { newBuilder := func(httpClient *http.Client) *invitationResourceType { gh := github.NewClient(httpClient) - return invitationBuilder(invitationBuilderParams{ + return InvitationBuilder(InvitationBuilderParams{ client: gh, orgCache: newOrgNameCache(gh), orgs: []string{invitationTestOrgLogin}, diff --git a/pkg/connector/license.go b/pkg/connector/license.go index f152e691..f3c86799 100644 --- a/pkg/connector/license.go +++ b/pkg/connector/license.go @@ -162,7 +162,7 @@ func licenseResource(enterprise string, purchasedSeats, consumedSeats int64, ent ) } -func licenseBuilder( +func LicenseBuilder( customClient *customclient.Client, enterprises []string, ) *licenseResourceType { diff --git a/pkg/connector/org.go b/pkg/connector/org.go index 96739f77..5bf3bc43 100644 --- a/pkg/connector/org.go +++ b/pkg/connector/org.go @@ -418,7 +418,7 @@ func (o *orgResourceType) Revoke(ctx context.Context, grant *v2.Grant) (annotati return nil, nil } -func orgBuilder(client, appClient *github.Client, orgCache *orgNameCache, orgs []string, syncSecrets bool) *orgResourceType { +func OrgBuilder(client, appClient *github.Client, orgCache *orgNameCache, orgs []string, syncSecrets bool) *orgResourceType { orgMap := make(map[string]struct{}) for _, o := range orgs { diff --git a/pkg/connector/org_role.go b/pkg/connector/org_role.go index efc21138..e78c30a0 100644 --- a/pkg/connector/org_role.go +++ b/pkg/connector/org_role.go @@ -445,7 +445,7 @@ func (o *orgRoleResourceType) Revoke(ctx context.Context, grant *v2.Grant) (anno return nil, nil } -func orgRoleBuilder(client *github.Client, orgCache *orgNameCache) *orgRoleResourceType { +func OrgRoleBuilder(client *github.Client, orgCache *orgNameCache) *orgRoleResourceType { return &orgRoleResourceType{ resourceType: resourceTypeOrgRole, client: client, diff --git a/pkg/connector/org_role_test.go b/pkg/connector/org_role_test.go index e5fe6fb9..5d867d8e 100644 --- a/pkg/connector/org_role_test.go +++ b/pkg/connector/org_role_test.go @@ -25,7 +25,7 @@ func TestOrgRole(t *testing.T) { githubClient := github.NewClient(mgh.Server()) cache := newOrgNameCache(githubClient) - client := orgRoleBuilder(githubClient, cache) + client := OrgRoleBuilder(githubClient, cache) organization, _ := organizationResource(ctx, githubOrganization, nil, true) roleResource, _ := orgRoleResource(ctx, &OrganizationRole{ @@ -93,7 +93,7 @@ func TestOrgRole(t *testing.T) { githubClient := github.NewClient(mockGithub.Server()) cache := newOrgNameCache(githubClient) - client := orgRoleBuilder(githubClient, cache) + client := OrgRoleBuilder(githubClient, cache) organization, _ := organizationResource(ctx, githubOrganization, nil, true) diff --git a/pkg/connector/org_test.go b/pkg/connector/org_test.go index 590f13a0..de32fe23 100644 --- a/pkg/connector/org_test.go +++ b/pkg/connector/org_test.go @@ -24,7 +24,7 @@ func TestOrganization(t *testing.T) { githubClient := github.NewClient(mgh.Server()) cache := newOrgNameCache(githubClient) - client := orgBuilder(githubClient, nil, cache, nil, false) + client := OrgBuilder(githubClient, nil, cache, nil, false) organization, _ := organizationResource(ctx, githubOrganization, nil, false) user, _ := userResource(ctx, githubUser, *githubUser.Email, nil) diff --git a/pkg/connector/repository.go b/pkg/connector/repository.go index 0a712416..f9eb3b10 100644 --- a/pkg/connector/repository.go +++ b/pkg/connector/repository.go @@ -525,7 +525,7 @@ func orgBasePermissionToRepoPermissions(basePerm string) []string { } } -func repositoryBuilder(client *github.Client, orgCache *orgNameCache, omitArchivedRepositories bool, directCollaboratorsOnly bool) *repositoryResourceType { +func RepositoryBuilder(client *github.Client, orgCache *orgNameCache, omitArchivedRepositories bool, directCollaboratorsOnly bool) *repositoryResourceType { return &repositoryResourceType{ resourceType: resourceTypeRepository, client: client, diff --git a/pkg/connector/repository_test.go b/pkg/connector/repository_test.go index 03640c26..61009d0c 100644 --- a/pkg/connector/repository_test.go +++ b/pkg/connector/repository_test.go @@ -25,7 +25,7 @@ func TestRepository(t *testing.T) { githubClient := github.NewClient(mgh.Server()) cache := newOrgNameCache(githubClient) - client := repositoryBuilder(githubClient, cache, false, false) + client := RepositoryBuilder(githubClient, cache, false, false) organization, _ := organizationResource(ctx, githubOrganization, nil, false) repository, _ := repositoryResource(ctx, githubRepository, organization.Id) diff --git a/pkg/connector/team.go b/pkg/connector/team.go index d4399f95..6cd75739 100644 --- a/pkg/connector/team.go +++ b/pkg/connector/team.go @@ -375,7 +375,7 @@ func (o *teamResourceType) Revoke(ctx context.Context, grant *v2.Grant) (annotat return nil, nil } -func teamBuilder(client *github.Client, orgCache *orgNameCache, directCollaboratorsOnly bool) *teamResourceType { +func TeamBuilder(client *github.Client, orgCache *orgNameCache, directCollaboratorsOnly bool) *teamResourceType { return &teamResourceType{ resourceType: resourceTypeTeam, client: client, diff --git a/pkg/connector/team_test.go b/pkg/connector/team_test.go index cc81caf0..5856f421 100644 --- a/pkg/connector/team_test.go +++ b/pkg/connector/team_test.go @@ -25,7 +25,7 @@ func TestTeam(t *testing.T) { githubClient := github.NewClient(mgh.Server()) cache := newOrgNameCache(githubClient) - client := teamBuilder(githubClient, cache, false) + client := TeamBuilder(githubClient, cache, false) organization, _ := organizationResource(ctx, githubOrganization, nil, false) team, _ := teamResource(githubTeam, githubOrganization.GetID(), organization.Id) diff --git a/pkg/connector/user.go b/pkg/connector/user.go index a67df7ba..d5c6568f 100644 --- a/pkg/connector/user.go +++ b/pkg/connector/user.go @@ -358,7 +358,7 @@ func (u *userResourceType) Delete(ctx context.Context, resourceId *v2.ResourceId return annotations, nil } -func userBuilder(client *github.Client, graphqlClient *githubv4.Client, orgCache *orgNameCache, orgs []string, customClient *customclient.Client, enterprises []string) *userResourceType { +func UserBuilder(client *github.Client, graphqlClient *githubv4.Client, orgCache *orgNameCache, orgs []string, customClient *customclient.Client, enterprises []string) *userResourceType { return &userResourceType{ resourceType: resourceTypeUser, client: client, diff --git a/pkg/connector/user_test.go b/pkg/connector/user_test.go index 6b21d2f3..e2e4d0e5 100644 --- a/pkg/connector/user_test.go +++ b/pkg/connector/user_test.go @@ -33,7 +33,7 @@ func TestUsersList(t *testing.T) { githubClient := github.NewClient(mgh.Server()) graphQLClient := mocks.MockGraphQL() cache := newOrgNameCache(githubClient) - client := userBuilder( + client := UserBuilder( githubClient, graphQLClient, cache, From ea915b14f47028d522ae94013841ae0c95769a72 Mon Sep 17 00:00:00 2001 From: subencheng Date: Thu, 28 May 2026 12:44:56 -0700 Subject: [PATCH 2/5] remove code --- pkg/connector/license.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pkg/connector/license.go b/pkg/connector/license.go index f3c86799..5e99eca2 100644 --- a/pkg/connector/license.go +++ b/pkg/connector/license.go @@ -9,8 +9,6 @@ import ( "github.com/conductorone/baton-sdk/pkg/types/entitlement" "github.com/conductorone/baton-sdk/pkg/types/grant" resourceSdk "github.com/conductorone/baton-sdk/pkg/types/resource" - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - "go.uber.org/zap" ) const ( @@ -37,8 +35,6 @@ func (l *licenseResourceType) List( parentID *v2.ResourceId, opts resourceSdk.SyncOpAttrs, ) ([]*v2.Resource, *resourceSdk.SyncOpResults, error) { - logger := ctxzap.Extract(ctx) - var ret []*v2.Resource for _, enterprise := range l.enterprises { // total_seats_purchased and total_seats_consumed are enterprise-wide @@ -46,14 +42,6 @@ func (l *licenseResourceType) List( // first page is enough. consumedLicenses, _, err := l.customClient.ListEnterpriseConsumedLicenses(ctx, enterprise, 1) if err != nil { - if isPermissionDenied(err) { - logger.Debug("baton-github: enterprise features (--enterprises) require a Personal Access Token. "+ - "GitHub App authentication cannot access the consumed-licenses API. "+ - "Either switch to PAT auth or remove the --enterprises flag.", - zap.String("enterprise", enterprise), - zap.Error(err)) - continue - } return nil, nil, fmt.Errorf("baton-github: error listing enterprise consumed licenses for %s: %w", enterprise, err) } From 8236eb3a2396210dff3ddd8100b71575b0f521b7 Mon Sep 17 00:00:00 2001 From: subencheng Date: Thu, 28 May 2026 14:11:59 -0700 Subject: [PATCH 3/5] connector opt in --- pkg/connector/enterprise_role.go | 13 ++++++++++++- pkg/connector/license.go | 14 +++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pkg/connector/enterprise_role.go b/pkg/connector/enterprise_role.go index a6e79aab..b1830c62 100644 --- a/pkg/connector/enterprise_role.go +++ b/pkg/connector/enterprise_role.go @@ -9,6 +9,7 @@ import ( "github.com/conductorone/baton-github/pkg/customclient" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" + "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/types/entitlement" "github.com/conductorone/baton-sdk/pkg/types/grant" resourceSdk "github.com/conductorone/baton-sdk/pkg/types/resource" @@ -177,8 +178,18 @@ func (o *enterpriseRoleResourceType) Grants( } func EnterpriseRoleBuilder(client *github.Client, appClient *github.Client, customClient *customclient.Client, enterprises []string) *enterpriseRoleResourceType { + annos := annotations.Annotations(resourceTypeLicense.GetAnnotations()) + if len(enterprises) == 0 { + annos.Append(&v2.SkipEntitlementsAndGrants{}) + } + rt := &v2.ResourceType{ + Id: resourceTypeEnterpriseRole.Id, + DisplayName: resourceTypeEnterpriseRole.DisplayName, + Traits: resourceTypeEnterpriseRole.Traits, + Annotations: annos, + } return &enterpriseRoleResourceType{ - resourceType: resourceTypeEnterpriseRole, + resourceType: rt, client: client, appClient: appClient, customClient: customClient, diff --git a/pkg/connector/license.go b/pkg/connector/license.go index 5e99eca2..3b52b98e 100644 --- a/pkg/connector/license.go +++ b/pkg/connector/license.go @@ -6,6 +6,7 @@ import ( "github.com/conductorone/baton-github/pkg/customclient" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" + "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/types/entitlement" "github.com/conductorone/baton-sdk/pkg/types/grant" resourceSdk "github.com/conductorone/baton-sdk/pkg/types/resource" @@ -154,8 +155,19 @@ func LicenseBuilder( customClient *customclient.Client, enterprises []string, ) *licenseResourceType { + annos := annotations.Annotations(resourceTypeLicense.GetAnnotations()) + if len(enterprises) == 0 { + annos.Append(&v2.SkipEntitlementsAndGrants{}) + } + + rt := &v2.ResourceType{ + Id: resourceTypeLicense.Id, + DisplayName: resourceTypeLicense.DisplayName, + Traits: resourceTypeLicense.Traits, + Annotations: annos, + } return &licenseResourceType{ - resourceType: resourceTypeLicense, + resourceType: rt, customClient: customClient, enterprises: enterprises, } From 1f85c5328fd72c65e54b7fab3560c472a86a22f2 Mon Sep 17 00:00:00 2001 From: subencheng Date: Thu, 28 May 2026 15:07:00 -0700 Subject: [PATCH 4/5] now --- pkg/connector/enterprise_role.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/enterprise_role.go b/pkg/connector/enterprise_role.go index b1830c62..0d0b4dad 100644 --- a/pkg/connector/enterprise_role.go +++ b/pkg/connector/enterprise_role.go @@ -178,7 +178,7 @@ func (o *enterpriseRoleResourceType) Grants( } func EnterpriseRoleBuilder(client *github.Client, appClient *github.Client, customClient *customclient.Client, enterprises []string) *enterpriseRoleResourceType { - annos := annotations.Annotations(resourceTypeLicense.GetAnnotations()) + annos := annotations.Annotations(resourceTypeEnterpriseRole.GetAnnotations()) if len(enterprises) == 0 { annos.Append(&v2.SkipEntitlementsAndGrants{}) } From 2fc096ff60017d5ccc4ef55feb687c7fe7bc68a2 Mon Sep 17 00:00:00 2001 From: subencheng Date: Thu, 28 May 2026 15:45:39 -0700 Subject: [PATCH 5/5] now --- pkg/connector/enterprise_role.go | 13 +------------ pkg/connector/license.go | 14 +------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/pkg/connector/enterprise_role.go b/pkg/connector/enterprise_role.go index 0d0b4dad..a6e79aab 100644 --- a/pkg/connector/enterprise_role.go +++ b/pkg/connector/enterprise_role.go @@ -9,7 +9,6 @@ import ( "github.com/conductorone/baton-github/pkg/customclient" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" - "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/types/entitlement" "github.com/conductorone/baton-sdk/pkg/types/grant" resourceSdk "github.com/conductorone/baton-sdk/pkg/types/resource" @@ -178,18 +177,8 @@ func (o *enterpriseRoleResourceType) Grants( } func EnterpriseRoleBuilder(client *github.Client, appClient *github.Client, customClient *customclient.Client, enterprises []string) *enterpriseRoleResourceType { - annos := annotations.Annotations(resourceTypeEnterpriseRole.GetAnnotations()) - if len(enterprises) == 0 { - annos.Append(&v2.SkipEntitlementsAndGrants{}) - } - rt := &v2.ResourceType{ - Id: resourceTypeEnterpriseRole.Id, - DisplayName: resourceTypeEnterpriseRole.DisplayName, - Traits: resourceTypeEnterpriseRole.Traits, - Annotations: annos, - } return &enterpriseRoleResourceType{ - resourceType: rt, + resourceType: resourceTypeEnterpriseRole, client: client, appClient: appClient, customClient: customClient, diff --git a/pkg/connector/license.go b/pkg/connector/license.go index 3b52b98e..5e99eca2 100644 --- a/pkg/connector/license.go +++ b/pkg/connector/license.go @@ -6,7 +6,6 @@ import ( "github.com/conductorone/baton-github/pkg/customclient" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" - "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/types/entitlement" "github.com/conductorone/baton-sdk/pkg/types/grant" resourceSdk "github.com/conductorone/baton-sdk/pkg/types/resource" @@ -155,19 +154,8 @@ func LicenseBuilder( customClient *customclient.Client, enterprises []string, ) *licenseResourceType { - annos := annotations.Annotations(resourceTypeLicense.GetAnnotations()) - if len(enterprises) == 0 { - annos.Append(&v2.SkipEntitlementsAndGrants{}) - } - - rt := &v2.ResourceType{ - Id: resourceTypeLicense.Id, - DisplayName: resourceTypeLicense.DisplayName, - Traits: resourceTypeLicense.Traits, - Annotations: annos, - } return &licenseResourceType{ - resourceType: rt, + resourceType: resourceTypeLicense, customClient: customClient, enterprises: enterprises, }