Repository navigation
Expand file tree
/
Copy pathautoClaimHandle.js
More file actions
131 lines (118 loc) · 4.45 KB
/
Copy pathautoClaimHandle.js
File metadata and controls
131 lines (118 loc) · 4.45 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// will handle /claim
async function findExistingAssignments(
github,
owner,
repo,
username,
currentIssueNumber
) {
const { data: issues } = await github.rest.issues.listForRepo({
owner,
repo,
assignee: username,
state: "open",
per_page: 100,
});
return issues.filter(
(issue) => !issue.pull_request && issue.number !== currentIssueNumber
);
}
// change to increase/decrease the cap
const MAX_ASSIGNED_ISSUES = 25;
async function handleClaim({ github, context }) {
const { owner, repo } = context.repo;
const issueNumber = context.payload.issue.number;
const commenter = context.payload.comment.user.login;
// Fetch the latest issue state to prevent race conditions on closed issues
const { data: issue } = await github.rest.issues.get({
owner,
repo,
issue_number: issueNumber,
});
if (issue.state === "closed") {
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: `🔒 **Oops!** This issue is closed. Commands can only be used on open issues.`,
});
return;
}
// Check if a Pull Request for this issue has already been merged
try {
const searchMergedPRs = await github.rest.search.issuesAndPullRequests({
q: `repo:${owner}/${repo} type:pr is:merged "${issueNumber}"`,
});
if (searchMergedPRs.data.total_count > 0) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: `🔒 **Claim Blocked!** A Pull Request resolving this issue has already been merged, so this issue is now locked for new claims. Only existing assignees can complete their active work. Please search for other open issues! 🔍`,
});
return;
}
} catch (err) {
console.log(`Failed to check merged PRs: ${err.message}`);
}
const currentAssignees = issue.assignees.map((a) =>
a.login.toLowerCase()
);
if (currentAssignees.includes(commenter.toLowerCase())) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: `✅ **You're all set!** You are already assigned to this issue, @${commenter}.`,
});
return;
}
// ── 1-hour cooldown: protects the issue opener's exclusive right for the first hour ──
const issueCreatedAt = new Date(issue.created_at);
const elapsedMs = Date.now() - issueCreatedAt.getTime();
const elapsedMinutes = elapsedMs / (1000 * 60);
if (elapsedMinutes < 60 && commenter.toLowerCase() !== issue.user.login.toLowerCase()) {
const minutesLeft = Math.ceil(60 - elapsedMinutes);
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: `⏳ **Cooldown Active!** This issue was created less than 1 hour ago (${Math.floor(elapsedMinutes)} minutes ago).\n\nTo give the issue opener (@${issue.user.login}) a fair chance to make progress, there is a **1-hour cooldown** before anyone else can claim this issue. Please try again in **${minutesLeft} minute(s)** or look for other open issues! 🔍`,
});
return;
}
const existingIssues = await findExistingAssignments(
github,
owner,
repo,
commenter,
issueNumber
);
if (existingIssues.length >= MAX_ASSIGNED_ISSUES) {
const issueList = existingIssues
.map((i) => `> 📋 [#${i.number} — ${i.title}](${i.html_url})`)
.join("\n");
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: `⚠️ **Limit reached, @${commenter}!** You already have **${existingIssues.length}/${MAX_ASSIGNED_ISSUES}** active assigned issues.\n\nPlease complete or \`/unclaim\` your current issue before claiming a new one:\n\n${issueList}`,
});
return;
}
await github.rest.issues.addAssignees({
owner,
repo,
issue_number: issueNumber,
assignees: [commenter],
});
// comment message
const contributingUrl = `https://github.com/${owner}/${repo}/blob/main/CONTRIBUTING.md`;
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: `🎉 **Assigned!** Welcome aboard, @${commenter}! 🌟\n\n⏳ **Timeframe:** You have **24 hours** of exclusive time to complete the issue and make a Pull Request. Please submit a PR before claiming any other issue.\n\n> 💡 **Tip:** Be sure to check out our [CONTRIBUTING.md](${contributingUrl}) to get off to a great start.\n\nHappy coding! 🚀✨`,
});
}
module.exports = { handleClaim };