feat: Apply status:stale and status:stale-reviews labels automatically#49
Conversation
187e700 to
3dc45a6
Compare
|
Hi Federico, Many thanks for putting this together! The implementation is very clean, and the unit test coverage is thorough and well-structured. I went through the logic and compared it with our triage revamp design proposal. I have 2 suggestions:
Thanks again for the great work on this! |
Addressed 1. For 2., I think keeping each "status" as mutually exclusive makes more sense logically. Aligned to include status:stale-review in the DevOps triage query |
Add logic to the triage tool to identify PRs with 'status:blocked' label and apply 'status:stale' if they have been in that state for more than 21 days. This is implemented by: - Querying for 'status:blocked' PRs in bulk triage. - Checking the timeline events of these PRs to find when the label was applied. - Applying 'status:stale' if the duration exceeds the threshold. - Refactoring 'triage_logic.py' to support multiple rules. - Updating tests and README. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
…y for > 21 days Add logic to identify PRs with 'status:under-review' label and apply 'status:stale-review' if there has been no activity (comments or reviews) in the past 21 days since the label was applied. This is implemented by: - Querying for 'status:under-review' PRs. - Finding the label application time. - Collecting all activity (issue comments, review comments, reviews) after that time. - Calculating the duration since the latest activity. - Applying the 'status:stale-review' label if it exceeds 21 days. - Adding tests and documenting in README. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Update 'status:stale' (blocked) logic to also check for activity (comments or reviews) in the past 21 days, matching the 'status:stale-review' logic. Refactored both rules to use a shared helper `_is_eligible_for_stale_by_label` to reduce duplication. Updated tests and README.md. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Update `_apply_label` to identify and remove any existing `status:*` labels from the PR before applying a new status label. Added unit tests to verify that: - Existing status labels are removed when dry-run is False. - Existing status labels are NOT removed when dry-run is True. - Non-status labels are ignored. Updated README.md to document this behavior. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Add logic to identify PRs with `status:stale` label that have new activity (commits or comments) by the PR author since the label was applied. If author activity is detected, the tool restores the `status:blocked` label (which automatically removes `status:stale` due to mutual exclusivity). Updated `triage_all_outstanding` to query for `status:stale` PRs. Added unit tests for recovery scenarios. Updated README.md. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Update stale recovery logic to apply `status:under-review` instead of `status:blocked` when a `status:stale` PR has new author activity. Added a unit test to verify that `status:under-review` is applied and `status:stale` is removed. Updated README.md. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Add logic to identify PRs with `status:stale-review` label that have new activity (reviews or comments) by anyone other than the PR author since the label was applied. If reviewer activity is detected, the tool applies `status:under-review` (which automatically removes `status:stale-review` due to mutual exclusivity). Updated `triage_all_outstanding` to query for `status:stale-review` PRs. Added unit tests for stale-review recovery. Updated README.md. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Update `_is_eligible_for_stale_review_recovery` to ensure that the detecting reviewer activity (comments or reviews) comes from a member of the GitHub organization (or a collaborator if it is a personal repository). Added helper methods `_get_org` and `_is_member` to check membership, with caching. Updated unit tests to mock organization membership and added tests for non-members and personal repos. Updated README.md. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
…signed Update `_triage_needs_triage` to automatically apply `status:under-review` (and remove `status:needs-triage` due to mutual exclusivity) if the PR has 1 or more requested reviewers (users or teams) assigned. Also directly apply `status:under-review` to open, non-draft PRs with no labels if they already have reviewers assigned, skipping `status:needs-triage` entirely. Added unit tests to `TestTriageLabelerNeedsTriageTransitionRules` to cover: - PR with status:needs-triage and user reviewer -> status:under-review - PR with status:needs-triage and team reviewer -> status:under-review - PR with status:needs-triage and no reviewers -> remains unchanged - Eligible PR (no labels) with reviewers -> status:under-review - Eligible PR (no labels) with no reviewers -> status:needs-triage Updated README.md. TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
…ewers assigned" This reverts commit fe933ed.
Rename the constant `TARGET_LABEL` (which holds "status:needs-triage") to `NEEDS_TRIAGE_LABEL` to match the naming convention of other status labels (e.g., `BLOCKED_LABEL`, `STALE_LABEL`). TAG=agy CONV=971925a1-475e-4b95-bd29-a640b0506c53
Cache organization membership checks in TriageLabeler to reduce API calls. Use committer.date instead of author.date for commit activity detection.
Update BLOCKED_STALE_THRESHOLD_DAYS to 30 to match the design spec. Update unit tests and README accordingly.
Update README.md to document all 5 candidate PR categories queried during bulk triage and accurately describe the labels applied/removed in the core triage loop.
4b9165f to
4cddb33
Compare
c17f3b6
into
Universal-Commerce-Protocol:main
Description
Add logic to the triage tool to:
status:blockedlabel and applystatus:staleif they have been in that state with no activity (comments or reviews) for more than 30 days since the label was applied.status:under-reviewlabel and applystatus:stale-reviewif there has been no activity (comments or reviews) in the past 21 days since the label was applied.status:*labels: when a new status label is applied, any other existing status labels are automatically removed from the PR.status:staleand new activity (commits or comments) by the PR author is detected, the tool restoresstatus:under-review(which automatically removesstatus:staledue to mutual exclusivity).status:stale-reviewand new activity (reviews or comments) by a member of the GitHub organization (excluding the PR author) is detected, the tool restoresstatus:under-review(which automatically removesstatus:stale-reviewdue to mutual exclusivity).Both features share a common helper to calculate stale duration based on activity.
Also updated the
README.mdto reflect that any label acts as a skip label for thestatus:needs-triagelogic, as the tool now searches forno:labeland skips in-memory if the PR has any labels. Documented the new rules in README with simplified tables, mutual exclusivity details, and recovery rules.Category (Required)
ucp-schematool (resolver, linter, validator). (Requires Maintainer approval)Related Issues
None
Checklist
!for breaking changes).