Skip to content

Conversation

@ggreer
Copy link
Contributor

@ggreer ggreer commented Sep 23, 2025

Summary by CodeRabbit

  • New Features
    • No user-facing features added.
  • Refactor
    • Streamlined entitlement identifier handling to remove unnecessary formatting.
    • Aligned account creation to use local credential options; behavior unchanged.
    • Added safeguards to ensure implementation consistency.
  • Chores
    • Upgraded Go toolchain to 1.25.
    • Updated core SDK and compression dependencies to latest versions for improved compatibility and security.

@ggreer ggreer force-pushed the ggreer/upgrade-baton-sdk branch 4 times, most recently from 1b87fc0 to 36da96c Compare September 23, 2025 00:44
@coderabbitai
Copy link

coderabbitai bot commented Sep 23, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • .github/workflows/ci.yaml is excluded by none and included by none

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Updates Go toolchain and dependencies in go.mod. Adjusts an annotation value retrieval in enterprise_role entitlement generation. Changes CreateAccount parameter type to LocalCredentialOptions and adds a compile-time interface conformance assertion for invitation resource type.

Changes

Cohort / File(s) Summary
Toolchain and Dependencies
go.mod
Bump Go toolchain to 1.25; upgrade github.com/conductorone/baton-sdk to v0.4.2; upgrade indirect github.com/klauspost/compress to v1.18.0; other requirements unchanged.
Enterprise Role Annotation
pkg/connector/enterprise_role.go
In Entitlements, set V1Identifier.Id using resource.Id.Resource directly instead of fmt.Sprintf(...).
Account Creation API Update
pkg/connector/invitation.go
Change CreateAccount signature to use *v2.LocalCredentialOptions (from *v2.CredentialOptions); add compile-time assertion var _ connectorbuilder.AccountManager = &invitationResourceType{}.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant InvitationResourceType as invitationResourceType
  participant ConnectorBuilder as connectorbuilder.AccountManager
  participant AccountStore as Account Storage

  Note over Client,InvitationResourceType: Account creation with LocalCredentialOptions
  Client->>InvitationResourceType: CreateAccount(ctx, accountInfo, localCredOpts)
  InvitationResourceType->>ConnectorBuilder: Validate/Use LocalCredentialOptions
  alt valid options
    InvitationResourceType->>AccountStore: Create account with credentials
    AccountStore-->>InvitationResourceType: Account created
    InvitationResourceType-->>Client: Result (success)
  else invalid options/error
    InvitationResourceType-->>Client: Error
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I nibbled through modules, hop by hop,
Toolchain taller, deps that pop.
An invite whispers, “Local creds, please,”
I twitch my nose and change with ease.
IDs unwrapped, clean and bright—
Thump-thump! The build takes flight. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly states the primary change—upgrading baton-sdk to v0.4.2—and notes lint fixes; the raw summary shows a go.mod dependency bump to v0.4.2 and related code edits (signature change, compile-time assertion, minor formatting) that align with lint or compatibility corrections. Therefore the title accurately reflects the main intent of the changeset. It is concise and specific enough for a reviewer scanning PR history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
pkg/connector/enterprise_role.go (1)

44-54: Data race + leaking internal map from cache

  • len(o.roleUsersCache) checked without lock; concurrent writes can panic.
  • Returning the internal map exposes it to unsynchronized reads while writers hold the lock.

Fix by gating fill with a separate mutex and returning a copy.

 type enterpriseRoleResourceType struct {
   resourceType   *v2.ResourceType
   client         *github.Client
   customClient   *customclient.Client
   enterprises    []string
   roleUsersCache map[string][]string
-  mu             *sync.Mutex
+  mu             *sync.Mutex        // protects roleUsersCache
+  loadMu         *sync.Mutex        // gates initial fill
 }
@@
 func (o *enterpriseRoleResourceType) getRoleUsersCache(ctx context.Context) (map[string][]string, error) {
-  if len(o.roleUsersCache) == 0 {
-    if err := o.fillCache(ctx); err != nil {
-      return nil, fmt.Errorf("baton-github: error caching user roles: %w", err)
-    }
-  }
-
-  o.mu.Lock()
-  defer o.mu.Unlock()
-  return o.roleUsersCache, nil
+  // Ensure single fill without holding o.mu (fillCache locks via cacheRole)
+  o.mu.Lock()
+  empty := len(o.roleUsersCache) == 0
+  o.mu.Unlock()
+  if empty {
+    o.loadMu.Lock()
+    // Double-check after acquiring loadMu
+    o.mu.Lock()
+    empty = len(o.roleUsersCache) == 0
+    o.mu.Unlock()
+    if empty {
+      if err := o.fillCache(ctx); err != nil {
+        o.loadMu.Unlock()
+        return nil, fmt.Errorf("baton-github: error caching user roles: %w", err)
+      }
+    }
+    o.loadMu.Unlock()
+  }
+  // Return a copy to avoid exposing internal map
+  o.mu.Lock()
+  out := make(map[string][]string, len(o.roleUsersCache))
+  for k, v := range o.roleUsersCache {
+    out[k] = append([]string(nil), v...)
+  }
+  o.mu.Unlock()
+  return out, nil
 }
