Skip to content

Commit e57dbfc

Browse files
committed
Fixes for Slack notifications and automated replies
Fixes #30 Fixes #31 Co-authored-by: [email protected]
1 parent 3d98ccb commit e57dbfc

File tree

5 files changed

+148
-8
lines changed

5 files changed

+148
-8
lines changed

.github/workflows/contributor-issue-comment.yml

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,26 @@ on:
1818

1919

2020
jobs:
21+
check-if-close-contributor:
22+
name: Check if user is a close contributor
23+
uses: learningequality/.github/.github/workflows/is-close-contributor.yml@main
24+
secrets:
25+
LE_BOT_APP_ID: ${{ secrets.LE_BOT_APP_ID }}
26+
LE_BOT_PRIVATE_KEY: ${{ secrets.LE_BOT_PRIVATE_KEY }}
27+
with:
28+
username: ${{ github.event.comment.user.login }}
29+
30+
2131
process-issue-comment:
2232
name: Process issue comment
23-
33+
needs: [check-if-close-contributor]
2434
if: >-
2535
${{
2636
!github.event.issue.pull_request &&
27-
github.event.comment.author_association != 'MEMBER' &&
2837
github.event.comment.author_association != 'OWNER' &&
2938
github.event.comment.user.login != 'sentry-io[bot]' &&
30-
github.event.comment.user.login != 'learning-equality-bot[bot]'
39+
github.event.comment.user.login != 'learning-equality-bot[bot]' &&
40+
(github.event.comment.author_association != 'MEMBER' || needs.check-if-close-contributor.outputs.is_close_contributor == 'true')
3141
}}
3242
3343
runs-on: ubuntu-latest
@@ -52,11 +62,11 @@ jobs:
5262
node-version: '20'
5363

5464
- name: Install dependencies
55-
run: npm install
65+
run: yarn install --frozen-lockfile
5666

5767
- name: Run script
5868
id: script
59-
uses: actions/github-script@v7
69+
uses: actions/github-script@v7
6070
with:
6171
github-token: ${{ steps.generate-token.outputs.token }}
6272
script: |
@@ -65,6 +75,7 @@ jobs:
6575
env:
6676
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
6777
SLACK_COMMUNITY_NOTIFICATIONS_WEBHOOK_URL: ${{ secrets.SLACK_COMMUNITY_NOTIFICATIONS_WEBHOOK_URL }}
78+
IS_CLOSE_CONTRIBUTOR: ${{ needs.check-if-close-contributor.outputs.is_close_contributor }}
6879

