From 60a5834b3181bc0cc2a24182a33a54011e48fa0e Mon Sep 17 00:00:00 2001 From: Mehul Prajapati Date: Mon, 28 Jul 2025 06:17:00 -0400 Subject: [PATCH 1/5] Update unassign-stale-issues.yml --- .github/workflows/unassign-stale-issues.yml | 51 +++++++++++++-------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/.github/workflows/unassign-stale-issues.yml b/.github/workflows/unassign-stale-issues.yml index c10e650..d3cb83c 100644 --- a/.github/workflows/unassign-stale-issues.yml +++ b/.github/workflows/unassign-stale-issues.yml @@ -15,9 +15,9 @@ jobs: github-token: ${{ secrets.PAT }} script: | const daysBeforeUnassign = 7; - const cutoffDate = new Date(); - cutoffDate.setDate(cutoffDate.getDate() - daysBeforeUnassign); + const now = new Date(); + // Get all open issues with assignees const issues = await github.paginate(github.rest.issues.listForRepo, { owner: context.repo.owner, repo: context.repo.repo, @@ -28,24 +28,38 @@ jobs: for (const issue of issues) { if (issue.pull_request) continue; // Skip PRs - const createdAt = new Date(issue.created_at); - const assigned = issue.assignees.length > 0; + // Get timeline events to find assignment and PR link events + const timeline = await github.paginate(github.rest.issues.listEventsForTimeline, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + mediaType: { previews: ["mockingbird"] } + }); - if (assigned && createdAt < cutoffDate) { - // Check if there's a linked PR via timeline - const timeline = await github.paginate(github.rest.issues.listEventsForTimeline, { - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue.number, - mediaType: { - previews: ["mockingbird"] - } - }); + // Find the first assignment event date + const assignedEvent = timeline.find(event => event.event === 'assigned'); + if (!assignedEvent) { + // No assignment event found, skip issue + continue; + } + const assignedAt = new Date(assignedEvent.created_at); + + // Find the first PR linked event date + const prLinkedEvent = timeline.find(event => event.event === 'connected'); + const prLinkedAt = prLinkedEvent ? new Date(prLinkedEvent.created_at) : null; + + // Calculate days since assignment + const daysSinceAssignment = (now - assignedAt) / (1000 * 60 * 60 * 24); + + // Check if issue is still assigned (in case assignees changed later) + const currentlyAssigned = issue.assignees.length > 0; - const hasLinkedPR = timeline.some(event => event.event === 'connected'); + if (currentlyAssigned && daysSinceAssignment >= daysBeforeUnassign) { + // If PR not linked or linked after 7 days + if (!prLinkedAt || prLinkedAt > new Date(assignedAt.getTime() + daysBeforeUnassign * 24 * 60 * 60 * 1000)) { + console.log(`Unassigning issue #${issue.number} - no PR linked within ${daysBeforeUnassign} days of assignment.`); - if (!hasLinkedPR) { - console.log(`Unassigning issue #${issue.number} (no PR in 7 days)`); + // Remove assignees await github.rest.issues.removeAssignees({ owner: context.repo.owner, repo: context.repo.repo, @@ -53,11 +67,12 @@ jobs: assignees: issue.assignees.map(user => user.login) }); + // Post comment await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, - body: `⏰ This issue was automatically unassigned because no pull request was raised within 5 days. Feel free to ask for re-assignment if you're still working on it.` + body: `⏰ This issue was automatically unassigned because no pull request was linked within ${daysBeforeUnassign} days of assignment. Please request reassignment if you are still working on it.` }); } } From fde882249fc471924f3c9a732ae44050aa65052f Mon Sep 17 00:00:00 2001 From: Mehul Prajapati Date: Mon, 28 Jul 2025 06:30:05 -0400 Subject: [PATCH 2/5] Update .github/workflows/unassign-stale-issues.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .github/workflows/unassign-stale-issues.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unassign-stale-issues.yml b/.github/workflows/unassign-stale-issues.yml index d3cb83c..6849784 100644 --- a/.github/workflows/unassign-stale-issues.yml +++ b/.github/workflows/unassign-stale-issues.yml @@ -38,12 +38,13 @@ jobs: // Find the first assignment event date const assignedEvent = timeline.find(event => event.event === 'assigned'); + const assignedEvents = timeline.filter(e => e.event === 'assigned'); + const assignedEvent = assignedEvents.at(-1); // latest if (!assignedEvent) { // No assignment event found, skip issue continue; } const assignedAt = new Date(assignedEvent.created_at); - // Find the first PR linked event date const prLinkedEvent = timeline.find(event => event.event === 'connected'); const prLinkedAt = prLinkedEvent ? new Date(prLinkedEvent.created_at) : null; From 656eb85d417f39af731fd83db81c6188ecf63f2b Mon Sep 17 00:00:00 2001 From: Mehul Prajapati Date: Mon, 28 Jul 2025 06:32:35 -0400 Subject: [PATCH 3/5] Update unassign-stale-issues.yml --- .github/workflows/unassign-stale-issues.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/unassign-stale-issues.yml b/.github/workflows/unassign-stale-issues.yml index 6849784..af93f3f 100644 --- a/.github/workflows/unassign-stale-issues.yml +++ b/.github/workflows/unassign-stale-issues.yml @@ -37,9 +37,7 @@ jobs: }); // Find the first assignment event date - const assignedEvent = timeline.find(event => event.event === 'assigned'); - const assignedEvents = timeline.filter(e => e.event === 'assigned'); - const assignedEvent = assignedEvents.at(-1); // latest + const assignedEvent = timeline.filter(e => e.event === 'assigned').at(-1);// latest if (!assignedEvent) { // No assignment event found, skip issue continue; From 301229f3683a0ffcb62d65395129f602c4c78ee7 Mon Sep 17 00:00:00 2001 From: Mehul Prajapati Date: Mon, 28 Jul 2025 07:45:52 -0400 Subject: [PATCH 4/5] Update suggestion Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .github/workflows/unassign-stale-issues.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unassign-stale-issues.yml b/.github/workflows/unassign-stale-issues.yml index af93f3f..13c61a7 100644 --- a/.github/workflows/unassign-stale-issues.yml +++ b/.github/workflows/unassign-stale-issues.yml @@ -44,7 +44,9 @@ jobs: } const assignedAt = new Date(assignedEvent.created_at); // Find the first PR linked event date - const prLinkedEvent = timeline.find(event => event.event === 'connected'); + const prLinkedEvent = timeline + .filter(e => e.event === 'connected' && new Date(e.created_at) >= assignedAt) + .at(0); // earliest link *after* assignment const prLinkedAt = prLinkedEvent ? new Date(prLinkedEvent.created_at) : null; // Calculate days since assignment From 6ca7542ff6dab4fc6b898cda9dd945d723aa2a3b Mon Sep 17 00:00:00 2001 From: Mehul Prajapati Date: Mon, 28 Jul 2025 09:10:54 -0400 Subject: [PATCH 5/5] Update .github/workflows/unassign-stale-issues.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .github/workflows/unassign-stale-issues.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unassign-stale-issues.yml b/.github/workflows/unassign-stale-issues.yml index 13c61a7..78e4544 100644 --- a/.github/workflows/unassign-stale-issues.yml +++ b/.github/workflows/unassign-stale-issues.yml @@ -45,7 +45,11 @@ jobs: const assignedAt = new Date(assignedEvent.created_at); // Find the first PR linked event date const prLinkedEvent = timeline - .filter(e => e.event === 'connected' && new Date(e.created_at) >= assignedAt) + .filter( + e => + ['connected', 'cross-referenced'].includes(e.event) && + new Date(e.created_at) >= assignedAt + ) .at(0); // earliest link *after* assignment const prLinkedAt = prLinkedEvent ? new Date(prLinkedEvent.created_at) : null;