home-assistant

ha-merge-queue

Finds open Home Assistant pull requests that are genuinely ready to merge, checking CI, the merge-gate statuses, code-owner approval, merge conflicts, requested changes and unresolved review threads. Use when looking for PRs to merge, doing merge-queue triage, or asking for "quick wins" from the open PR backlog.

home-assistant 90,170 38,428 Updated 1w ago
GitHub

Install

npx skillscat add home-assistant/core/ha-merge-queue

Install via the SkillsCat registry.

About this skill

The skill searches open Home Assistant pull requests, filters out those that are not mergeable, and verifies that each candidate has passing CI, required approvals, no merge conflicts, and no pending review comments. It helps maintainers quickly identify PRs that can be merged immediately or need a single action to become ready.

SKILL.md

Find Ready-to-Merge Pull Requests

Produce a shortlist of open PRs a maintainer can approve and merge immediately, plus a
short list of near-misses that each need one specific nudge. Default to 10 candidates
unless the user asks for a different number.

Gather candidates

Search open PRs, excluding those that are structurally not mergeable:

repo:home-assistant/core is:open is:pr draft:false status:success -review:changes_requested
  -label:"awaiting-frontend" -label:"stale" -label:"cla-needed"

Add label:"small-pr" for quick wins, or label:"code-owner-approved" / review:approved
for PRs already carrying an approval. Run several searches and pool the results — no single
query surfaces everything.

The search index lags reality by hours. Treat status: as a rough filter, never as proof;
verify every finalist with the per-PR checks below.

Verify each finalist

Check all five. A PR fails the shortlist if any one fails.

Paginate every list response before deciding. Check runs, reviews and review threads are all
paged, typically 30 per page, and a full-suite Home Assistant PR runs to 40-odd check runs —
so page one shows a green subset while a failure or a standing review sits on page two.
Compare the returned count against the reported total and keep fetching until they match.

  1. Merge-gate statuses — fetch the combined commit status. This is the cheapest and
    most informative call, and it is what actually blocks the merge button. Five contexts
    matter: code-owner-approval (required for Platinum integrations),
    required-labels (red when the author checked no "Type of change" box),
    docs-missing (red when a user-facing change has no documentation PR), cla-bot, and
    blocking-label-awaiting-frontend.

  2. Check runs — the commit statuses do not cover GitHub Actions. Fetch the check runs
    and require every one to have reached an acceptable terminal result: status must be
    completed, and conclusion must be success, skipped or neutral. Everything else
    disqualifies — failure, cancelled, timed_out, action_required and stale, and
    any run still queued or in_progress. A green combined status sitting on top of a red
    or still-running test job is common, so the status list alone is never enough.

  3. Merge conflicts — read mergeable_state. GitHub computes it asynchronously: a
    request that finds no cached answer returns unknown and starts the computation, and
    the request after that can still return unknown. Poll with bounded retries — a few
    attempts, pausing between them — and treat an unknown that never resolves as not
    ready, rather than assuming it is fine.

    • clean — every merge requirement met; merge now
    • blocked — some branch-protection requirement is unmet. It does not specifically mean
      "waiting on an approval", so do not report it that way by default: use the other four
      checks to establish which requirement is missing, and only call it awaiting review once
      they all come back clean.
    • behind — the base branch has moved on. Actionable and often a one-click update, so
      surface it rather than dropping the PR.
    • unstable — a non-required check is failing. Find out which one before shortlisting.
    • dirty — merge conflict. The author needs to merge dev into the branch. Do not tell
      them to rebase: AGENTS.md forbids rewriting history on a PR branch once the PR is
      open, because reviewers need to see what changed since their last review.
      homeassistant/generated/integrations.json conflicts constantly, so PRs adding
      integrations go stale fast.
    • anything else (draft, has_hooks, a value not listed here) — do not guess at what it
      means. Treat the PR as not ready and report the value you got.
  4. Review submissions — fetch the reviews, not just the threads. A CHANGES_REQUESTED
    review is returned here and nowhere else, and a reviewer can request changes with only a
    top-level body and no inline comments — such a PR has zero open review threads and looks
    clean to the check above. Take the latest submission per reviewer: a standing
    CHANGES_REQUESTED that no later APPROVED from the same person supersedes disqualifies
    the PR, regardless of whether its inline threads have since been resolved — resolving a
    thread does not withdraw the review. Do not lean on the -review:changes_requested
    search qualifier instead — the
    index is stale, and mergeable_state: blocked does not distinguish "needs an approval"
    from "changes were requested".

  5. Review threads — fetch review threads and read is_resolved. Judge a thread by
    whether it is resolved or substantively addressed, never by who wrote it: an unresolved
    finding from copilot-pull-request-reviewer is a bug report and can be a real defect,
    so read it on its merits before discounting it. Every thread still open counts against
    the PR until you have read it and concluded it needs no change — the question was
    answered, the suggestion was considered and declined, the point was fixed elsewhere in
    the diff. Say for each open thread what it is and why it does or does not block. Never
    discount one for the category it appears to fall into; an unaddressed defect is a
    blocker whether or not anyone is arguing about it.

Report

Rank by how little work each PR needs: clean first, then blocked with everything else
green. For each PR give the number as a full markdown link, the integration or core area,
one line on what it does, and its blocking state. Plenty of home-assistant/core PRs touch
helpers, the framework, the recorder or repo tooling and have no integration at all — name
what they touch instead, rather than dropping them or inventing one.

Then list the near-misses separately, each with the one action that unblocks it. The
recurring ones:

  • A failing test unrelated to the diff — name the test, say re-run the job.
  • required-labels red — name the label to add (bugfix, new-feature, …).
  • Awaiting code-owner approval — name the code owner from manifest.json.
  • A standing CHANGES_REQUESTED review — name the reviewer, and say what they asked for.
  • dirty — the author must merge dev and regenerate any generated files.

Call out mismatches worth a maintainer's attention: a PR whose body declares a breaking
change but carries no breaking-change label will silently miss the release notes.

IMPORTANT

  • Only report in the CONSOLE. DO NOT ACT ON GITHUB — no comments, no reviews, no merges,
    no pushes to contributor branches. Per AI_POLICY.md, a human decides and acts.
  • Never call a PR ready on green CI alone. Read the diff of every PR you shortlist; CI
    cannot tell you whether the change is correct or wanted.