6980
- name: Send Slack notification about GitHub comment
7081
uses: slackapi/[email protected]
@@ -87,3 +98,13 @@ jobs:
8798
"text": "${{ steps.script.outputs.slack_notification_bot_comment }}"
8899
}
89100
101+
- name: Send Slack notification about skipped GitHub bot reply
102+
if: ${{ steps.script.outputs.bot_reply_skipped }}
103+
uses: slackapi/[email protected]
104+
with:
105+
webhook-type: incoming-webhook
106+
webhook: ${{ steps.script.outputs.webhook_url }}
107+
payload: >
108+
{
109+
"text": "${{ steps.script.outputs.slack_notification_bot_skipped }}"
110+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Check if user is a close contributor
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
username:
7+
description: 'Github username'
8+
required: true
9+
type: string
10+
secrets:
11+
LE_BOT_APP_ID:
12+
required: true
13+
LE_BOT_PRIVATE_KEY:
14+
required: true
15+
outputs:
16+
is_close_contributor:
17+
description: "True if the user is a close contributor, otherwise false"
18+
value: ${{ jobs.check-contributor.outputs.is_close_contributor }}
19+
20+
jobs:
21+
check-contributor:
22+
name: Run check
23+
runs-on: ubuntu-latest
24+
outputs:
25+
is_close_contributor: ${{ steps.check-script.outputs.is_close_contributor }}
26+
steps:
27+
- name: Generate App Token
28+
id: generate-token
29+
uses: tibdex/github-app-token@v2
30+
with:
31+
app_id: ${{ secrets.LE_BOT_APP_ID }}
32+
private_key: ${{ secrets.LE_BOT_PRIVATE_KEY }}
33+
34+
- name: Checkout .github repository
35+
uses: actions/checkout@v4
36+
with:
37+
repository: learningequality/.github
38+
ref: main
39+
40+
- name: Setup Node.js
41+
uses: actions/setup-node@v4
42+
with:
43+
node-version: '20'
44+
45+
- name: Install dependencies
46+
run: yarn install --frozen-lockfile
47+
48+
- name: Run script
49+
id: check-script
50+
uses: actions/github-script@v7
51+
env:
52+
USERNAME: ${{ inputs.username }}
53+
with:
54+
github-token: ${{ steps.generate-token.outputs.token }}
55+
script: |
56+
const script = require('./scripts/is-close-contributor.js');
57+
return await script({core, github, context });

scripts/constants.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ const LE_BOT_USERNAME = 'learning-equality-bot[bot]';
33
// close contributors are treated a bit special in some workflows,
44
// for example, we receive a high priority notification about their
55
// comments on all issues rather than just on 'help wanted' issues
6-
const CLOSE_CONTRIBUTORS = ['BabyElias', 'Dimi20cen', 'EshaanAgg', 'GarvitSinghal47', 'habibayman', 'iamshobhraj', 'indirectlylit', 'Jakoma02', 'KshitijThareja', 'muditchoudhary', 'nathanaelg16', 'nikkuAg', 'Sahil-Sinha-11', 'shivam-daksh', 'shruti862', 'thesujai', 'WinnyChang'];
6+
const CLOSE_CONTRIBUTORS = ['AadarshM07', 'BabyElias', 'Dimi20cen', 'EshaanAgg', 'GarvitSinghal47', 'habibayman', 'iamshobhraj', 'indirectlylit', 'Jakoma02', 'KshitijThareja', 'muditchoudhary', 'nathanaelg16', 'nikkuAg', 'Sahil-Sinha-11', 'shivam-daksh', 'shruti862', 'thesujai', 'WinnyChang', 'yeshwanth235'];
7+
8+
const TEAMS_WITH_CLOSE_CONTRIBUTORS = ['gsoc-contributors', 'learning-equality-community-guide'];
79

810
const KEYWORDS_DETECT_ASSIGNMENT_REQUEST = [
911
'assign', 'assigned',
@@ -39,4 +41,5 @@ module.exports = {
3941
KEYWORDS_DETECT_ASSIGNMENT_REQUEST,
4042
ISSUE_LABEL_HELP_WANTED,
4143
BOT_MESSAGE_ISSUE_NOT_OPEN,
44+
TEAMS_WITH_CLOSE_CONTRIBUTORS,
4245
};

scripts/contributor-issue-comment.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const {
22
LE_BOT_USERNAME,
3-
CLOSE_CONTRIBUTORS,
43
KEYWORDS_DETECT_ASSIGNMENT_REQUEST,
54
ISSUE_LABEL_HELP_WANTED,
65
BOT_MESSAGE_ISSUE_NOT_OPEN
@@ -21,6 +20,7 @@ module.exports = async ({ github, context, core }) => {
2120
const owner = context.repo.owner;
2221
const supportDevSlackWebhookUrl = process.env.SLACK_WEBHOOK_URL;
2322
const supportDevNotificationsSlackWebhookUrl = process.env.SLACK_COMMUNITY_NOTIFICATIONS_WEBHOOK_URL;
23+
const isCloseContributor = process.env.IS_CLOSE_CONTRIBUTOR === 'true';
2424
const keywordRegexes = KEYWORDS_DETECT_ASSIGNMENT_REQUEST
2525
.map(k => k.trim().toLowerCase())
2626
.filter(Boolean)
@@ -81,7 +81,7 @@ module.exports = async ({ github, context, core }) => {
8181
}
8282

8383

84-
if (await hasLabel(ISSUE_LABEL_HELP_WANTED) || CLOSE_CONTRIBUTORS.includes(commentAuthor)) {
84+
if ( isCloseContributor || await hasLabel(ISSUE_LABEL_HELP_WANTED) ) {
8585
core.setOutput('webhook_url', supportDevSlackWebhookUrl);
8686
} else {
8787
core.setOutput('webhook_url', supportDevNotificationsSlackWebhookUrl);
@@ -93,6 +93,9 @@ module.exports = async ({ github, context, core }) => {
9393
if(PastBotComments.length > 0){
9494
lastBotComment = PastBotComments.at(-1);
9595
core.setOutput('bot_replied', false);
96+
core.setOutput('bot_reply_skipped', true);
97+
const slackMessage = `*[${repo}] Bot response skipped on issue: <${issueUrl}|${escapedTitle}> (less than 1 hour since last bot reply)*`;
98+
core.setOutput('slack_notification_bot_skipped', slackMessage);
9699
} else if(PastBotComments.length === 0){
97100
console.log("bot is replying");
98101
lastBotComment = await botReply();

scripts/is-close-contributor.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const { CLOSE_CONTRIBUTORS, TEAMS_WITH_CLOSE_CONTRIBUTORS } = require('./constants');
2+
3+
module.exports = async ({ core, github, context }) => {
4+
const username = process.env.USERNAME;
5+
if (!username) {
6+
core.setFailed('Missing username input.');
7+
return;
8+
}
9+
10+
if (CLOSE_CONTRIBUTORS.map(c => c.toLowerCase().trim()).includes(username.toLowerCase().trim())) {
11+
core.info(`User '${username}' found in the CLOSE CONTRIBUTORS list.`);
12+
core.setOutput('is_close_contributor', true);
13+
return;
14+
}
15+
16+
const org = context.repo.owner;
17+
18+
// Even though we check on team members here, it's best
19+
// to add everyone to CLOSE_CONTRIBUTORS constant anyway
20+
// for reliable results (e.g. check below won't work
21+
// for private members)
22+
const promises = TEAMS_WITH_CLOSE_CONTRIBUTORS.map(team_slug =>
23+
github.rest.teams.getMembershipForUserInOrg({
24+
org,
25+
team_slug,
26+
username,
27+
})
28+
);
29+
30+
try {
31+
const results = await Promise.allSettled(promises);
32+
let isTeamMember = false;
33+
34+
for (const result of results) {
35+
if (result.status === 'fulfilled' && result.value.data.state === 'active') {
36+
isTeamMember = true;
37+
break;
38+
}
39+
40+
if (result.status === 'rejected' && result.reason.status !== 404) {
41+
throw new Error(`API Error: ${result.reason.message}`);
42+
}
43+
}
44+
45+
if (isTeamMember) {
46+
core.info(`User '${username}' was found to be a member of a monitored team.`);
47+
} else {
48+
core.info(`User '${username}' was not found to be a member of a monitored team.`);
49+
}
50+
51+
core.setOutput('is_close_contributor', isTeamMember);
52+
53+
} catch (error) {
54+
core.setFailed(error.message);
55+
}
56+
};

0 commit comments

Comments
 (0)