Skip to content

Fix GitHub App setup race and tidy integrations cards - #538

Merged
simonhamp merged 1 commit into
mainfrom
fix-github-install-dupe
Sep 26, 2026
Merged

simonhamp merged 1 commit into
mainfrom
fix-github-install-dupe

Conversation

@simonhamp

Copy link
Copy Markdown
Member

Fixes Nightwatch issue 97, a 500 on /auth/github/setup with a duplicate key on github_installations.installation_id.

GitHub sends the installation.created webhook at the same moment it redirects the user to the setup URL. The setup request looked up the installation, didn't find it, then asked GitHub's /user/installations whether it belonged to the user. The webhook saved the row while that call was in flight, so the setup's create() hit the unique key.

Setup now uses GitHubInstallation::createOrFirst(). If the webhook got there first, setup picks up that row and syncs it as usual. The "already linked to another NativePHP account" check has moved below the lookup, so it also catches a row that appears mid-request under a different user. createOrFirst() is called on the model rather than through $user->githubInstallations() because the relation version only looks for the current user's rows and would rethrow in that case. The webhook side already used updateOrCreate(), which copes with losing the race.

Two new tests in GitHubAppSetupTest fake GitHub so the row appears while the request is checking. Both failed with the production error before the fix.

This also tidies the cards on the integrations page, which had mixed corner radii and one had a shadow. The App Installations card is now a Flux card like the GitHub Account card above it, so it loses the shadow and its oversized heading. The claude-code, mobile and Discord cards and the GitHub migration banner go from rounded-lg to rounded-xl to match Flux cards and callouts. Colours are unchanged apart from the Installations card's dark mode background, which was navy and now matches the other plain cards. The migration banner also appears on the plugin index and create pages, so those pick up the new radius too.

🤖 Generated with Claude Code

GitHub sends the installation webhook at the same moment it redirects the
user to the setup URL. The webhook could save the installation while the
setup request was still checking it with GitHub, so the setup's create()
hit the unique key on installation_id. Setup now uses createOrFirst() and
checks who owns the installation afterwards.

The cards on the integrations page now share the Flux card radius and none
has a shadow. The App Installations card is a Flux card like the GitHub
Account card above it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simonhamp
simonhamp marked this pull request as ready for review September 26, 2026 14:33
@simonhamp
simonhamp merged commit 0dccdfd into main Sep 26, 2026
3 checks passed
@simonhamp
simonhamp deleted the fix-github-install-dupe branch September 26, 2026 14:40
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.

1 participant