|
| 1 | +import os |
| 2 | +import datetime |
| 3 | +from github import Github |
| 4 | + |
| 5 | +REPO_NAME = "pytorch/executorch" |
| 6 | +LABEL = "need-user-input" |
| 7 | +REMINDER_MARKER = "<!-- executorch-auto-reminder -->" |
| 8 | +REMINDER_COMMENT = ( |
| 9 | + f"{REMINDER_MARKER}\nHi @{0}, this issue/PR has been marked as 'need-user-input'. " |
| 10 | + "Please respond or provide input. If we don't hear back in 30 days, this will be closed." |
| 11 | +) |
| 12 | +CLOSE_COMMENT = ( |
| 13 | + f"{REMINDER_MARKER}\nClosing due to no response after 30 days. " |
| 14 | + "If you still need help, feel free to re-open or comment again!" |
| 15 | +) |
| 16 | +DAYS_BEFORE_REMINDER = 30 |
| 17 | +DAYS_BEFORE_CLOSE = 30 |
| 18 | + |
| 19 | +def main(): |
| 20 | + g = Github(os.environ['GH_TOKEN']) |
| 21 | + repo = g.get_repo(REPO_NAME) |
| 22 | + |
| 23 | + issues = repo.get_issues(state='open', labels=[LABEL]) |
| 24 | + now = datetime.datetime.utcnow() |
| 25 | + |
| 26 | + for issue in issues: |
| 27 | + comments = list(issue.get_comments()) |
| 28 | + last_comment = comments[-1] if comments else None |
| 29 | + |
| 30 | + # Find automation comments |
| 31 | + auto_comments = [c for c in comments if REMINDER_MARKER in c.body] |
| 32 | + user_comments = [c for c in comments if REMINDER_MARKER not in c.body] |
| 33 | + |
| 34 | + # Case 1: No automation comment yet, and last comment > 30 days ago |
| 35 | + if not auto_comments: |
| 36 | + if last_comment and (now - last_comment.created_at).days >= DAYS_BEFORE_REMINDER: |
| 37 | + # Tag the issue author or PR author |
| 38 | + user = issue.user.login |
| 39 | + issue.create_comment(REMINDER_COMMENT.format(user)) |
| 40 | + print(f"Reminded {user} on issue/PR #{issue.number}") |
| 41 | + |
| 42 | + # Case 2: Automation comment exists, but no user response after 30 more days |
| 43 | + elif auto_comments: |
| 44 | + last_auto = auto_comments[-1] |
| 45 | + # Any user response after automation? |
| 46 | + user_responded = any( |
| 47 | + c.created_at > last_auto.created_at and c.user.login == issue.user.login |
| 48 | + for c in user_comments |
| 49 | + ) |
| 50 | + |
| 51 | + if not user_responded: |
| 52 | + if (now - last_auto.created_at).days >= DAYS_BEFORE_CLOSE: |
| 53 | + issue.create_comment(CLOSE_COMMENT) |
| 54 | + issue.edit(state="closed") |
| 55 | + print(f"Closed issue/PR #{issue.number} due to inactivity.") |
| 56 | + |
| 57 | + else: |
| 58 | + # Remove label if user responded |
| 59 | + labels = [l.name for l in issue.labels if l.name != LABEL] |
| 60 | + issue.set_labels(*labels) |
| 61 | + print(f"Removed label from issue/PR #{issue.number} after user response.") |
| 62 | + |
| 63 | +if __name__ == "__main__": |
| 64 | + main() |
0 commit comments