Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions evals/evals.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@
"name": "required-check-queued-not-running",
"prompt": "My PR has been waiting on CI for forty minutes and the status tool says the required checks are still running. Should I enqueue it for merge so it goes in as soon as they finish?",
"expected_output": "Should check whether those checks are actually running or merely queued: queued and in_progress are different API states, and a required check sitting in queued with nothing running means no runner has picked it up, not that CI is slow; should warn that a merge queue drops an entry whose required check does not report inside check_response_timeout_minutes and that the clock covers waiting for a runner, so enqueueing now risks a silent dequeue and each retry leaves more runs holding slots; should not try to look up the concurrency limit, which is not exposed by the API"
},
{
"id": 27,
"name": "blocked-with-everything-green",
"prompt": "My PR is mergeStateStatus BLOCKED. Every check passes, no review thread is open, the ruleset needs zero approvals and every required context is present. What is holding it?",
"expected_output": "Should suspect an unsigned commit rather than re-reading branch protection: a required_signatures ruleset is shut by one commit anywhere on the branch that carries no valid signature, and GitHub surfaces that only as BLOCKED, never as a failing check or a rollup entry, so nothing visible names it; should check every commit on the branch, not just the head, and re-sign the branch with a rebase that amends each commit rather than only the tip"
}
]
}
22 changes: 22 additions & 0 deletions skills/git-workflow/scripts/pr-status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ collect() {
... on User{login} ... on Bot{login} ... on Team{slug} } } }
reviewThreads(first:100){ nodes{ id isResolved isOutdated
comments(first:1){ nodes{ databaseId author{login} path } } } }
# One unsigned commit anywhere on the branch shuts a required_signatures
# ruleset, and GitHub surfaces that only as mergeStateStatus BLOCKED —
# no red check, nothing in the rollup. Without this the tool can only
# say "investigate".
allCommits: commits(first:100){ nodes{ commit{ oid signature{ isValid } } } }
commits(last:1){ nodes{ commit{ oid statusCheckRollup{ state
contexts(first:100){ nodes{
__typename
Expand Down Expand Up @@ -170,6 +175,9 @@ evaluate() {
},
required_contexts: $required,
rules_fetched: ($ok == 1),
unsigned: [$p.allCommits.nodes[]?.commit
| select((.signature.isValid // false) | not)
| .oid[0:8]],
rulesets: $ruletypes,
reviews_on_head: ($head_reviews|map({(.author.login): .state})|add // {}),
has_review_on_head: (($head_reviews|length) > 0),
Expand Down Expand Up @@ -292,6 +300,20 @@ evaluate() {
{action:"triage-ci", why:"UNSTABLE: a non-required check is red; the gate stays shut until it is green or the PR is force-merged"}
elif $s.checks.pending > 0 then
{action:"wait", why:"\($s.checks.pending) check(s) still running (none of them required)"}
# Checked last, because it only matters once everything visible is
# green: an unsigned commit produces no red check and no rollup entry,
# so it surfaces purely as BLOCKED and used to end here as
# "investigate".
elif (($s.unsigned|length) > 0 and (($ruletypes | index("required_signatures")) != null)) then
{action:"fix-signatures",
why:("\($s.unsigned|length) commit(s) on this branch carry no valid signature — \($s.unsigned|join(", "))"
+ " — and the required_signatures ruleset is active. GitHub reports this"
+ " only as mergeStateStatus \($s.mergeState), never as a failing check"),
# No single quotes in here: the whole jq program lives in a
# single-quoted shell string and one would end it (shellcheck
# SC2026 catches it, but only after the parse has already gone
# wrong further down).
cmd:"git rebase --exec \"git commit --amend --no-edit -S\" $(git merge-base HEAD origin/\($s.base)) ; git push --force-with-lease"}
else
{action:"investigate", why:"mergeState=\($s.mergeState) with no failing check, no open thread and no missing review — check branch protection manually"}
end)
Expand Down
Loading