chore(ci): close failing or conflicted PRs sooner

This commit is contained in:
jdx 2026-05-17 15:37:19 +00:00
parent 43db152e9b
commit dbf8712684
No known key found for this signature in database
GPG key ID: 584DADE86724B407

View file

@ -5,27 +5,50 @@ on:
- cron: "0 0 * * *" # daily at midnight
workflow_dispatch:
concurrency:
group: pr-closer
cancel-in-progress: true
jobs:
close-stale-prs:
runs-on: ubuntu-latest
permissions:
pull-requests: write
checks: read
statuses: read
steps:
- name: Close stale PRs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
gh pr list -R "${{ github.repository }}" --state open --json number,author,labels,updatedAt,statusCheckRollup --limit 100 | \
jq -r '.[] | select(
(.updatedAt | fromdateiso8601) < (now - 30*24*60*60) and
.author.login != "jdx" and
([.labels[].name] | index("keep-open") | not)
) | [.number, (if (.statusCheckRollup | length > 0) and (.statusCheckRollup | any(.conclusion == "FAILURE" or .conclusion == "failure")) then "failing" else "passing" end)] | @tsv' | \
while read -r pr status; do
echo "Closing PR #$pr (checks: $status)"
if [ "$status" = "failing" ]; then
gh pr close "$pr" -R "${{ github.repository }}" -c "This PR has been open for more than 30 days without activity. Note: CI checks were failing, which may be why it wasn't reviewed. Feel free to reopen or create a new PR if you'd like to continue working on this."
else
gh pr close "$pr" -R "${{ github.repository }}" -c "This PR has been open for more than 30 days without activity. Feel free to reopen or create a new PR if you'd like to continue working on this."
set -o pipefail
CUTOFF=$(date -u -d '6 days ago' +%Y-%m-%d)
gh pr list -R "$REPO" --state open --search "updated:<$CUTOFF -author:jdx -label:keep-open draft:false" --json number,mergeStateStatus,statusCheckRollup --limit 500 | \
jq -r '
def failed_check:
(.statusCheckRollup | length > 0) and
([.statusCheckRollup // [] | .[] | ((.conclusion // .state // "") | ascii_upcase)] | any(. == "FAILURE" or . == "ERROR" or . == "TIMED_OUT" or . == "ACTION_REQUIRED"));
.[]
| failed_check as $failed
| ([.statusCheckRollup // [] | .[] | ((.conclusion // .state // "") | ascii_upcase)] | any(. == "CANCELLED")) as $cancelled
| (.mergeStateStatus == "DIRTY") as $conflicted
| (.mergeStateStatus == "UNKNOWN") as $unknown
| if $failed and $conflicted then [.number, "failing checks and merge conflicts"]
elif $failed then [.number, "failing checks"]
elif $conflicted then [.number, "merge conflicts"]
elif $cancelled then [.number, "cancelled checks", "warn"]
elif $unknown then [.number, "unknown merge state", "warn"]
else empty
end
| @tsv
' | \
while IFS=$'\t' read -r pr reason action; do
if [ "$action" = "warn" ]; then
echo "Skipping PR #$pr ($reason)"
continue
fi
echo "Closing PR #$pr ($reason)"
gh pr close "$pr" -R "$REPO" -c "This PR has been inactive for at least 7 days and currently has $reason. Feel free to reopen or create a new PR if you'd like to continue working on this." || echo "Warning: failed to close PR #$pr, skipping"
done