-
Notifications
You must be signed in to change notification settings - Fork 200
84 lines (73 loc) · 3.5 KB
/
unassign-stale-issues.yml
File metadata and controls
84 lines (73 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
name: Unassign Issues with No PR After 7 Days
on:
schedule:
- cron: '0 2 * * *' # Runs daily at 2 AM UTC
workflow_dispatch: # Manual trigger support
jobs:
unassign-stale-issues:
runs-on: ubuntu-latest
steps:
- name: Check for stale assigned issues
uses: actions/github-script@v7
with:
github-token: ${{ secrets.PAT }}
script: |
const daysBeforeUnassign = 7;
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,
state: 'open',
assignee: '*'
});
for (const issue of issues) {
if (issue.pull_request) continue; // Skip PRs
// 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"] }
});
// Find the first assignment event date
const assignedEvent = timeline.filter(e => e.event === 'assigned').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
.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;
// 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;
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.`);
// Remove assignees
await github.rest.issues.removeAssignees({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
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 linked within ${daysBeforeUnassign} days of assignment. Please request reassignment if you are still working on it.`
});
}
}
}