Skip to content

Stale PR closure workflow/script - #9883

Merged
Jose Alvarez (jpalvarezl) merged 12 commits into
microsoft:mainfrom
jpalvarezl:jpalvarezl/feature/stale_pr_closure
Nov 3, 2026
Merged

Jose Alvarez (jpalvarezl) merged 12 commits into
microsoft:mainfrom
jpalvarezl:jpalvarezl/feature/stale_pr_closure

Conversation

@jpalvarezl

Copy link
Copy Markdown
Member

Motivation & Context

The existing stale automation only checks pull requests carrying a manually applied label, sends a single reminder, and does not close inactive pull requests. In practice, the required label is not being applied, so the scheduled workflow scans no candidates.

This change provides a deterministic, PR-only process for warning external contributors and closing pull requests that remain inactive after a maintainer response. It intentionally avoids AI-based classification and includes maintainer-controlled exemptions and dry-run support.

Description & Review Guide

  • What are the major changes?
    • Renames the stale automation to stale_pr_ping and restricts it to open pull requests.
    • Loads maintainers from the Python and .NET rules in CODEOWNERS on the repository's default branch.
    • Warns an external PR author after the configured inactivity period when the latest conversation comment is from a CODEOWNER, then applies requested-info.
    • Closes the PR after another configured inactivity period.
    • Exempts CODEOWNER-authored PRs and PRs carrying the maintainer-controlled dont-close label.
    • Preserves DAYS_THRESHOLD as a shared configuration override for the warning and closing periods.
    • Supports dry-run execution through the manual workflow input.
    • Adds focused coverage for classification, thresholds, dry-run behavior, retries, warning, closure, and exemptions. python -m pytest .github\tests\test_stale_pr_ping.py -q passes with 40 tests.
  • What is the impact of these changes?
    • Scheduled runs process qualifying PRs daily; manual runs can use dry-run mode to preview warnings and closures.
    • When run live, qualifying PRs receive a fixed warning and requested-info; continued inactivity then results in a fixed closing comment and closure.
    • New commits, comments, reviews, or other PR updates reset the relevant inactivity period through GitHub's updated_at timestamp.
  • What do you want reviewers to focus on?
    • The CODEOWNERS-based maintainer classification, the use of the latest conversation comment to establish that the contributor owns the next response, and the safety boundaries around dry-run mode and dont-close.

Related Issue

N/A - repository automation. Updates .github/workflows/stale-pr-ping.yml.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: GitHub Copilot assisted with the design discussion, implementation, tests, and PR description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and the title prefix in sync automatically.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The script can close previously labeled PRs without issuing the new closure warning or allowing its required grace period.

3 open issues
What changed in this PR

Replaces label-triggered issue and PR reminders with a deterministic lifecycle for warning and closing inactive external pull requests.

Changes:

  • Uses default-branch CODEOWNERS for maintainer classification, with exemptions for maintainer-authored and dont-close PRs.
  • Adds warning and closure stages with configurable inactivity thresholds, retries, and dry-run support.
  • Replaces the previous tests with coverage for lifecycle eligibility, actions, exemptions, and failures.
File Description
.github/​workflows/​stale-pr-ping.yml Runs the new PR lifecycle script and updates input descriptions.
.github/​tests/​test_stale_pr_ping.py Adds tests for the new lifecycle and configuration.
.github/​tests/​test_stale_issue_pr_ping.py Removes tests for the previous reminder process.
.github/​scripts/​stale_pr_ping.py Implements maintainer classification, warnings, and automatic closure.
.github/​scripts/​stale_issue_pr_ping.py Removes the label-triggered issue and PR reminder script.

Review effort: Balanced

Comment thread .github/scripts/stale_pr_ping.py Resolved
Comment thread .github/scripts/stale_pr_ping.py Resolved
Comment thread .github/scripts/stale_pr_ping.py Resolved

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (7 commit(s)): ab71f8c24907, b15a77a06b12, 7c2e255cf245, cdae2eb18610, 22eff9b7dffe, bf4054c40115, 25249828df46
Model: gpt-5.6-sol

Overview

The PR replaces the label-gated issue/PR reminder with an open-PR-only two-stage lifecycle and adds useful safeguards: CODEOWNER and dont-close exemptions, dry-run support, comment-before-mutation ordering, retries, and focused tests. Four lifecycle gaps remain: the shared label can close previously labeled PRs without the new warning, contributor activity does not cancel the closing state, a partial warning cannot recover across runs, and unbounded comment enumeration lets hostile PRs repeatedly consume shared automation resources.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
4 verified findings remained after source verification (4 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: .github/scripts/stale_pr_ping.py

Comment thread .github/scripts/stale_pr_ping.py Resolved
Comment thread .github/scripts/stale_pr_ping.py Resolved
Comment thread .github/scripts/stale_pr_ping.py Resolved
Comment thread .github/scripts/stale_pr_ping.py Resolved
@jpalvarezl
Jose Alvarez (jpalvarezl) added this pull request to the merge queue Nov 3, 2026
Merged via the queue into microsoft:main with commit 7998d7c Nov 3, 2026
29 checks passed

This branch was previously deployed

1 inactive deployment
github-app-auth — 5533282b Deployed Nov 3, 2026 by jpalvarezl via add_label #26943
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants