Skip to content

main branch protection deadlocks workflow-only PRs (app-pinned build-and-test required by ruleset + classic protection, no bypass) #375

Description

@don-petry

Summary

Workflow-only PRs to main (e.g. #370, the dev-lead statuses:read shim fix) cannot be merged through the API — not even by an org admin with --admin. Surfaced while merging the dev-lead #402 series.

Root cause — a self-deadlocking required check, enforced twice

The required status check build-and-test is:

  1. Required by the code-quality ruleset (id 14872174) — which has an empty bypass_actors list, so nobody (not even admins) can bypass it; and
  2. also required by classic branch protection on main, with strict: true and enforce_admins: true (admins are explicitly subject to it).

build-and-test is pinned to a specific GitHub App, and its workflow doesn't run on workflow-file-only changes (path filters), so it never posts a status → the required check sits in expected forever → the PR is permanently unmergeable. A manually-posted commit status is rejected ("not set by the expected GitHub app"). --admin is rejected because enforce_admins: true + the ruleset has no bypass actor.

This is a redundant + over-strict protection config: the same check is required by both a ruleset and legacy classic protection, and neither path allows an override.

Workaround used to merge #370 (fully reverted)

Temporarily, in a guarded sequence with a trap ensuring restoration:

  1. set code-quality ruleset enforcement → disabled
  2. disabled classic enforce_admins
  3. gh pr merge --admin --squash
  4. restored both (verified: enforcement=active, enforce_admins=true, bypass_actors=[])

Recommended fixes (for investigation)

  • Remove the redundant classic branch protection on main — rulesets supersede it; maintaining both is the core trap.
  • Make build-and-test not required for workflow-only PRs (path-aware), or post a neutral/success status for paths it skips, so it can't deadlock.
  • Add an admin bypass actor to the code-quality ruleset (mirroring protect-branches, which already has one), so future emergencies don't need protection to be toggled.
  • Audit the other org repos for the same classic-protection + ruleset redundancy and app-pinned-check deadlock (bmad-bgreat-suite#273 hit a similar CodeQL stall, resolvable via a posted status — gas was stricter).

Filed unlabeled deliberately (no dev-lead label) so the agent doesn't try to auto-implement it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions