1515 github-token : ${{ secrets.PAT }}
1616 script : |
1717 const daysBeforeUnassign = 7;
18- const cutoffDate = new Date();
19- cutoffDate.setDate(cutoffDate.getDate() - daysBeforeUnassign);
18+ const now = new Date();
2019
20+ // Get all open issues with assignees
2121 const issues = await github.paginate(github.rest.issues.listForRepo, {
2222 owner: context.repo.owner,
2323 repo: context.repo.repo,
@@ -28,36 +28,56 @@ jobs:
2828 for (const issue of issues) {
2929 if (issue.pull_request) continue; // Skip PRs
3030
31- const createdAt = new Date(issue.created_at);
32- const assigned = issue.assignees.length > 0;
31+ // Get timeline events to find assignment and PR link events
32+ const timeline = await github.paginate(github.rest.issues.listEventsForTimeline, {
33+ owner: context.repo.owner,
34+ repo: context.repo.repo,
35+ issue_number: issue.number,
36+ mediaType: { previews: ["mockingbird"] }
37+ });
3338
34- if (assigned && createdAt < cutoffDate) {
35- // Check if there's a linked PR via timeline
36- const timeline = await github.paginate(github.rest.issues.listEventsForTimeline, {
37- owner: context.repo.owner,
38- repo: context.repo.repo,
39- issue_number: issue.number,
40- mediaType: {
41- previews: ["mockingbird"]
42- }
43- });
39+ // Find the first assignment event date
40+ const assignedEvent = timeline.filter(e => e.event === 'assigned').at(-1);// latest
41+ if (!assignedEvent) {
42+ // No assignment event found, skip issue
43+ continue;
44+ }
45+ const assignedAt = new Date(assignedEvent.created_at);
46+ // Find the first PR linked event date
47+ const prLinkedEvent = timeline
48+ .filter(
49+ e =>
50+ ['connected', 'cross-referenced'].includes(e.event) &&
51+ new Date(e.created_at) >= assignedAt
52+ )
53+ .at(0); // earliest link *after* assignment
54+ const prLinkedAt = prLinkedEvent ? new Date(prLinkedEvent.created_at) : null;
55+
56+ // Calculate days since assignment
57+ const daysSinceAssignment = (now - assignedAt) / (1000 * 60 * 60 * 24);
58+
59+ // Check if issue is still assigned (in case assignees changed later)
60+ const currentlyAssigned = issue.assignees.length > 0;
4461
45- const hasLinkedPR = timeline.some(event => event.event === 'connected');
62+ if (currentlyAssigned && daysSinceAssignment >= daysBeforeUnassign) {
63+ // If PR not linked or linked after 7 days
64+ if (!prLinkedAt || prLinkedAt > new Date(assignedAt.getTime() + daysBeforeUnassign * 24 * 60 * 60 * 1000)) {
65+ console.log(`Unassigning issue #${issue.number} - no PR linked within ${daysBeforeUnassign} days of assignment.`);
4666
47- if (!hasLinkedPR) {
48- console.log(`Unassigning issue #${issue.number} (no PR in 7 days)`);
67+ // Remove assignees
4968 await github.rest.issues.removeAssignees({
5069 owner: context.repo.owner,
5170 repo: context.repo.repo,
5271 issue_number: issue.number,
5372 assignees: issue.assignees.map(user => user.login)
5473 });
5574
75+ // Post comment
5676 await github.rest.issues.createComment({
5777 owner: context.repo.owner,
5878 repo: context.repo.repo,
5979 issue_number: issue.number,
60- 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.`
80+ 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.`
6181 });
6282 }
6383 }
0 commit comments