Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions .github/workflows/contributor-issue-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,26 @@ on:


jobs:
check-if-close-contributor:
name: Check if user is a close contributor
uses: learningequality/.github/.github/workflows/is-close-contributor.yml@main
secrets:
LE_BOT_APP_ID: ${{ secrets.LE_BOT_APP_ID }}
LE_BOT_PRIVATE_KEY: ${{ secrets.LE_BOT_PRIVATE_KEY }}
with:
username: ${{ github.event.comment.user.login }}


process-issue-comment:
name: Process issue comment

needs: [check-if-close-contributor]
if: >-
${{
!github.event.issue.pull_request &&
github.event.comment.author_association != 'MEMBER' &&
github.event.comment.author_association != 'OWNER' &&
github.event.comment.user.login != 'sentry-io[bot]' &&
github.event.comment.user.login != 'learning-equality-bot[bot]'
github.event.comment.user.login != 'learning-equality-bot[bot]' &&
(github.event.comment.author_association != 'MEMBER' || needs.check-if-close-contributor.outputs.is_close_contributor == 'true')
}}

runs-on: ubuntu-latest
Expand All @@ -52,11 +62,11 @@ jobs:
node-version: '20'

- name: Install dependencies
run: npm install
run: yarn install --frozen-lockfile

- name: Run script
id: script
uses: actions/github-script@v7
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
Expand All @@ -65,6 +75,7 @@ jobs:
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_COMMUNITY_NOTIFICATIONS_WEBHOOK_URL: ${{ secrets.SLACK_COMMUNITY_NOTIFICATIONS_WEBHOOK_URL }}
IS_CLOSE_CONTRIBUTOR: ${{ needs.check-if-close-contributor.outputs.is_close_contributor }}

- name: Send Slack notification about GitHub comment
uses: slackapi/slack-github-action@v2.1.0
Expand All @@ -87,3 +98,13 @@ jobs:
"text": "${{ steps.script.outputs.slack_notification_bot_comment }}"
}

- name: Send Slack notification about skipped GitHub bot reply
if: ${{ steps.script.outputs.bot_reply_skipped }}
uses: slackapi/slack-github-action@v2.1.0
with:
webhook-type: incoming-webhook
webhook: ${{ steps.script.outputs.webhook_url }}
payload: >
{
"text": "${{ steps.script.outputs.slack_notification_bot_skipped }}"
}
57 changes: 57 additions & 0 deletions .github/workflows/is-close-contributor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Check if user is a close contributor

on:
workflow_call:
inputs:
username:
description: 'Github username'
required: true
type: string
secrets:
LE_BOT_APP_ID:
required: true
LE_BOT_PRIVATE_KEY:
required: true
outputs:
is_close_contributor:
description: "True if the user is a close contributor, otherwise false"
value: ${{ jobs.check-contributor.outputs.is_close_contributor }}

jobs:
check-contributor:
name: Run check
runs-on: ubuntu-latest
outputs:
is_close_contributor: ${{ steps.check-script.outputs.is_close_contributor }}
steps:
- name: Generate App Token
id: generate-token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.LE_BOT_APP_ID }}
private_key: ${{ secrets.LE_BOT_PRIVATE_KEY }}

- name: Checkout .github repository
uses: actions/checkout@v4
with:
repository: learningequality/.github
ref: main

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Run script
id: check-script
uses: actions/github-script@v7
env:
USERNAME: ${{ inputs.username }}
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const script = require('./scripts/is-close-contributor.js');
return await script({core, github, context });
5 changes: 4 additions & 1 deletion scripts/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ const LE_BOT_USERNAME = 'learning-equality-bot[bot]';
// close contributors are treated a bit special in some workflows,
// for example, we receive a high priority notification about their
// comments on all issues rather than just on 'help wanted' issues
const CLOSE_CONTRIBUTORS = ['BabyElias', 'Dimi20cen', 'EshaanAgg', 'GarvitSinghal47', 'habibayman', 'iamshobhraj', 'indirectlylit', 'Jakoma02', 'KshitijThareja', 'muditchoudhary', 'nathanaelg16', 'nikkuAg', 'Sahil-Sinha-11', 'shivam-daksh', 'shruti862', 'thesujai', 'WinnyChang'];
const CLOSE_CONTRIBUTORS = ['AadarshM07', 'Abhishek-Punhani', 'BabyElias', 'Dimi20cen', 'EshaanAgg', 'GarvitSinghal47', 'habibayman', 'iamshobhraj', 'indirectlylit', 'Jakoma02', 'KshitijThareja', 'muditchoudhary', 'nathanaelg16', 'nikkuAg', 'Sahil-Sinha-11', 'shivam-daksh', 'shruti862', 'thesujai', 'WinnyChang', 'yeshwanth235'];

