Skip to content

fix: prevent duplicate preview deployments on labeled PRs#4552

Open
Wouter8 wants to merge 1 commit into
Dokploy:canaryfrom
Wouter8:fix/duplicate-preview-deployments-labeled
Open

fix: prevent duplicate preview deployments on labeled PRs#4552
Wouter8 wants to merge 1 commit into
Dokploy:canaryfrom
Wouter8:fix/duplicate-preview-deployments-labeled

Conversation

@Wouter8
Copy link
Copy Markdown

@Wouter8 Wouter8 commented Jun 5, 2026

Problem

Opening a PR that has a label produces duplicate preview deployments — a regression of #1204 (issue #1198).

GitHub fires two pull_request webhooks when a labeled PR is opened: opened and labeled. Two later changes made both create a preview for the same PR:

  • e554adc3 added "labeled" to shouldCreateDeployment, so label events can create previews.
  • a212d4249 dropped the UNIQUE(applicationId, pullRequestId) constraint on preview_deployments.

createPreviewDeployment does a non-atomic check-then-insert. With no constraint and no lock, the concurrent opened + labeled webhooks both pass the existence check and both insert, so two previews are created per PR.

Fix

  • Restore the UNIQUE(applicationId, pullRequestId) constraint. The migration de-duplicates existing rows (keeping the oldest per PR/app) before adding it, so it applies cleanly on installs that already have duplicates.
  • Make createPreviewDeployment idempotent: insert first with onConflictDoNothing; the winner does the side effects (comment, domain), the loser returns the existing preview. The "add the label to an open PR later" flow keeps working.
  • Do not redeploy an existing preview on labeled/unlabeled — a label change is not a code change (extracted into shouldDeployPreviewDeployment + unit tests).

Verification

  • Migration + ON CONFLICT path verified against Postgres 16: duplicates collapse to the oldest row, the constraint is added, the racy second insert returns no row, and new PRs still insert.
  • pnpm typecheck passes for @dokploy/server and dokploy.
  • biome check clean; vitest green including new tests.

Opening a PR with a label fires `opened` + `labeled` together; both
created a preview for the same PR after the dedup constraint was dropped
(a212d42) and `labeled` became a trigger (e554adc).

Restore the unique (applicationId, pullRequestId) constraint (de-duping
rows first), make createPreviewDeployment idempotent via
onConflictDoNothing, and stop label events redeploying existing previews.
@Wouter8 Wouter8 requested a review from Siumauricio as a code owner June 5, 2026 13:27
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant