Skip to content
39 changes: 36 additions & 3 deletions scripts/org_status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ collect_classify_prs() {
pageInfo{hasNextPage endCursor}
nodes{
number title createdAt isDraft
headRefName baseRefName
labels(first:20){nodes{name}}
reviewDecision
statusCheckRollup{state}
Expand Down Expand Up @@ -70,6 +71,8 @@ collect_classify_prs() {
title: .title,
opened: (.createdAt | split("T")[0]),
url: ("https://github.com/" + $owner + "/" + $repo + "/pull/" + (.number|tostring)),
headRefName: .headRefName,
baseRefName: .baseRefName,
labels: [.labels.nodes[].name],
isDraft: .isDraft,
ci: (.statusCheckRollup.state // null),
Expand Down Expand Up @@ -108,6 +111,34 @@ done
echo "Total open PRs: $(echo "$ALL_PRS" | jq 'length')" >&2
echo "::endgroup::" >&2

# ── Behind-Base Detection ─────────────────────────────────────────────────────
# For each PR, compute behind_by via the REST compare API. PRs with behind_by > 0
# need to be rebased/merged with their base branch before they can land.
# (GraphQL has no equivalent field; mergeable only reports CONFLICTING.)
echo "::group::Computing behind_by per PR" >&2
# Accumulate one augmented PR per line of NDJSON, then slurp into a single
# array at the end β€” avoids O(nΒ²) reparse of a growing array each iteration.
AUGMENTED_NDJSON=""
while IFS= read -r pr; do
[ -z "$pr" ] && continue
pr_repo=$(echo "$pr" | jq -r '.repo')
pr_head=$(echo "$pr" | jq -r '.headRefName')
pr_base=$(echo "$pr" | jq -r '.baseRefName')
if compare_response=$(gh api "repos/${pr_repo}/compare/${pr_base}...${pr_head}" --jq '.behind_by' 2>&1); then
behind="$compare_response"
else
echo " WARN: compare ${pr_repo} ${pr_base}...${pr_head} failed β€” treating as up to date: $compare_response" >&2
behind=0
fi
[[ "$behind" =~ ^[0-9]+$ ]] || behind=0
Comment thread
don-petry marked this conversation as resolved.
AUGMENTED_NDJSON+=$(echo "$pr" | jq -c --argjson b "$behind" '. + {behindBy: $b, needsRebase: ($b > 0)}')
AUGMENTED_NDJSON+=$'\n'
done <<< "$(echo "$ALL_PRS" | jq -c '.[]')"
ALL_PRS=$(echo "$AUGMENTED_NDJSON" | jq -cs '.')
NEEDS_REBASE_COUNT=$(echo "$ALL_PRS" | jq '[.[] | select(.needsRebase)] | length')
echo "PRs needing rebase: $NEEDS_REBASE_COUNT" >&2
echo "::endgroup::" >&2

# Pre-aggregate PR counts by category per repo (keeps prompt size manageable)
PR_BY_REPO=$(echo "$ALL_PRS" | jq '
sort_by(.repo) | group_by(.repo) | map({
Expand All @@ -120,7 +151,8 @@ PR_BY_REPO=$(echo "$ALL_PRS" | jq '
approved: ([.[] | select(.category=="Approved")] | length),
awaiting_review: ([.[] | select(.category=="Awaiting Review")] | length),
no_ci_policy: ([.[] | select(.category=="No CI / No Policy")] | length),
dep_bumps: ([.[] | select(.isDepBump)] | length)
dep_bumps: ([.[] | select(.isDepBump)] | length),
needs_rebase: ([.[] | select(.needsRebase)] | length)
}) | sort_by(-.total)')

NEEDS_REVIEW_PRS=$(echo "$ALL_PRS" | jq '[.[] | select(.needsHumanReview)]')
Expand Down Expand Up @@ -288,10 +320,11 @@ Org-wide blocker summary table (sum all repos). You MUST include the header row
Rows in this order: Awaiting Review, CI Failing, CI Pending, Changes Requested, Approved, Draft, No CI / No Policy, **TOTAL**

Per-repo breakdown table (omit repos with 0 total PRs). You MUST include the header row and separator row:
| Repo | Total | Awaiting Review | CI Failing | CI Pending | Changes Req | Approved | No CI/Policy | Draft |
|---|---|---|---|---|---|---|---|---|
| Repo | Total | Awaiting Review | CI Failing | CI Pending | Changes Req | Approved | No CI/Policy | Draft | Needs Rebase |
|---|---|---|---|---|---|---|---|---|---|
- Repo name as a link to the repo: [owner/repo](https://github.com/owner/repo)
- Add ⚠ next to repo name if CI Failing > 5 or Awaiting Review > 10
- Needs Rebase column: render the \`needs_rebase\` count from the data. If the count is 0 render β€”. If > 0 render the number followed by πŸ”„ (e.g. \`3 πŸ”„\`).

### \`## Open PRs β€” Needs Human Review\`
Full table for PRs with needsHumanReview == true:
Expand Down