@@
 func enterpriseRoleBuilder(client *github.Client, customClient *customclient.Client, enterprises []string) *enterpriseRoleResourceType {
   return &enterpriseRoleResourceType{
     resourceType:   resourceTypeEnterpriseRole,
     client:         client,
     customClient:   customClient,
     enterprises:    enterprises,
     roleUsersCache: make(map[string][]string),
-    mu:             &sync.Mutex{},
+    mu:             &sync.Mutex{},
+    loadMu:         &sync.Mutex{},
   }
 }
pkg/connector/invitation.go (3)

55-56: Shadowing package name ‘annotations’ causes compile error

Local var named annotations shadows the imported package, so annotations.WithRateLimiting(...) won’t compile.

- var annotations annotations.Annotations
+ var ann annotations.Annotations
@@
- annotations.WithRateLimiting(restApiRateLimit)
- return invitationResources, pageToken, annotations, nil
+ ann.WithRateLimiting(restApiRateLimit)
+ return invitationResources, pageToken, ann, nil

Also applies to: 103-105


151-153: Same shadowing bug in CreateAccount

Rename the var.

- var annotations annotations.Annotations
- annotations.WithRateLimiting(restApiRateLimit)
- return &v2.CreateAccountResponse_SuccessResult{
+ var ann annotations.Annotations
+ ann.WithRateLimiting(restApiRateLimit)
+ return &v2.CreateAccountResponse_SuccessResult{
   Resource: r,
- }, nil, annotations, nil
+ }, nil, ann, nil

199-201: Same shadowing bug in Delete

Rename the var.

- var annotations annotations.Annotations
- annotations.WithRateLimiting(restApiRateLimit)
- return annotations, nil
+ var ann annotations.Annotations
+ ann.WithRateLimiting(restApiRateLimit)
+ return ann, nil
🧹 Nitpick comments (4)
pkg/connector/enterprise_role.go (1)

93-99: Avoid double Split; use Cut/SplitN once

Minor tidy-up.

