Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bounty Bot Enhancement: Fixed Label Updates & Slack Integration #66

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
43 changes: 43 additions & 0 deletions .github/workflows/blt-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Auto Assign & Bounty Bot

on:
issue_comment:
types: [created]
schedule:
- cron: '0 0 * * *'
workflow_dispatch:

jobs:
auto-assign:
runs-on: ubuntu-latest
steps:
- name: Assign Issues
uses: OWASP/BLT-Action@main
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true # Allow next job to run if this fails

bounty:
runs-on: ubuntu-latest
needs: auto-assign
steps:
- name: Checkout code
uses: actions/checkout@v4

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

- name: Install dependencies
run: |
npm install @octokit/rest @slack/web-api

- name: Capture GitHub Context
run: echo '${{ toJson(github.event) }}' > github_context.json

- name: Run Bounty Bot
env:
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
run: node src/index.js github_context.json # Ensure this matches your file name
65 changes: 62 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
const core = require('@actions/core');
const github = require('@actions/github');
const {WebClient} = require('@slack/web-api');

const run = async () => {
try {
console.log("Starting GitHub Action...");

// Get necessary inputs
const gitHubToken = core.getInput('repo-token', { required: true });
const gitHubToken = core.getInput('repo-token') || process.env.PERSONAL_ACCESS_TOKEN;
const slackToken = core.getInput('slack-token');
const slackChannel = core.getInput('slack-channel');
const bountyAmount = core.getInput('bounty-amount') || 0;
const octokit = github.getOctokit(gitHubToken);
const slack = new WebClient(slackToken);

const { eventName, payload, repo } = github.context;
const { issue, comment } = payload;
Expand Down Expand Up @@ -71,7 +76,7 @@ const run = async () => {
owner,
repo: repoName,
issue_number: issue.number,
body: `You have been unassigned from this issue. It’s now open for others. You can reassign it anytime by typing /assign.`
body: `You have been unassigned from this issue. It's now open for others. You can reassign it anytime by typing /assign.`
});
}
} else {
Expand Down Expand Up @@ -147,6 +152,59 @@ const run = async () => {
console.error(`Error assigning issue #${issue.number}:`, error);
}
}

// Bounty processing for the current comment
try {
const { data: labels } = await octokit.issues.listLabelsOnIssue({
owner,
repo: repoName,
issue_number: issue.number
});
let totalBounty = parseInt(bountyAmount, 10) || 0;
const bountyLabel = labels.find(label => label.name.startsWith("$"));

if (bountyLabel) {
totalBounty += parseInt(bountyLabel.name.slice(1), 10);
await octokit.issues.updateLabel({
owner,
repo: repoName,
name: bountyLabel.name,
new_name: `$${totalBounty}`
});
} else {
await octokit.issues.addLabels({
owner,
repo: repoName,
issue_number: issue.number,
labels: [`$${totalBounty}`]
});
}

// Only create bounty comment if there's an actual bounty
if (totalBounty > 0) {
await octokit.issues.createComment({
owner,
repo: repoName,
issue_number: issue.number,
body: `πŸ’° A bounty has been added! This issue now has a total bounty of **$${totalBounty}** thanks to @${comment.user.login}.`
});
}
} catch (error) {
console.error("Error processing bounty:", error);
}

// Slack notification
try {
if (slackToken && slackChannel) {
const message = `New activity on GitHub: ${repository} issue #${issue.number} - ${comment.body.slice(0, 100)}...`;
await slack.chat.postMessage({
channel: slackChannel,
text: message
});
}
} catch (error) {
console.error("Error sending Slack notification:", error);
}
}

console.log('Checking for stale assignments...');
Expand Down Expand Up @@ -208,7 +266,8 @@ const run = async () => {

} catch (error) {
console.error("Critical error in GitHub Action:", error);
core.setFailed(error.message);
}
};

run();
run();