Skip to content

Comments

fix: don't treat UNSTABLE merge state as blocker when CI is pending#126

Open
AgentWrapper wants to merge 5 commits intomainfrom
fix/unstable-merge-state-logic
Open

fix: don't treat UNSTABLE merge state as blocker when CI is pending#126
AgentWrapper wants to merge 5 commits intomainfrom
fix/unstable-merge-state-logic

Conversation

@AgentWrapper
Copy link
Collaborator

@AgentWrapper AgentWrapper commented Feb 19, 2026

Summary

GitHub's mergeStateStatus: UNSTABLE means required status checks exist but aren't all passing. Previously we unconditionally added "Required checks are failing" as a blocker, which caused two problems:

  1. False alarm for pending CI — dashboard showed "Required checks are failing" while CI was just running
  2. Redundant blockers for failing CI — both "CI is failing" (from CI section) and "Required checks are failing" (from UNSTABLE section) appeared simultaneously

Fix: Gate the UNSTABLE blocker on ciPassing — it only fires when the CI section didn't already report the problem. This is also the fail-closed safety net for edge cases where our CI aggregation says "none" (all skipped) but GitHub still reports UNSTABLE.

Blocker matrix after fix

ciStatus CI section blocker UNSTABLE blocker Notes
failing "CI is failing" (none) CI section covers it
pending "CI is pending" (none) Not failing, just running
none (none) "Required checks are failing" Fail-closed safety net
passing (none) "Required checks are failing" Fail-closed safety net

Test plan

  • reports CI failures as blockers — UNSTABLE + FAILURE: only "CI is failing", no duplicate
  • falls back to CI failing when CI fetch fails — UNSTABLE + error: only "CI is failing"
  • does not treat UNSTABLE as a blocker when CI is pending — UNSTABLE + PENDING: only "CI is pending"
  • reports UNSTABLE as blocker when CI status is none (fail closed) — UNSTABLE + SKIPPED: "Required checks are failing"
  • All 56 scm-github tests pass
  • Full suite: typecheck + lint + test all green

🤖 Generated with Claude Code

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

AgentWrapper and others added 5 commits February 20, 2026 18:57
GitHub's mergeStateStatus: UNSTABLE means required status checks exist
but aren't all passing — it doesn't distinguish between pending and
failing. Previously we unconditionally added "Required checks are
failing" as a blocker, which made the dashboard show PRs as unmergeable
while CI was still running.

Now cross-references UNSTABLE with the actual ciStatus: only adds the
blocker when CI is genuinely failing, not when checks are still pending.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous check (ciStatus === FAILING) left a gap: when ciStatus is
"none" (all checks skipped) but GitHub says UNSTABLE, neither section
added a blocker — false positive "mergeable". Flipped to
ciStatus !== PENDING so we only suppress the UNSTABLE blocker for the
one case where it's misleading (checks still running).

Added test for UNSTABLE + skipped-only checks to cover the fail-closed
edge case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of checking ciStatus !== PENDING (which still adds a redundant
"Required checks are failing" alongside "CI is failing"), gate on
ciPassing — the UNSTABLE blocker now only fires when the CI section
didn't already report the problem. This eliminates duplicate blockers
while preserving the fail-closed safety net for edge cases (e.g. all
checks skipped but GitHub reports UNSTABLE).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Trimmed the 7-line UNSTABLE comment to 3 lines. Replaced toContain +
not.toContain pairs with toEqual([...]) so tests pin the exact blocker
list — no unexpected extras can sneak in undetected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AgentWrapper AgentWrapper force-pushed the fix/unstable-merge-state-logic branch from d2b5037 to ca45d42 Compare February 20, 2026 13:31
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