fix(integrations): Fix "Update in GitHub" flow#2215
Conversation
…s urls Add githubInstallationSettingsUrl helper and connect PostHog client finish_setup for GitHub App installation flow from notification settings.
Prompt To Fix All With AIFix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
apps/code/src/renderer/features/settings/components/sections/GitHubIntegrationSection.tsx:48-52
**Silent failure gives no user feedback**
When `prepareGithubTeamIntegrationCallback` throws, the `catch` block silently returns. The user clicks "Update in GitHub" and nothing happens — no GitHub tab opens, no error message appears. At minimum the error should be surfaced (e.g. a toast), otherwise users are left believing the click registered when it didn't.
### Issue 2 of 3
apps/code/src/renderer/features/integrations/utils/githubInstallationSettingsUrl.test.ts:26-51
Three distinct input/output cases are bundled in a single `it` with multiple `expect` calls. The project explicitly prefers parameterised tests — if the first assertion fails the remaining cases are never run, making it harder to pinpoint regressions. Using `it.each` gives each case an independent result and a descriptive name.
```suggestion
describe("resolveGithubInstallationId", () => {
it.each([
[
"prefers top-level installation_id over integration_id and config",
{ id: 99, kind: "github", installation_id: "a", config: { installation_id: "c" } },
"a",
],
[
"falls back to integration_id when installation_id is absent",
{ id: 1, kind: "github", integration_id: 12345 },
"12345",
],
[
"falls back to config.installation_id as last resort",
{ id: 1, kind: "github", config: { installation_id: "c" } },
"c",
],
])("%s", (_label, input, expected) => {
expect(resolveGithubInstallationId(input as Parameters<typeof resolveGithubInstallationId>[0])).toBe(expected);
});
});
```
### Issue 3 of 3
apps/code/src/renderer/api/posthogClient.ts:664
Redundant status guard — `response.ok` is already `true` for every 2xx response including 204, so `&& response.status !== 204` can never change the outcome of the outer `!response.ok` check. Per simplicity rule 4, this is a superfluous part.
```suggestion
if (!response.ok) {
```
Reviews (1): Last reviewed commit: "feat(integrations): wire github finish s..." | Re-trigger Greptile |
| try { | ||
| await client.prepareGithubTeamIntegrationCallback(projectId, nextPath); | ||
| } catch { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Silent failure gives no user feedback
When prepareGithubTeamIntegrationCallback throws, the catch block silently returns. The user clicks "Update in GitHub" and nothing happens — no GitHub tab opens, no error message appears. At minimum the error should be surfaced (e.g. a toast), otherwise users are left believing the click registered when it didn't.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/settings/components/sections/GitHubIntegrationSection.tsx
Line: 48-52
Comment:
**Silent failure gives no user feedback**
When `prepareGithubTeamIntegrationCallback` throws, the `catch` block silently returns. The user clicks "Update in GitHub" and nothing happens — no GitHub tab opens, no error message appears. At minimum the error should be surfaced (e.g. a toast), otherwise users are left believing the click registered when it didn't.
How can I resolve this? If you propose a fix, please make it concise.| describe("resolveGithubInstallationId", () => { | ||
| it("prefers top-level installation_id then id then config", () => { | ||
| expect( | ||
| resolveGithubInstallationId({ | ||
| id: 99, | ||
| kind: "github", | ||
| installation_id: "a", | ||
| config: { installation_id: "c" }, | ||
| }), | ||
| ).toBe("a"); | ||
| expect( | ||
| resolveGithubInstallationId({ | ||
| id: 1, | ||
| kind: "github", | ||
| integration_id: 12345, | ||
| }), | ||
| ).toBe("12345"); | ||
| expect( | ||
| resolveGithubInstallationId({ | ||
| id: 1, | ||
| kind: "github", | ||
| config: { installation_id: "c" }, | ||
| }), | ||
| ).toBe("c"); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Three distinct input/output cases are bundled in a single
it with multiple expect calls. The project explicitly prefers parameterised tests — if the first assertion fails the remaining cases are never run, making it harder to pinpoint regressions. Using it.each gives each case an independent result and a descriptive name.
| describe("resolveGithubInstallationId", () => { | |
| it("prefers top-level installation_id then id then config", () => { | |
| expect( | |
| resolveGithubInstallationId({ | |
| id: 99, | |
| kind: "github", | |
| installation_id: "a", | |
| config: { installation_id: "c" }, | |
| }), | |
| ).toBe("a"); | |
| expect( | |
| resolveGithubInstallationId({ | |
| id: 1, | |
| kind: "github", | |
| integration_id: 12345, | |
| }), | |
| ).toBe("12345"); | |
| expect( | |
| resolveGithubInstallationId({ | |
| id: 1, | |
| kind: "github", | |
| config: { installation_id: "c" }, | |
| }), | |
| ).toBe("c"); | |
| }); | |
| }); | |
| describe("resolveGithubInstallationId", () => { | |
| it.each([ | |
| [ | |
| "prefers top-level installation_id over integration_id and config", | |
| { id: 99, kind: "github", installation_id: "a", config: { installation_id: "c" } }, | |
| "a", | |
| ], | |
| [ | |
| "falls back to integration_id when installation_id is absent", | |
| { id: 1, kind: "github", integration_id: 12345 }, | |
| "12345", | |
| ], | |
| [ | |
| "falls back to config.installation_id as last resort", | |
| { id: 1, kind: "github", config: { installation_id: "c" } }, | |
| "c", | |
| ], | |
| ])("%s", (_label, input, expected) => { | |
| expect(resolveGithubInstallationId(input as Parameters<typeof resolveGithubInstallationId>[0])).toBe(expected); | |
| }); | |
| }); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/integrations/utils/githubInstallationSettingsUrl.test.ts
Line: 26-51
Comment:
Three distinct input/output cases are bundled in a single `it` with multiple `expect` calls. The project explicitly prefers parameterised tests — if the first assertion fails the remaining cases are never run, making it harder to pinpoint regressions. Using `it.each` gives each case an independent result and a descriptive name.
```suggestion
describe("resolveGithubInstallationId", () => {
it.each([
[
"prefers top-level installation_id over integration_id and config",
{ id: 99, kind: "github", installation_id: "a", config: { installation_id: "c" } },
"a",
],
[
"falls back to integration_id when installation_id is absent",
{ id: 1, kind: "github", integration_id: 12345 },
"12345",
],
[
"falls back to config.installation_id as last resort",
{ id: 1, kind: "github", config: { installation_id: "c" } },
"c",
],
])("%s", (_label, input, expected) => {
expect(resolveGithubInstallationId(input as Parameters<typeof resolveGithubInstallationId>[0])).toBe(expected);
});
});
```
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!
| body: JSON.stringify({ next }), | ||
| }, | ||
| }); | ||
| if (!response.ok && response.status !== 204) { |
There was a problem hiding this comment.
Redundant status guard —
response.ok is already true for every 2xx response including 204, so && response.status !== 204 can never change the outcome of the outer !response.ok check. Per simplicity rule 4, this is a superfluous part.
| if (!response.ok && response.status !== 204) { | |
| if (!response.ok) { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/api/posthogClient.ts
Line: 664
Comment:
Redundant status guard — `response.ok` is already `true` for every 2xx response including 204, so `&& response.status !== 204` can never change the outcome of the outer `!response.ok` check. Per simplicity rule 4, this is a superfluous part.
```suggestion
if (!response.ok) {
```
How can I resolve this? If you propose a fix, please make it concise.Keep repo tooltip summarization from main alongside finish_setup wiring.
What's broken
If you already have GitHub connected and hit "Update in GitHub" in Code settings, it wasn't doing the right thing. It kicked off a fresh connect flow instead of taking you to your existing app installation. And when you came back after changing repo access on GitHub, Code didn't reliably pick up the update (esp. the
setup_action=updatepath where GitHub doesn't sendstate).What this fixes
"Update in GitHub" now opens the correct GitHub installation settings page (org installs vs personal installs are different URLs), and sets up the callback so PostHog knows to finish setup when you return. You land back in Code with refreshed integration state. Initial "Connect GitHub" is unchanged..
Needs PostHog/posthog#58951 on the backend for the return trip to actually work end-to-end.