Skip to content

fix: remove redundant isSynchronized deploy handler to prevent concurrent builds#219

Merged
vigneshrajsb merged 3 commits into
mainfrom
fix/pr-sync-missing-trigger-ref
Jun 23, 2026
Merged

fix: remove redundant isSynchronized deploy handler to prevent concurrent builds#219
vigneshrajsb merged 3 commits into
mainfrom
fix/pr-sync-missing-trigger-ref

Conversation

@vigneshrajsb

@vigneshrajsb vigneshrajsb commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Problem

PR #205 added a pull_request synchronize handler that calls enqueueResolveAndDeployBuild whenever a PR branch receives new commits. The intent was to ensure PR environments rebuild on push, but the push event handler already covers this completely.

deployable.defaultBranchName stores the literal yaml value (@branch, main, etc.) — never the resolved PR branch name. This means shouldBuild in the push handler is always true for PR environments:

serviceBranchName = "@branch"      →  shouldBuild = ("@branch" !== "feature/my-pr") = true ✅
serviceBranchName = "main"         →  shouldBuild = ("main"    !== "feature/my-pr") = true ✅

Every service in the environment is already rebuilt by the push handler. The synchronize handler was redundant.

Impact

Having both handlers enqueue for the same commit produces two concurrent resolveAndDeployBuild runs that race for runUUID ownership. If the losing run encounters any error, recordBuildFailure force-patches runUUID and writes ERROR status — even though the winning run's services are healthy. This is the root cause of PR environments appearing failed in the UI when all services are actually running.

Fix

Remove the isSynchronized block from handlePullRequestHook and its now-unused isSynchronized variable. Remove the corresponding test.

Test plan

  • All 350 tests pass
  • Lint clean
  • Validate on staging: push a commit to a PR env branch, confirm only one resolveAndDeployBuild run fires (single runUUID in Groundcover logs, no duplicate K8s build jobs)

…event

When a user pushes to a PR branch, GitHub fires both a push event and a
pull_request synchronize event for the same commit. PR #218 added triggerRef
(the commit SHA) to the push handler's enqueueResolveAndDeployBuild call so
that back-to-back distinct commits are not silently coalesced. However, the
synchronize handler was not updated, so it still enqueues with no triggerRef.

The two events now produce different dedupe keys:
  push:     resolve:<buildId>:<fingerprint>:<commitSha>
  sync:     resolve:<buildId>:<fingerprint>

Both jobs run concurrently, race for runUUID ownership, and if the losing run
encounters an error it patches the build status to ERROR even though all
services are healthy.

Fix: pass the same branchSha as triggerRef in the synchronize handler so both
events produce identical dedupe keys and coalesce to a single
resolveAndDeployBuild run.
@vigneshrajsb vigneshrajsb requested a review from a team as a code owner June 23, 2026 00:53
…te coalescing

The previous comment claimed push and synchronize produce the same dedupe key
and coalesce, which is only true when the push path omits githubRepositoryId
(e.g. the failed-deploy rebuild path). In the normal case, push passes
githubRepositoryId so its fingerprint differs from the synchronize path even
with matching triggerRef. Update the comment to accurately describe the fix as
preventing back-to-back synchronize events for distinct commits from collapsing.
The pull_request synchronize handler added in PR #205 enqueues
resolveAndDeployBuild for every PR push, but the push event handler already
covers the same work. deployable.defaultBranchName stores the literal yaml
value (e.g. "@Branch", "main"), never the resolved PR branch name, so
shouldBuild is always true for PR environments — the push handler fires for
every service without exception.

Having both handlers enqueue for the same commit causes two concurrent
resolveAndDeployBuild runs that race for runUUID ownership. If the losing run
hits any error, recordBuildFailure force-patches runUUID and writes ERROR
status even though the winning run's services are healthy.

Remove the synchronize block and its now-unused isSynchronized variable.
Remove the corresponding test that asserted the redundant enqueue.
@vigneshrajsb vigneshrajsb changed the title fix: pass triggerRef in PR synchronize handler to coalesce with push event fix: remove redundant isSynchronized deploy handler to prevent concurrent builds Jun 23, 2026
@vigneshrajsb vigneshrajsb merged commit 7c8c06b into main Jun 23, 2026
5 checks passed
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