Skip to content

fix(land-and-deploy): detect merged PR after gh failure#1620

Open
davidfoy wants to merge 1 commit into
garrytan:mainfrom
davidfoy:fix/land-and-deploy-postfail-state-check
Open

fix(land-and-deploy): detect merged PR after gh failure#1620
davidfoy wants to merge 1 commit into
garrytan:mainfrom
davidfoy:fix/land-and-deploy-postfail-state-check

Conversation

@davidfoy
Copy link
Copy Markdown

Problem

gh pr merge --squash --delete-branch (and --auto variants) can exit non-zero with a local git error — most commonly a worktree conflict like fatal: 'main' is already checked out at '/path' — while the server-side merge has already succeeded. The /land-and-deploy skill had no detection for this case: a naive retry of gh pr merge would be a destructive second attempt against a now-merged PR.

This isn't a worktree-only issue. Any non-zero exit from gh pr merge can mask a successful server-side merge if the API call completed before the local cleanup phase failed. Tracked upstream in cli/cli#3442 and cli/cli#13380.

Symptom in the field: the operator sees a "deploy failed" message, manually investigates, and discovers the PR merged but the deploy never fired — leaving prod on stale code with no automation.

Fix

Replace the previous (worktree-specific) recovery with a universal post-failure invariant: after ANY non-zero gh pr merge exit, query authoritative PR state before retrying or stopping. Three branches:

  • MERGED → success path. Capture merge SHA, offer (don't force) cleanup of clearly-stale worktrees with no uncommitted work, continue to existing §4a CI detection.
  • OPEN + auto-merge enabled → queue-wait path (proceeds to existing merge-queue handling).
  • OPEN (no auto-merge) or CLOSED → genuine failure. Surface both errors, STOP.

Hard rule: never call gh pr merge twice after a failure. Server state is authoritative.

Worktree cleanup is non-destructive — lists candidates, requires no uncommitted work, defers to user rather than --forceing.

Files

  • land-and-deploy/SKILL.md — adds §4a-postfail section between the permission-error STOP and the existing §4a merge-queue detection.

Related

After ANY non-zero exit from `gh pr merge`, query authoritative GitHub PR
state before retrying or stopping. Replaces the narrow worktree-specific
trigger with a universal post-failure invariant.

Three outcome branches:
- MERGED: success path. Capture SHA, offer (non-force) cleanup of clearly-stale
  worktrees with no uncommitted work, continue to CI detection.
- OPEN + auto-merge enabled: queue-wait path (existing merge-queue handling).
- OPEN (no auto-merge) or CLOSED: genuine failure, surface both errors, STOP.

Hard rule: never call `gh pr merge` twice after a failure. Server state is
authoritative. Worktree cleanup is non-destructive — candidates-only, no
--force, defers to user.

Related: cli/cli#3442, cli/cli#13380.
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