- for roleId := range cache {
-   roleName := strings.Split(roleId, ":")[1]
-   enterprise := strings.Split(roleId, ":")[0]
+ for roleId := range cache {
+   enterprise, roleName, _ := strings.Cut(roleId, ":")
pkg/connector/invitation.go (3)

77-77: Typo in error message

Invitatioins → Invitations.

- return nil, "", nil, fmt.Errorf("github-connector: ListPendingOrgInvitatioins failed: %w", err)
+ return nil, "", nil, fmt.Errorf("github-connector: ListPendingOrgInvitations failed: %w", err)

69-73: Pagination params: handle nil pt defensively

If pt is nil, pt.Size may panic. If upstream guarantees non-nil, ignore. Otherwise, guard or default PerPage.

- invitations, resp, err := i.client.Organizations.ListPendingOrgInvitations(ctx, orgName, &github.ListOptions{
-   Page:    page,
-   PerPage: pt.Size,
- })
+ perPage := 0
+ if pt != nil {
+   perPage = pt.Size
+ }
+ invitations, resp, err := i.client.Organizations.ListPendingOrgInvitations(ctx, orgName, &github.ListOptions{
+   Page:    page,
+   PerPage: perPage,
+ })

16-40: Nil-safe inviter access (optional)

Current go-github getters are nil-safe, but a defensive map write avoids empty "inviter": "" entries if undesired.

- resource.WithUserProfile(map[string]interface{}{
-   "login":   login,
-   "inviter": invitation.GetInviter().GetLogin(),
- }),
+ func() resource.UserTraitOption {
+   prof := map[string]interface{}{"login": login}
+   if inv := invitation.GetInviter(); inv != nil && inv.GetLogin() != "" {
+     prof["inviter"] = inv.GetLogin()
+   }
+   return resource.WithUserProfile(prof)
+ }(),
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0bb8268 and 36da96c.

⛔ Files ignored due to path filters (98)
  • .github/workflows/ci.yaml is excluded by none and included by none
  • .github/workflows/main.yaml is excluded by none and included by none
  • go.sum is excluded by !**/*.sum and included by none
  • vendor/github.com/conductorone/baton-sdk/internal/connector/connector.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_resource_tree.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_resource_tree.pb.validate.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_sync_id.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_sync_id.pb.validate.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/connector.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/event_feed.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/event_feed.pb.validate.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/resource.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/resource.pb.validate.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connectorapi/baton/v1/baton.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connectorapi/baton/v1/baton.pb.validate.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connectorapi/baton/v1/session.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connectorapi/baton/v1/session.pb.validate.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pb/c1/connectorapi/baton/v1/session_grpc.pb.go is excluded by !**/*.pb.go, !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/annotations/annotations.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/bid/bid.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/cli/cli.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/cli/commands.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/cli/lambda_server__added.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/config/config.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/connectorbuilder/connectorbuilder.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/connectorrunner/runner.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/connectorstore/connectorstore.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/crypto/client_secret.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/crypto/crypto.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/crypto/password.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/crypto/providers/jwk/jwk.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/crypto/providers/registry.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/c1file.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/c1file_attached.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/clone_sync.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/decoder.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/diff.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/dotc1z.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/file.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/manager/local/local.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/manager/manager.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/manager/s3/s3.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/sql_helpers.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/sync_runs.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/field/defaults.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/field/validation.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/lambda/grpc/config/config.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/lambda/grpc/transport.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/provisioner/provisioner.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/ratelimit/mem_ratelimiter.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sdk/version.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/session/README.md is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/session/grpc_session.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/session/json.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/session/memory.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/session/session.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/client_wrapper.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/expand/cycle.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/expand/graph.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/expand/scc/bitset.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/expand/scc/scc.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/expand/scc/test_source.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/state.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/sync/syncer.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/synccompactor/attached/attached.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/synccompactor/compactor.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/tasks/c1api/delete_resource.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/tasks/c1api/full_sync.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/tasks/c1api/manager.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/tasks/c1api/service_client.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/tasks/local/syncer.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/types/session_cache.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/types/types.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/ugrpc/c1_credential_provider.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/ugrpc/interceptors.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/uhttp/dbcache.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/uhttp/wrapper.go is excluded by !vendor/** and included by none
  • vendor/github.com/conductorone/baton-sdk/pkg/us3/s3.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/README.md is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/huff0/bitreader.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/internal/le/le.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/internal/le/unsafe_disabled.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/internal/le/unsafe_enabled.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/s2sx.mod is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/README.md is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/bitreader.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/blockdec.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/blockenc.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/decoder.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/enc_base.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/matchlen_generic.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/seqdec.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/seqdec_generic.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/seqenc.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/snappy.go is excluded by !vendor/** and included by none
  • vendor/github.com/klauspost/compress/zstd/zstd.go is excluded by !vendor/** and included by none
  • vendor/modules.txt is excluded by !vendor/** and included by none
📒 Files selected for processing (3)
  • go.mod (2 hunks)
  • pkg/connector/enterprise_role.go (1 hunks)
  • pkg/connector/invitation.go (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: ci
🔇 Additional comments (6)
go.mod (3)

73-73: klauspost/compress → v1.18.0

LGTM.


3-3: Go 1.25 bump — verify CI/toolchain alignment

go.mod at repo root contains "go 1.25". No .github/workflows, Dockerfiles with golang base images, or .tool-versions/asdf pins were detected in this repo — confirm any external CI (org-level Actions), Docker/image build pipelines, and developer toolchains are aligned to Go 1.25.


6-6: Approve: baton-sdk v0.4.2 upgrade validated — no v0.3 stragglers found

CreateAccount now accepts v2.LocalCredentialOptions (pkg/connector/invitation.go:124–127). No occurrences of the old CredentialOptions were found; annotation identifiers are consistently using &v2.V1Identifier across the codebase.

pkg/connector/enterprise_role.go (1)

122-123: Annotation Id change matches v0.4.x

Using resource.Id.Resource directly is correct.

pkg/connector/invitation.go (2)

48-49: Interface conformance assertion

Good addition; prevents drift.


124-131: CreateAccount now takes LocalCredentialOptions

Matches baton-sdk v0.4.x.

Confirm CreateAccountCapabilityDetails options align with LocalCredentialOptions (NO_PASSWORD only).

@ggreer ggreer force-pushed the ggreer/upgrade-baton-sdk branch from 36da96c to 57fb5f2 Compare September 23, 2025 01:12
@ggreer ggreer force-pushed the ggreer/upgrade-baton-sdk branch from 57fb5f2 to 4d4718b Compare September 23, 2025 01:30
@ggreer ggreer merged commit 36cca22 into main Sep 23, 2025
5 checks passed
@ggreer ggreer deleted the ggreer/upgrade-baton-sdk branch September 23, 2025 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants