-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathshare-reward.ts
More file actions
98 lines (79 loc) · 2.81 KB
/
share-reward.ts
File metadata and controls
98 lines (79 loc) · 2.81 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
import { components } from 'npm:@octokit/openapi-types';
import { $, argv, YAML } from 'npm:zx';
import { Reward } from './type.ts';
$.verbose = true;
const [
repositoryOwner,
repositoryName,
issueNumber,
payer, // GitHub username of the payer (provided by workflow, defaults to issue creator)
currency,
reward,
] = argv._;
interface PRMeta {
author: components['schemas']['simple-user'];
assignees: components['schemas']['simple-user'][];
}
const PR_URL = await $`gh api graphql -f query='{
repository(owner: "${repositoryOwner}", name: "${repositoryName}") {
issue(number: ${issueNumber}) {
closedByPullRequestsReferences(first: 10) {
nodes {
url
merged
}
}
}
}
}' --jq '.data.repository.issue.closedByPullRequestsReferences.nodes[] | select(.merged == true) | .url' | head -n 1`;
if (!PR_URL.text().trim())
throw new ReferenceError('No merged PR is found for the given issue number.');
const { author, assignees }: PRMeta = await (
await $`gh pr view ${PR_URL} --json author,assignees`
).json();
// Function to check if a user is a Copilot/bot user
function isCopilotUser(login: string): boolean {
const lowerLogin = login.toLowerCase();
return (
lowerLogin.includes('copilot') ||
lowerLogin.includes('[bot]') ||
lowerLogin === 'github-actions[bot]' ||
lowerLogin.endsWith('[bot]')
);
}
// Filter out Copilot and bot users from the list
const allUsers = [author.login, ...assignees.map(({ login }) => login)];
const users = allUsers.filter(login => !isCopilotUser(login));
console.log(`All users: ${allUsers.join(', ')}`);
console.log(`Filtered users (excluding bots/copilot): ${users.join(', ')}`);
// Handle case where all users are bots/copilot
if (users.length === 0) {
console.log('No real users found (all users are bots/copilot). Skipping reward distribution.');
console.log(`Filtered users: ${allUsers.join(', ')}`);
process.exit(0);
}
const rewardNumber = parseFloat(reward);
if (isNaN(rewardNumber) || rewardNumber <= 0)
throw new RangeError(
`Reward amount is not a valid number, can not proceed with reward distribution. Received reward value: ${reward}`,
);
const averageReward = (rewardNumber / users.length).toFixed(2);
const list: Reward[] = users.map(login => ({
issue: `#${issueNumber}`,
payer: `@${payer}`,
payee: `@${login}`,
currency,
reward: parseFloat(averageReward),
}));
const listText = YAML.stringify(list);
console.log(listText);
await $`git config --global user.name "github-actions[bot]"`;
await $`git config --global user.email "github-actions[bot]@users.noreply.github.com"`;
await $`git tag -a "reward-${issueNumber}" -m ${listText}`;
await $`git push origin --tags`;
const commentBody = `## Reward data
\`\`\`yml
${listText}
\`\`\`
`;
await $`gh issue comment ${issueNumber} --body ${commentBody}`;