fix(preview): create one preview per pull request when webhook deliveries race - #5460
Open
mikaoelitiana wants to merge 1 commit into
Open
mikaoelitiana wants to merge 1 commit into
mikaoelitiana wants to merge 1 commit into
Conversation
…ries race GitHub sends one `pull_request` delivery per label on top of `opened`, all within the same second. The handler guarded creation with a non-atomic `findPreviewDeploymentByApplicationId` → `createPreviewDeployment`, and the GitHub comment round-trip inside `createPreviewDeployment` widened the window to several seconds, so every delivery saw no existing preview and created its own — one container, domain and PR comment each. Serialize the find-or-create per (application, pull request) so concurrent deliveries wait for the first to insert and then see its row. A `labeled` delivery that finds an existing preview now returns without enqueueing a build: a label never moves the PR head, so there is nothing to rebuild, and this collapses the N redundant same-SHA builds the extra deliveries used to queue. Closes Dokploy#5086 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR about?
One pull request could end up with several preview deployments (#5086). GitHub sends one
pull_requestdelivery per label on top ofopened, all within the same second, andpages/api/deploy/github.tsguards creation with a non-atomicfindPreviewDeploymentByApplicationId→createPreviewDeployment. The GitHub comment round-trip insidecreatePreviewDeploymentmakes the check→insert window several seconds wide, so every delivery sees no existing preview and creates its own container, domain and PR comment.Two changes, both in the webhook handler:
(applicationId, pullRequestId)with a small in-process promise chain (withPreviewLock). Concurrent deliveries for the same PR now wait for the first one to insert its row and then find it, so exactly one preview is created.labeleddelivery that finds an existing preview no longer enqueues a build. A label event never moves the PR head, so there is nothing to rebuild. This also collapses the N redundant same-SHA builds the extra deliveries used to queue.labeledon a PR without a preview still creates one (the label-filter opt-in flow from feat: add support for 'labeled' action in GitHub deployment handler #3960 is unchanged), andsynchronize/reopenedstill redeploy.Why not a unique constraint on
(applicationId, pullRequestId)? Instances hit by this bug already hold duplicate rows for open PRs (ours has three for one PR), so a migration adding the constraint would fail on upgrade, and deleting the extra rows in the migration would orphan their containers and domains. The lock fixes the self-hosted single-process case without touching the schema. It is process-local, so a horizontally scaled deployment of the webhook handler would still need the constraint once existing rows can be reconciled.Testing
apps/dokploy/__test__/deploy/github-webhook-handler.test.tsgains three cases:opened+ twolabeleddeliveries racing create one preview and one build;labeledon an existing preview enqueues nothing;labeledon a PR without a preview still creates one. The first two fail on unpatchedcanary(3 creates instead of 1; 1 queued build instead of 0) and pass with this change.biome checkclean on both files;tsc --noEmitforapps/dokployreports no errors.Checklist
canarybranch.Issues related (if applicable)
closes #5086
🤖 Generated with Claude Code
The PR appears safe to merge, with the intended single-process race addressed and no actionable regressions identified.
Summary
labeleddelivery finds an existing preview.Reviews (1) · Last reviewed commit: "fix(preview): create one preview per pul..."