Add PR Needs-Author-Feedback lifecycle workflow#48812
Conversation
Adds a GitHub Actions workflow that manages the Needs-Author-Feedback label lifecycle for pull requests: - New non-draft PRs automatically receive the Needs-Triage label - When author pushes commits or comments, Needs-Author-Feedback is removed and Needs-Triage is re-added - After 7 days of inactivity, PR is converted to draft with a warning - After 14 days of inactivity, PR is closed with a clear message This complements the existing fabricbot-based issue management in resourceManagement.yml by adding PR-specific behaviors (draft conversion) that require GitHub Actions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Actions workflow to automate the Needs-Author-Feedback label lifecycle for pull requests, including auto-triage labeling, automatic label swaps when the author responds, and scheduled stale handling (draft conversion + eventual close).
Changes:
- Introduces
.github/workflows/pr-needs-author-feedback.ymlto applyNeeds-Triageon new non-draft PRs. - Automatically removes
Needs-Author-Feedback(and re-addsNeeds-Triage) when the PR author pushes commits or comments. - Adds a scheduled stale check intended to convert inactive PRs to draft after 7 days and close them after 14 days (based on author activity).
…nation - Fix: close only after 14 days of author inactivity (not 7 days after draft conversion). The previous logic closed on the next 6h cycle after converting to draft. - Fix: filter commits by author login so maintainer pushes don't reset the inactivity timer. - Fix: use paginate() for both listComments and listCommits to handle PRs with >100 items. - Fix: only post the draft-conversion comment if the GraphQL mutation actually succeeded. - Bump actions/github-script from v7 to v9 for consistency with the rest of the repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add concurrency guard to prevent overlapping runs from racing on the same PR (consistent with auto-labeler.yml pattern). - Add pull_request_review trigger so author review submissions also remove the Needs-Author-Feedback label. - Include PR review comments (pulls.listReviewComments) in the scheduled inactivity check, not just issue comments. - Use the label-applied timestamp as inactivity baseline: timer starts from max(label_applied_date, last_author_activity), so labeling a long-stale PR gives the author a fresh 7-day window. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…wording, fallback
- Use stable concurrency group ('maintenance') for schedule/dispatch runs
so only one maintenance run is active at a time.
- Add open-state check for pull_request_review trigger to avoid mutating
labels on closed PRs.
- Bot warning detection now requires the comment timestamp >= label-applied
date, so label remove/re-apply cycles don't reuse stale warnings.
- Already-draft PRs get accurate wording ('This draft pull request has been
marked as requiring author feedback...') instead of falsely claiming
conversion.
- If GraphQL convertPullRequestToDraft fails and inactivity >= 14 days,
close the PR as a fallback instead of leaving it open indefinitely.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extends the workflow to handle 'Add single comment' on diffs (pull_request_review_comment events). Without this, inline review comments from the author were counted as activity by the scheduled job but did not remove the Needs-Author-Feedback label in real time. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous marker phrase spanned a line break in the join()'d comment body, so it never matched the conversion comment. Use the shorter 'requiring author feedback' which appears on a single line in both the auto-conversion comment and the already-draft warning comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Skip expensive API pagination for PRs labeled < 7 days ago (can never meet draft/close threshold) - Re-check that Needs-Author-Feedback label is still present before converting to draft or closing (guards against race with concurrent label removal) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
I may have been unclear. I don't mind that it's a GitHub action. My question was why not use the same process that FabricBot does for issues?
|
@michaeljolley This PR aims to achieve the third bullet point, and part of second bullet point to make existing needinfo workflow works for PRs as well: All other parts are handled by existing logic. Existing fabricbot policy has limitations in logics like checking whether it's draft, so I used GitHub Action to complete the workflow |
@michaeljolley created #49151 where I leverage existing fabricbot policy - meaning that we no longer can convert to draft but to close directly due to limitations. If you think that's more like the way to go, then I'll close this one |
|
Yeah. I vote close over draft for sure. |
…9151) ## Summary Adds fabricbot rules to manage the `Needs-Author-Feedback` label lifecycle for **pull requests**, complementing the existing issue management rules in `resourceManagement.yml`. This is a **simpler alternative** to the GitHub Actions workflow approach (PR #48812), trading advanced features (draft conversion, author-specific activity tracking) for zero-maintenance fabricbot automation. ## Behavior ### Flow diagram ``` ┌──────────────────────────────────────────────────────────────────────┐ │ Maintainer adds "Needs-Author-Feedback" label to a PR │ └──────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ 7 days, no activity │────►│ Add "Status-No recent activity" │ │ │ │ + post warning comment │ └─────────────────────────────────────┘ └──────────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ 7 more days (14 total), no activity│────►│ Close PR + post closing comment │ └─────────────────────────────────────┘ └──────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────────────┐ │ Author pushes commits OR comments on PR (at any point) │ └──────────────────────────────────────────────────────────────────────┘ │ ▼ Remove "Needs-Author-Feedback" → Add "Needs-Triage" Remove "Status-No recent activity" (if present) ``` ### Scheduled searches (every 6 hours) | Condition | Action | |-----------|--------| | PR + `Needs-Author-Feedback` + 7 days inactive + no `Status-No recent activity` | Add `Status-No recent activity` label + warning comment | | PR + `Needs-Author-Feedback` + `Status-No recent activity` + 7 more days inactive | Post closing comment + close PR | ### Event responders | Trigger | Action | |---------|--------| | Author comments on PR (`Issue_Comment` + `issueAuthor`) | Remove `Needs-Author-Feedback`, add `Needs-Triage` + `Needs-Team-Response` | | Author pushes commits (`Pull_Request` + `Synchronize` + `issueAuthor`) | Remove `Needs-Author-Feedback`, add `Needs-Triage` | | Any PR update activity | Remove `Status-No recent activity` | ### Bot messages **Warning (at 7 days):** > This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within 7 days of this comment**. To keep this PR active, please push your changes or leave a comment. **Closing (at 14 days):** > This pull request has been automatically closed because it has been marked as requiring author feedback but has not had any activity for **14 days**. If you would like to continue working on this, please reopen the PR and push your changes. ## Comparison with GitHub Actions workflow (PR #48812) | Feature | This PR (fabricbot) | PR #48812 (Actions) | |---------|-------------------|-------------------| | Convert to draft at 7 days | ❌ Not supported | ✅ Via GraphQL | | Close at 14 days | ✅ | ✅ | | Author-specific activity tracking | ❌ Any activity resets timer | ✅ Only author activity counts | | Bot comment resets timer |⚠️ Yes (fabricbot limitation) | ✅ No (filtered out) | | Maintenance burden | None (fabricbot managed) | Low (workflow file) | | Testing before merge | ❌ No local testing | ✅ `workflow_dispatch` + dry-run | | Review comment detection | ❌ Only issue comments | ✅ Reviews + inline comments | ## Trade-offs **Pros:** - Zero maintenance — fabricbot is a managed service - Consistent with existing issue management patterns in the same file - No workflow YAML to debug or maintain **Cons:** - No draft conversion (fabricbot cannot call GraphQL) - `noActivitySince` counts **all** activity — bot comments, maintainer comments, and label changes all reset the inactivity timer - Cannot distinguish author activity from other activity - No way to test locally or with dry-run before merge ## Relationship to existing automation Mirrors the existing issue rules (lines 11-43) which use the same pattern: - Issues: 5 days → warning, 5 more days → close - PRs (this change): 7 days → warning, 7 more days → close Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Adds a GitHub Actions workflow that manages the "Needs-Author-Feedback" label lifecycle for pull requests, complementing the existing fabricbot-based issue management.
This addresses the problem of community PRs going stale while pending author response — currently fabricbot handles stale issues but not PRs.
Behavior
Flow diagram
Jobs
author-responded-pushsynchronize)Needs-Author-Feedbackcheck-stale-prsworkflow_dispatchWhy not extend fabricbot (resourceManagement.yml)?
The existing fabricbot policy handles issues with
Needs-Author-Feedback(5d stale → 10d close) and already removes the label on author comments for both issues and PRs. However, fabricbot cannot:synchronize) events on PRsconvertPullRequestToDraft)isPullRequest(onlyisIssueexists)This workflow adds only what fabricbot can't do — avoiding duplication.
Inactivity detection
issues.listEventsto find when the label was most recently applied, handling label re-application cycles correctly.Edge cases handled
convertPullRequestToDraftmutation since REST API doesn't support this.created_at >= labelAppliedDateso prior cycle's warnings are ignored.'maintenance'group.workflow_dispatchtrigger withdry_runinput allows safe testing without making changes.Triggers summary
pull_request_target: [synchronize]schedule(every 6h)workflow_dispatchRelationship to existing automation
resourceManagement.yml(fabricbot)Needs-Author-Feedbackon author comment; stale close for issues onlyNo overlap — fabricbot handles comment-based label removal, this workflow handles push-based removal and the stale lifecycle.
Testing