Unverified Commit 35f87624 authored by Hong Minhee's avatar Hong Minhee
Browse files

Workflow to check stale assigned issues



This workflow runs daily and checks for issues that have been assigned
for over two weeks without any activity from the assignee. It will post
a reminder comment if:

- The issue has an assignee
- No comments from the assignee in the last 2 weeks
- No linked pull requests
- No recent bot reminders

The workflow can also be triggered manually for testing purposes.

[ci skip]

Co-Authored-By: default avatarClaude <noreply@anthropic.com>
parent e63c0422
Loading
Loading
Loading
Loading
+83 −0
Original line number Diff line number Diff line
name: Check stale assigned issues

on:
  schedule:
  - cron: '0 0 * * *'  # Run daily at midnight UTC
  workflow_dispatch:  # Allow manual trigger

permissions:
  issues: write

jobs:
  check-assignees:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/github-script@v7
      with:
        script: |
          const TWO_WEEKS = 14 * 24 * 60 * 60 * 1000;
          const now = Date.now();

          // Get all open issues
          const issues = await github.paginate(github.rest.issues.listForRepo, {
            owner: context.repo.owner,
            repo: context.repo.repo,
            state: 'open',
            per_page: 100
          });

          for (const issue of issues) {
            // Skip issues without assignees or pull requests
            if (!issue.assignees.length || issue.pull_request) continue;

            // Get comments
            const comments = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issue.number
            });

            // Find last comment by any assignee
            const lastAssigneeComment = comments.data
              .filter(c => issue.assignees.some(a => a.login === c.user.login))
              .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0];

            // Determine last activity time
            const issueCreatedAt = new Date(issue.created_at);
            const lastActivity = lastAssigneeComment
              ? new Date(lastAssigneeComment.created_at)
              : issueCreatedAt;

            // Check for linked pull requests
            const timelineEvents = await github.rest.issues.listEventsForTimeline({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issue.number
            });

            const hasLinkedPR = timelineEvents.data.some(
              e => e.event === 'cross-referenced' && e.source?.issue?.pull_request
            );

            // Check if issue is stale (no activity for over two weeks and no linked PR)
            if (!hasLinkedPR && now - lastActivity.getTime() > TWO_WEEKS) {
              // Check if we already posted a reminder recently
              const recentComments = comments.data.filter(
                c => c.user.type === 'Bot' &&
                     c.body.includes('has been assigned for over two weeks') &&
                     now - new Date(c.created_at).getTime() < TWO_WEEKS
              );

              // Only post if we haven't posted a reminder in the last two weeks
              if (recentComments.length === 0) {
                const assigneeLogins = issue.assignees.map(a => `@${a.login}`).join(' ');
                await github.rest.issues.createComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: issue.number,
                  body: `${assigneeLogins} This issue has been assigned for over two weeks without updates. Please provide a status update, or unassign yourself if you're unable to continue working on it.`
                });
                console.log(`Posted reminder for issue #${issue.number}`);
              }
            }
          }
+1 −0
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@
    "npm:sharp@~0.34.3": "0.34.4",
    "npm:shiki@^1.6.4": "1.29.2",
    "npm:structured-field-values@^2.0.4": "2.0.4",
    "npm:tsdown@0.12.9": "0.12.9_rolldown@1.0.0-beta.42",
    "npm:tsdown@~0.12.9": "0.12.9_rolldown@1.0.0-beta.42",
    "npm:tsx@^4.19.4": "4.20.6",
    "npm:uri-template-router@^0.0.17": "0.0.17",