Skip to content

Commit 4768f84

Browse files
author
Samuel Fialka
committed
feat(ci): add backlog management bot
1 parent 6d4886c commit 4768f84

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: 'Backlog Management Bot'
2+
on:
3+
schedule:
4+
- cron: '0 2 * * *' # Run daily at 2 AM UTC
5+
workflow_dispatch:
6+
pull_request:
7+
types: [opened, reopened, synchronize, labeled]
8+
9+
permissions:
10+
issues: write
11+
pull-requests: write
12+
13+
jobs:
14+
stale:
15+
name: 'Stale Issue Management'
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/stale@v9
19+
with:
20+
repo-token: ${{ github.token }}
21+
stale-issue-message: ''
22+
close-issue-message: |
23+
[TEST MODE] This issue has been automatically closed due to inactivity. If this issue is still relevant, please reopen it or create a new issue with updated information.
24+
days-before-issue-stale: 0
25+
days-before-issue-close: 0
26+
exempt-issue-labels: 'to-be-discussed'
27+
exempt-issue-assignees: true
28+
exempt-all-issue-assignees: true
29+
operations-per-run: 100
30+
assignee-reminder:
31+
name: 'Assignee Reminder Bot'
32+
runs-on: ubuntu-latest
33+
steps:
34+
- name: Send Reminders for Assigned Issues
35+
uses: actions/github-script@v7
36+
with:
37+
github-token: ${{ secrets.GITHUB_TOKEN }}
38+
script: |
39+
// Get all open issues that are assigned
40+
const { data: issues } = await github.rest.issues.listForRepo({
41+
owner: context.repo.owner,
42+
repo: context.repo.repo,
43+
state: 'open',
44+
per_page: 100
45+
});
46+
47+
const now = new Date();
48+
const reminderThreshold = 0; // days
49+
50+
for (const issue of issues) {
51+
if (!issue.assignees || issue.assignees.length === 0) continue;
52+
if (issue.pull_request) continue;
53+
// if (!issue.title.includes('[TEST]')) continue;
54+
55+
const labels = issue.labels.map(label => label.name);
56+
const exemptLabels = ['stale', 'to-be-discussed'];
57+
if (labels.some(label => exemptLabels.includes(label))) continue;
58+
59+
// Check last activity
60+
const lastUpdate = new Date(issue.updated_at);
61+
const daysSinceUpdate = Math.floor((now - lastUpdate) / (1000 * 60 * 60 * 24));
62+
63+
if (daysSinceUpdate >= reminderThreshold) {
64+
// Check if we've already sent a reminder recently
65+
const { data: comments } = await github.rest.issues.listComments({
66+
owner: context.repo.owner,
67+
repo: context.repo.repo,
68+
issue_number: issue.number,
69+
per_page: 10
70+
});
71+
72+
const recentBotComment = comments.find(comment =>
73+
comment.user.login === 'github-actions[bot]' &&
74+
comment.body.includes('⏰ Friendly Reminder') &&
75+
(now - new Date(comment.created_at)) < (7 * 24 * 60 * 60 * 1000) // 7 days
76+
);
77+
78+
if (!recentBotComment) {
79+
const assigneeNames = issue.assignees.map(assignee => `@${assignee.login}`).join(', ');
80+
// console.log(`[TEST] Would send reminder to: ${assigneeNames} for issue #${issue.number} (${issue.title})`);
81+
82+
await github.rest.issues.createComment({
83+
owner: context.repo.owner,
84+
repo: context.repo.repo,
85+
issue_number: issue.number,
86+
body:
87+
`## ⏰ Friendly Reminder
88+
89+
Hello ${assigneeNames}!
90+
This issue has been assigned to you and hasn't had any activity for ${daysSinceUpdate} days. Please provide a status update or progress comment
91+
92+
---
93+
*This is an automated reminder from the Backlog Management Bot.*`
94+
});
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)