const TEAMS_WITH_CLOSE_CONTRIBUTORS = ['gsoc-contributors', 'learning-equality-community-guide'];

const KEYWORDS_DETECT_ASSIGNMENT_REQUEST = [
'assign', 'assigned',
Expand Down Expand Up @@ -39,4 +41,5 @@ module.exports = {
KEYWORDS_DETECT_ASSIGNMENT_REQUEST,
ISSUE_LABEL_HELP_WANTED,
BOT_MESSAGE_ISSUE_NOT_OPEN,
TEAMS_WITH_CLOSE_CONTRIBUTORS,
};
7 changes: 5 additions & 2 deletions scripts/contributor-issue-comment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const {
LE_BOT_USERNAME,
CLOSE_CONTRIBUTORS,
KEYWORDS_DETECT_ASSIGNMENT_REQUEST,
ISSUE_LABEL_HELP_WANTED,
BOT_MESSAGE_ISSUE_NOT_OPEN
Expand All @@ -21,6 +20,7 @@ module.exports = async ({ github, context, core }) => {
const owner = context.repo.owner;
const supportDevSlackWebhookUrl = process.env.SLACK_WEBHOOK_URL;
const supportDevNotificationsSlackWebhookUrl = process.env.SLACK_COMMUNITY_NOTIFICATIONS_WEBHOOK_URL;
const isCloseContributor = process.env.IS_CLOSE_CONTRIBUTOR === 'true';
const keywordRegexes = KEYWORDS_DETECT_ASSIGNMENT_REQUEST
.map(k => k.trim().toLowerCase())
.filter(Boolean)
Expand Down Expand Up @@ -81,7 +81,7 @@ module.exports = async ({ github, context, core }) => {
}


if (await hasLabel(ISSUE_LABEL_HELP_WANTED) || CLOSE_CONTRIBUTORS.includes(commentAuthor)) {
if ( isCloseContributor || await hasLabel(ISSUE_LABEL_HELP_WANTED) ) {
core.setOutput('webhook_url', supportDevSlackWebhookUrl);
} else {
core.setOutput('webhook_url', supportDevNotificationsSlackWebhookUrl);
Expand All @@ -93,6 +93,9 @@ module.exports = async ({ github, context, core }) => {
if(PastBotComments.length > 0){
lastBotComment = PastBotComments.at(-1);
core.setOutput('bot_replied', false);
core.setOutput('bot_reply_skipped', true);
const slackMessage = `*[${repo}] Bot response skipped on issue: <${issueUrl}|${escapedTitle}> (less than 1 hour since last bot reply)*`;
core.setOutput('slack_notification_bot_skipped', slackMessage);
} else if(PastBotComments.length === 0){
console.log("bot is replying");
lastBotComment = await botReply();
Expand Down
56 changes: 56 additions & 0 deletions scripts/is-close-contributor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const { CLOSE_CONTRIBUTORS, TEAMS_WITH_CLOSE_CONTRIBUTORS } = require('./constants');

module.exports = async ({ core, github, context }) => {
const username = process.env.USERNAME;
if (!username) {
core.setFailed('Missing username input.');
return;
}

if (CLOSE_CONTRIBUTORS.map(c => c.toLowerCase().trim()).includes(username.toLowerCase().trim())) {
core.info(`User '${username}' found in the CLOSE CONTRIBUTORS list.`);
core.setOutput('is_close_contributor', true);
return;
}

const org = context.repo.owner;

// Even though we check on team members here, it's best
// to add everyone to CLOSE_CONTRIBUTORS constant anyway
// for reliable results (e.g. check below won't work
// for private members)
const promises = TEAMS_WITH_CLOSE_CONTRIBUTORS.map(team_slug =>
github.rest.teams.getMembershipForUserInOrg({
org,
team_slug,
username,
})
);

try {
const results = await Promise.allSettled(promises);
let isTeamMember = false;

for (const result of results) {
if (result.status === 'fulfilled' && result.value.data.state === 'active') {
isTeamMember = true;
break;
}

if (result.status === 'rejected' && result.reason.status !== 404) {
throw new Error(`API Error: ${result.reason.message}`);
}
}

if (isTeamMember) {
core.info(`User '${username}' was found to be a member of a monitored team.`);
} else {
core.info(`User '${username}' was not found to be a member of a monitored team.`);
}

core.setOutput('is_close_contributor', isTeamMember);

} catch (error) {
core.setFailed(error.message);
}
};