Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

feat(code): unify user-scoped GitHub connect into a shared hook - #1996

Merged
k11kirky merged 1 commit into
mainfrom
posthog-code/unify-github-connect
May 4, 2026
Merged

k11kirky merged 1 commit into
mainfrom
posthog-code/unify-github-connect

Conversation

@k11kirky

@k11kirky k11kirky commented May 4, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The GitHub user connect logic was duplicated across GitHubConnectionBanner and GitIntegrationStep, making it harder to maintain and reason about. Each component independently managed connection state, polling timers, timeout handling, query invalidation, and the window-focus refetch fallback.

Changes

Extracts all GitHub user connect logic into a new useGithubUserConnect hook that encapsulates:

  • Connection state (idle, connecting, timed-out)
  • Opening the GitHub install URL in the browser
  • Dev-mode polling fallback for query invalidation
  • Safety timeout after 5 minutes of inactivity
  • Window-focus refetch while a connection is in flight
  • useGitHubIntegrationCallback integration for deep-link success/error handling

GitHubConnectionBanner and GitIntegrationStep are updated to use the new hook, removing their inline implementations. The isConnectingGithub field and setConnectingGithub action are removed from the onboarding store since connection state is now owned by the hook.

@greptile-apps

greptile-apps Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/code/src/renderer/features/integrations/hooks/useGithubUserConnect.ts:89-93
**`toast.error` fires unconditionally regardless of connection state**

`onError` calls `toast.error(message)` even when `state === "idle"`. For `GitHubConnectionBanner` — which is mounted in the persistent inbox UI — this means that if a stale pending error callback is consumed on mount via `consumePendingCallback` (e.g. left over from a previous connect attempt in another session), the user will see an unexpected error toast with no obvious cause. The original banner didn't use `useGitHubIntegrationCallback` at all, so this is a new behaviour for that consumer.

Guard the toast (and optionally the full `onError` body) behind a state check:

```typescript
onError: (message) => {
  stopPolling();
  if (stateRef.current === "connecting") {
    toast.error(message);
  }
  setState("idle");
},
```

### Issue 2 of 2
apps/code/src/renderer/features/integrations/hooks/useGithubUserConnect.ts:114-119
**Redundant `projectId !== null` guard**

`projectId !== null` is already guaranteed at this point — the `connect` callback returns early on line 103 if `projectId === null`. The extra check is superfluous and contradicts the simplicity rule of "no superfluous parts".

```typescript
      if (IS_DEV) {
        pollTimerRef.current = setInterval(
          () => invalidate(projectId),
          POLL_INTERVAL_MS,
        );
      }
```

Reviews (1): Last reviewed commit: "feat(code): unify user-scoped GitHub con..." | Re-trigger Greptile

Comment on lines +89 to +93
onError: (message) => {
stopPolling();
setState("idle");
toast.error(message);
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 toast.error fires unconditionally regardless of connection state

onError calls toast.error(message) even when state === "idle". For GitHubConnectionBanner — which is mounted in the persistent inbox UI — this means that if a stale pending error callback is consumed on mount via consumePendingCallback (e.g. left over from a previous connect attempt in another session), the user will see an unexpected error toast with no obvious cause. The original banner didn't use useGitHubIntegrationCallback at all, so this is a new behaviour for that consumer.

Guard the toast (and optionally the full onError body) behind a state check:

onError: (message) => {
  stopPolling();
  if (stateRef.current === "connecting") {
    toast.error(message);
  }
  setState("idle");
},
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/integrations/hooks/useGithubUserConnect.ts
Line: 89-93

Comment:
**`toast.error` fires unconditionally regardless of connection state**

`onError` calls `toast.error(message)` even when `state === "idle"`. For `GitHubConnectionBanner` — which is mounted in the persistent inbox UI — this means that if a stale pending error callback is consumed on mount via `consumePendingCallback` (e.g. left over from a previous connect attempt in another session), the user will see an unexpected error toast with no obvious cause. The original banner didn't use `useGitHubIntegrationCallback` at all, so this is a new behaviour for that consumer.

Guard the toast (and optionally the full `onError` body) behind a state check:

```typescript
onError: (message) => {
  stopPolling();
  if (stateRef.current === "connecting") {
    toast.error(message);
  }
  setState("idle");
},
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +114 to +119
if (IS_DEV && projectId !== null) {
pollTimerRef.current = setInterval(
() => invalidate(projectId),
POLL_INTERVAL_MS,
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Redundant projectId !== null guard

projectId !== null is already guaranteed at this point — the connect callback returns early on line 103 if projectId === null. The extra check is superfluous and contradicts the simplicity rule of "no superfluous parts".

      if (IS_DEV) {
        pollTimerRef.current = setInterval(
          () => invalidate(projectId),
          POLL_INTERVAL_MS,
        );
      }
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/integrations/hooks/useGithubUserConnect.ts
Line: 114-119

Comment:
**Redundant `projectId !== null` guard**

`projectId !== null` is already guaranteed at this point — the `connect` callback returns early on line 103 if `projectId === null`. The extra check is superfluous and contradicts the simplicity rule of "no superfluous parts".

```typescript
      if (IS_DEV) {
        pollTimerRef.current = setInterval(
          () => invalidate(projectId),
          POLL_INTERVAL_MS,
        );
      }
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@jonathanlab jonathanlab left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice

@k11kirky
k11kirky force-pushed the posthog-code/unify-github-connect branch from 4c4c4e4 to 025691b Compare May 4, 2026 14:14

k11kirky commented May 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Merge activity

  • May 4, 2:36 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 4, 2:38 PM UTC: Graphite rebased this pull request as part of a merge.
  • May 4, 2:46 PM UTC: @k11kirky merged this pull request with Graphite.

@k11kirky
k11kirky changed the base branch from 05-04-feat_code_cleaner_github_integration_onboarding_step to graphite-base/1996 May 4, 2026 14:36
@k11kirky
k11kirky changed the base branch from graphite-base/1996 to main May 4, 2026 14:36
@k11kirky
k11kirky force-pushed the posthog-code/unify-github-connect branch from 025691b to 46ab5f9 Compare May 4, 2026 14:37
@k11kirky
k11kirky merged commit 491c460 into main May 4, 2026
16 checks passed
@k11kirky
k11kirky deleted the posthog-code/unify-github-connect branch May 4, 2026 14:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants