Sitelet https://github.com/smartwatermelon/github-workflows/issues/87
Skip to content

dependabot-auto-merge is inert in 29/51 fleet repos: can_approve_pull_request_reviews unset by installer #87

Description

@twistedmelonman

Summary

dependabot-auto-merge.yml is installed in 51/51 smartwatermelon repos, but silently does nothing unless the per-repo Actions setting can_approve_pull_request_reviews is true. 29 of the 51 have it false, so the workflow is inert in a majority of the fleet. There is no account-level default for this setting — it must be set per repo — and nothing in the install path sets or checks it.

Mechanism

The workflow runs both commands in one run: block, which uses bash -e:

run: |
  gh pr review --approve "$PR_URL"
  gh pr merge --auto --squash --delete-branch "$PR_URL"

With can_approve_pull_request_reviews: false, GitHub rejects the approval (GitHub Actions is not permitted to approve pull requests). Under -e that aborts the step, so gh pr merge --auto never executes and the PR is left open. The failure mode is a red check on an otherwise-mergeable PR — not an obviously actionable error.

Note this bites even where approvals are not required: on qwen-sidebar, required_approving_review_count is 0, so the approval was never needed. It is the hard failure of the call that breaks the chain, not a missing approval.

Current fleet state

count
repos with dependabot-auto-merge.yml 51
can_approve_pull_request_reviews: true (functional) 22
can_approve_pull_request_reviews: false (inert) 29

can_approve=false:

  • .github
  • x-thread-reader
  • mac-server-setup
  • free-claude-code
  • lamatic
  • Auramaur
  • github-workflows
  • pre-commit-testing
  • transmission-filebot
  • tilsit-caddy
  • ocean-dashboard-k8s
  • lock-sync-old
  • git-config
  • bash-config
  • markdownlint-config
  • shellcheck-config
  • yt-dlp-config
  • yamllint-config
  • tidy-config
  • dig-config
  • btop-config
  • vim-config
  • pre-commit-config
  • claude-sandbox
  • mac-migration
  • beam-sre-kata
  • anniversary
  • sailpoint-sre
  • cat-boxen

Note github-workflows and .github are both in the broken set.

Status: latent, not yet widely manifest

Being precise about impact, since the audit does not show 29 repos full of stuck PRs:

  • Most broken repos have simply not received a patch/minor Dependabot PR since install. Sampled dependabot-auto-merge.yml runs in those repos are skipped — the github.actor == 'dependabot[bot]' guard correctly declining non-Dependabot PRs. The failing path has not been exercised.
  • Two repos do have long-stuck open Dependabot PRs — .github#9 (actions/checkout 6→7, open since 2026-06-20) and free-claude-code#2 (uv group, open since 2026-06-29) — but at least .github#9 has a different root cause: no auto-merge run exists for that branch at all and no checks are reported, so the workflow never fired. Do not attribute these two to this issue without separate investigation.

So the accurate claim is that 29 repos will fail on their next qualifying Dependabot PR, not that 29 are currently backed up. The mechanism itself is well-evidenced: claude-config has the setting true and its Dependabot PRs merge cleanly (#184, #142, #141, #124), while qwen-sidebar had it false and was verified non-functional before being corrected.

Suggested remediation

One-shot fleet fix:

gh repo list smartwatermelon --limit 200 --json name --jq '.[].name' | while read -r r; do
  gh api "repos/smartwatermelon/$r/contents/.github/workflows/dependabot-auto-merge.yml" \
    --jq '.name' >/dev/null 2>&1 || continue
  cur=$(gh api "repos/smartwatermelon/$r/actions/permissions/workflow" \
    --jq '.can_approve_pull_request_reviews' 2>/dev/null)
  [ "$cur" = "true" ] && continue
  echo "fixing $r"
  gh api -X PUT "repos/smartwatermelon/$r/actions/permissions/workflow" \
    -F can_approve_pull_request_reviews=true \
    -f default_workflow_permissions=read
done

default_workflow_permissions=read is passed explicitly because the PUT replaces the whole object; omitting it would reset the field. Every audited repo is already read, and the workflow declares its own permissions: block, so read is correct to preserve.

Durable fixes worth considering, in rough order of value:

  1. Have bulk-install-claude-review.sh (or a sibling installer) set this setting when it installs dependabot-auto-merge.yml. Installing a workflow that cannot function is the root problem — the setting is part of the deliverable, not the environment.
  2. Add it to the installer's classification output, so a repo with the workflow but the setting off reports as STALE/BROKEN rather than CURRENT.
  3. Fail loudly in the workflow. Since required_approving_review_count is frequently 0, the approve call is often unnecessary; making it non-fatal would let auto-merge proceed where no approval is required:
    gh pr review --approve "$PR_URL" \
      || echo "::warning::Approval failed (check can_approve_pull_request_reviews); continuing to auto-merge."
    gh pr merge --auto --squash --delete-branch "$PR_URL"
    This trades a silent stall for a visible warning, and still works where approval is genuinely required (auto-merge just waits).
  4. Document the setting in the rollout playbook as a prerequisite.

Options 1 and 3 are complementary — 1 prevents the misconfiguration, 3 makes it non-fatal and diagnosable when it recurs.

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