-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Bug Description
Preview deployments configured with previewLabels fail ~80% of the time because the labeled webhook action cannot create new preview deployment records — only opened, synchronize, and reopened can.
Root Cause
In apps/dokploy/pages/api/deploy/github.ts, the shouldCreateDeployment flag excludes labeled:
const shouldCreateDeployment =
action === "opened" ||
action === "synchronize" ||
action === "reopened";This interacts with GitHub's non-deterministic webhook ordering (documented in GitHub Community Discussion #69337). When a PR is created with a label (e.g. gh pr create --label preview), GitHub fires both opened and labeled webhooks, but their delivery order is unpredictable.
Failure case (~80% of the time):
openedarrives first — PR has no label yet in the payload → label check (if (!hasLabel) continue) skips the app → no preview createdlabeledarrives second — label check passes, butshouldCreateDeploymentisfalse→ cannot create a new preview deployment record → nothing happens
Success case (~20% of the time):
labeledarrives first —shouldCreateDeploymentis false, no effectopenedarrives second — by now the label is present in the payload → label check passes → preview created
The handler returns {"message": "Apps Deployed"} with HTTP 200 in both cases, making this silent.
Steps to Reproduce
- Configure an application with preview deployments enabled and
previewLabelsset (e.g.,["preview"]) - Create a PR targeting the configured branch with the label applied at creation time (e.g.,
gh pr create --label preview) - Observe that preview deployment is created inconsistently — fails most of the time
Evidence
We tested by creating 5 identical PRs with gh pr create --label test and observed the webhook delivery order:
| PR | Webhook order | Would preview work? |
|---|---|---|
| 1 | opened → labeled | No |
| 2 | opened → labeled | No |
| 3 | labeled → opened | Yes |
| 4 | opened → labeled | No |
| 5 | opened → labeled | No |
4 out of 5 failed (80% failure rate).
Suggested Fix
Add "labeled" to the shouldCreateDeployment condition:
const shouldCreateDeployment =
action === "opened" ||
action === "synchronize" ||
action === "reopened" ||
action === "labeled";unlabeled should remain excluded — removing a label should not create new preview deployments.
This also fixes the secondary use case where a user opens a PR first and adds the label later — currently that also fails silently.
Affected Versions
All versions from v0.25.0 (when previewLabels was introduced in PR #2231) through v0.28.5 (latest).
Environment
- Dokploy v0.28.4, self-hosted
- GitHub App integration (not OAuth)