From cdb03d2ba3ae207f26fed2687d286c050c8f09a8 Mon Sep 17 00:00:00 2001 From: sadaf Date: Sat, 23 Sep 2023 16:27:45 +0530 Subject: [PATCH 1/9] feat(event.ts): sending context through params --- src/bindings/event.ts | 27 ++++++++++++--------------- src/types/config.ts | 5 +++++ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/bindings/event.ts b/src/bindings/event.ts index f36641565..b9f55b1d6 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -2,7 +2,7 @@ import { Context } from "probot"; import { createAdapters } from "../adapters"; import { processors, wildcardProcessors } from "../handlers/processors"; import { shouldSkip } from "../helpers"; -import { BotConfig, GithubEvent, Payload, PayloadSchema, LogLevel } from "../types"; +import { BotContext, GithubEvent, Payload, PayloadSchema, LogLevel } from "../types"; import { Adapters } from "../types/adapters"; import { ajv } from "../utils"; import { loadConfig } from "./config"; @@ -12,9 +12,6 @@ import { validateConfigChange } from "../handlers/push"; let botContext: Context = {} as Context; export const getBotContext = () => botContext; -let botConfig: BotConfig = {} as BotConfig; -export const getBotConfig = () => botConfig; - let adapters: Adapters = {} as Adapters; export const getAdapters = () => adapters; @@ -30,7 +27,7 @@ export const getLogger = (): Logger => logger; const NO_VALIDATION = [GithubEvent.INSTALLATION_ADDED_EVENT as string, GithubEvent.PUSH_EVENT as string]; -export const bindEvents = async (context: Context): Promise => { +export const bindEvents = async (context: BotContext): Promise => { const { id, name } = context; botContext = context; const payload = context.payload as Payload; @@ -39,12 +36,12 @@ export const bindEvents = async (context: Context): Promise => { let botConfigError; try { - botConfig = await loadConfig(context); + context.botConfig = await loadConfig(context); } catch (err) { botConfigError = err; } - adapters = createAdapters(botConfig); + adapters = createAdapters(context.botConfig); const options = { app: "UbiquiBot", @@ -53,9 +50,9 @@ export const bindEvents = async (context: Context): Promise => { logger = new GitHubLogger( options.app, - botConfig?.log?.logEnvironment ?? "development", - botConfig?.log?.level ?? LogLevel.DEBUG, - botConfig?.log?.retryLimit ?? 0 + context.botConfig?.log?.logEnvironment ?? "development", + context.botConfig?.log?.level ?? LogLevel.DEBUG, + context.botConfig?.log?.retryLimit ?? 0 ); // contributors will see logs in console while on development env if (!logger) { return; @@ -74,11 +71,11 @@ export const bindEvents = async (context: Context): Promise => { logger.info( `Config loaded! config: ${JSON.stringify({ - price: botConfig.price, - unassign: botConfig.unassign, - mode: botConfig.mode, - log: botConfig.log, - wallet: botConfig.wallet, + price: context.botConfig.price, + unassign: context.botConfig.unassign, + mode: context.botConfig.mode, + log: context.botConfig.log, + wallet: context.botConfig.wallet, })}` ); diff --git a/src/types/config.ts b/src/types/config.ts index 4f5dde5ce..fcc841bc2 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -1,5 +1,6 @@ import { Static, Type } from "@sinclair/typebox"; import { LogLevel } from "./log"; +import { Context } from "probot"; const LabelItemSchema = Type.Object( { @@ -143,6 +144,10 @@ export const BotConfigSchema = Type.Object({ export type BotConfig = Static; +export interface BotContext extends Context { + botConfig: BotConfig; +} + export const StreamlinedCommentSchema = Type.Object({ login: Type.Optional(Type.String()), body: Type.Optional(Type.String()), From 238700c976207a24d21584abfda71831759b7311 Mon Sep 17 00:00:00 2001 From: sadaf Date: Mon, 25 Sep 2023 10:50:48 +0530 Subject: [PATCH 2/9] feat(telegram): making changes in the telegram notifier --- src/adapters/telegram/helpers/client.ts | 11 ++++++----- src/bindings/event.ts | 5 ----- src/tests/message-test.ts | 11 ++++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/adapters/telegram/helpers/client.ts b/src/adapters/telegram/helpers/client.ts index 4a54afc09..37f248ebf 100644 --- a/src/adapters/telegram/helpers/client.ts +++ b/src/adapters/telegram/helpers/client.ts @@ -1,5 +1,6 @@ import { Input } from "telegraf"; -import { getAdapters, getBotConfig } from "../../../bindings"; +import { getAdapters } from "../../../bindings"; +import { BotContext } from "../../../types"; import { TLMessageFormattedPayload, TLMessagePayload, TLPhotoPayload } from "../types/payload"; export function messageFormatter(messagePayload: TLMessagePayload) { @@ -14,10 +15,10 @@ export function messageFormatter(messagePayload: TLMessagePayload) { return msgObj; } -export async function telegramFormattedNotifier(messagePayload: TLMessageFormattedPayload) { +export async function telegramFormattedNotifier(messagePayload: TLMessageFormattedPayload, context: BotContext) { const { telegram: { delay }, - } = getBotConfig(); + } = context.botConfig; const { telegram } = getAdapters(); const { chatIds, text, parseMode } = messagePayload; @@ -40,14 +41,14 @@ export async function telegramFormattedNotifier(messagePayload: TLMessageFormatt sendHandler(); } -export async function telegramNotifier(messagePayload: TLMessagePayload) { +export async function telegramNotifier(messagePayload: TLMessagePayload, context: BotContext) { const messageString = messageFormatter(messagePayload); const messageObj: TLMessageFormattedPayload = { chatIds: messagePayload.chatIds, text: messageString, parseMode: "HTML", }; - await telegramFormattedNotifier(messageObj); + await telegramFormattedNotifier(messageObj, context); } export async function telegramPhotoNotifier(messagePayload: TLPhotoPayload) { diff --git a/src/bindings/event.ts b/src/bindings/event.ts index b9f55b1d6..0386e0979 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -1,4 +1,3 @@ -import { Context } from "probot"; import { createAdapters } from "../adapters"; import { processors, wildcardProcessors } from "../handlers/processors"; import { shouldSkip } from "../helpers"; @@ -9,9 +8,6 @@ import { loadConfig } from "./config"; import { GitHubLogger } from "../adapters/supabase"; import { validateConfigChange } from "../handlers/push"; -let botContext: Context = {} as Context; -export const getBotContext = () => botContext; - let adapters: Adapters = {} as Adapters; export const getAdapters = () => adapters; @@ -29,7 +25,6 @@ const NO_VALIDATION = [GithubEvent.INSTALLATION_ADDED_EVENT as string, GithubEve export const bindEvents = async (context: BotContext): Promise => { const { id, name } = context; - botContext = context; const payload = context.payload as Payload; const allowedEvents = Object.values(GithubEvent) as string[]; const eventName = payload.action ? `${name}.${payload.action}` : name; // some events wont have actions as this grows diff --git a/src/tests/message-test.ts b/src/tests/message-test.ts index 97aec52a8..b311f0200 100644 --- a/src/tests/message-test.ts +++ b/src/tests/message-test.ts @@ -1,7 +1,8 @@ import { telegramFormattedNotifier, telegramNotifier } from "../adapters/telegram/helpers"; +import { BotContext } from "../types"; const chatIds = ["tg1", "tg2", "tg3"]; // SHOULD update chatIds with valid ones -export async function messageTests() { +export async function messageTests(context: BotContext) { /**@method telegramNotifier - call unformatted issue */ await telegramNotifier({ chatIds: chatIds, @@ -11,7 +12,7 @@ export async function messageTests() { id: `10`, ref: `https://github.com/ubiquity/ubiquity-dollar/issues/10`, user: `pavlovcik`, - }); + }, context); /**@method telegramNotifier - call unformatted pull */ await telegramNotifier({ @@ -22,7 +23,7 @@ export async function messageTests() { id: `246`, ref: `https://github.com/ubiquity/ubiquity-dollar/pull/246`, user: `pavlovcik`, - }); + }, context); /**@method telegramFormattedNotifier - call formatted issue */ await telegramFormattedNotifier({ @@ -34,7 +35,7 @@ export async function messageTests() { `pavlovcik\n` + `I worked through getting the build process to work by force \nmoving all dev dependencies into dependencies, but \nnow the build process is extremely slow on vercel.`, parseMode: "HTML", - }); + }, context); /**@method telegramFormattedNotifier - call formatted pull */ await telegramFormattedNotifier({ @@ -46,5 +47,5 @@ export async function messageTests() { `pavlovcik\n` + `Small enhancements but mostly renamed the \ninternal smart contract references, and \nadded support for DAI and USDT in the inventory.`, parseMode: "HTML", - }); + }, context); } From ba461da8cc876bb93404953ae884e7e8036d8257 Mon Sep 17 00:00:00 2001 From: sadaf Date: Tue, 26 Sep 2023 14:44:33 +0530 Subject: [PATCH 3/9] adding botContext to params --- src/adapters/supabase/helpers/log.ts | 11 ++++---- src/adapters/telegram/helpers/client.ts | 6 ++-- src/bindings/event.ts | 1 + src/handlers/access/labels-access.ts | 9 +++--- src/handlers/assign/action.ts | 12 ++++---- src/handlers/assign/auto.ts | 7 ++--- src/handlers/comment/action.ts | 15 +++++----- src/handlers/comment/handlers/allow.ts | 7 ++--- src/handlers/comment/handlers/ask.ts | 7 ++--- src/handlers/comment/handlers/assign.ts | 10 +++---- src/handlers/comment/handlers/first.ts | 11 ++++---- src/handlers/comment/handlers/help.ts | 14 +++++----- src/handlers/comment/handlers/index.ts | 28 +++++++++---------- src/handlers/comment/handlers/multiplier.ts | 7 ++--- src/handlers/comment/handlers/payout.ts | 15 +++++----- src/handlers/comment/handlers/query.ts | 7 ++--- src/handlers/comment/handlers/unassign.ts | 10 +++---- src/handlers/comment/handlers/wallet.ts | 10 +++---- src/handlers/issue/pre.ts | 7 ++--- src/handlers/payout/action.ts | 12 ++++---- src/handlers/payout/post.ts | 11 +++----- src/handlers/pricing/action.ts | 13 ++++----- src/handlers/pricing/pre.ts | 7 +++-- .../pull-request/create-devpool-pr.ts | 8 ++---- src/handlers/push/index.ts | 12 +++----- src/handlers/shared/pricing.ts | 12 ++++---- src/tests/message-test.ts | 16 +++++------ 27 files changed, 133 insertions(+), 152 deletions(-) diff --git a/src/adapters/supabase/helpers/log.ts b/src/adapters/supabase/helpers/log.ts index 51a16f5b2..d890620e7 100644 --- a/src/adapters/supabase/helpers/log.ts +++ b/src/adapters/supabase/helpers/log.ts @@ -1,5 +1,5 @@ -import { getAdapters, getBotContext, Logger } from "../../../bindings"; -import { Payload, LogLevel } from "../../../types"; +import { getAdapters, Logger } from "../../../bindings"; +import { Payload, LogLevel, BotContext } from "../../../types"; import { getOrgAndRepoFromPath } from "../../../utils/private"; interface Log { @@ -43,13 +43,15 @@ export class GitHubLogger implements Logger { private retryDelay = 1000; // Delay between retries in milliseconds private throttleCount = 0; private retryLimit = 0; // Retries disabled by default + private context; - constructor(app: string, logEnvironment: string, maxLevel: LogLevel, retryLimit: number) { + constructor(context: BotContext, app: string, logEnvironment: string, maxLevel: LogLevel, retryLimit: number) { this.app = app; this.logEnvironment = logEnvironment; this.maxLevel = getNumericLevel(maxLevel); this.retryLimit = retryLimit; this.supabase = getAdapters().supabase; + this.context = context; } async sendLogsToSupabase({ repo, org, commentId, issueNumber, logMessage, level, timestamp }: Log) { @@ -132,8 +134,7 @@ export class GitHubLogger implements Logger { private save(logMessage: string | object, level: LogLevel, errorPayload?: string | object) { if (getNumericLevel(level) > this.maxLevel) return; // only return errors lower than max level - const context = getBotContext(); - const payload = context.payload as Payload; + const payload = this.context.payload as Payload; const timestamp = new Date().toUTCString(); const { comment, issue, repository } = payload; diff --git a/src/adapters/telegram/helpers/client.ts b/src/adapters/telegram/helpers/client.ts index 37f248ebf..1ced31f41 100644 --- a/src/adapters/telegram/helpers/client.ts +++ b/src/adapters/telegram/helpers/client.ts @@ -15,7 +15,7 @@ export function messageFormatter(messagePayload: TLMessagePayload) { return msgObj; } -export async function telegramFormattedNotifier(messagePayload: TLMessageFormattedPayload, context: BotContext) { +export async function telegramFormattedNotifier(context: BotContext, messagePayload: TLMessageFormattedPayload) { const { telegram: { delay }, } = context.botConfig; @@ -41,14 +41,14 @@ export async function telegramFormattedNotifier(messagePayload: TLMessageFormatt sendHandler(); } -export async function telegramNotifier(messagePayload: TLMessagePayload, context: BotContext) { +export async function telegramNotifier(context: BotContext, messagePayload: TLMessagePayload) { const messageString = messageFormatter(messagePayload); const messageObj: TLMessageFormattedPayload = { chatIds: messagePayload.chatIds, text: messageString, parseMode: "HTML", }; - await telegramFormattedNotifier(messageObj, context); + await telegramFormattedNotifier(context, messageObj); } export async function telegramPhotoNotifier(messagePayload: TLPhotoPayload) { diff --git a/src/bindings/event.ts b/src/bindings/event.ts index 0386e0979..32455ff17 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -44,6 +44,7 @@ export const bindEvents = async (context: BotContext): Promise => { }; logger = new GitHubLogger( + context, options.app, context.botConfig?.log?.logEnvironment ?? "development", context.botConfig?.log?.level ?? LogLevel.DEBUG, diff --git a/src/handlers/access/labels-access.ts b/src/handlers/access/labels-access.ts index 228aa5a38..83a4a4fae 100644 --- a/src/handlers/access/labels-access.ts +++ b/src/handlers/access/labels-access.ts @@ -1,13 +1,12 @@ import { getAccessLevel } from "../../adapters/supabase"; -import { getBotConfig, getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { addCommentToIssue, getUserPermission, removeLabel, addLabelToIssue } from "../../helpers"; -import { Payload } from "../../types"; +import { BotContext, Payload } from "../../types"; -export const handleLabelsAccess = async () => { - const { accessControl } = getBotConfig(); +export const handleLabelsAccess = async (context: BotContext) => { + const { accessControl } = context.botConfig; if (!accessControl.label) return true; - const context = getBotContext(); const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue) return; diff --git a/src/handlers/assign/action.ts b/src/handlers/assign/action.ts index e0093de07..7540e918d 100644 --- a/src/handlers/assign/action.ts +++ b/src/handlers/assign/action.ts @@ -1,13 +1,12 @@ -import { getBotConfig, getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { addCommentToIssue, closePullRequest, calculateWeight, calculateDuration } from "../../helpers"; import { gitLinkedPrParser } from "../../helpers/parser"; -import { Payload, LabelItem } from "../../types"; +import { Payload, LabelItem, BotContext } from "../../types"; import { deadLinePrefix } from "../shared"; const exclude_accounts: string[] = []; -export const commentWithAssignMessage = async (): Promise => { - const context = getBotContext(); - const config = getBotConfig(); +export const commentWithAssignMessage = async (context: BotContext): Promise => { + const config = context.botConfig; const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue) { @@ -67,8 +66,7 @@ export const commentWithAssignMessage = async (): Promise => { await addCommentToIssue(commit_msg, payload.issue?.number); }; -export const closePullRequestForAnIssue = async (): Promise => { - const context = getBotContext(); +export const closePullRequestForAnIssue = async (context: BotContext): Promise => { const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue?.number) return; diff --git a/src/handlers/assign/auto.ts b/src/handlers/assign/auto.ts index 380b59983..4f6523fac 100644 --- a/src/handlers/assign/auto.ts +++ b/src/handlers/assign/auto.ts @@ -1,11 +1,10 @@ -import { getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { addAssignees, getAllPullRequests, getIssueByNumber, getPullByNumber } from "../../helpers"; import { gitLinkedIssueParser } from "../../helpers/parser"; -import { Payload } from "../../types"; +import { BotContext, Payload } from "../../types"; // Check for pull requests linked to their respective issues but not assigned to them -export const checkPullRequests = async () => { - const context = getBotContext(); +export const checkPullRequests = async (context: BotContext) => { const logger = getLogger(); const pulls = await getAllPullRequests(context); diff --git a/src/handlers/comment/action.ts b/src/handlers/comment/action.ts index 60ea5bbae..1d4f1e6d1 100644 --- a/src/handlers/comment/action.ts +++ b/src/handlers/comment/action.ts @@ -1,13 +1,12 @@ -import { getBotConfig, getBotContext, getLogger } from "../../bindings"; -import { Payload } from "../../types"; +import { getLogger } from "../../bindings"; +import { BotContext, Payload } from "../../types"; import { ErrorDiff } from "../../utils/helpers"; import { IssueCommentCommands } from "./commands"; import { commentParser, userCommands } from "./handlers"; import { verifyFirstCheck } from "./handlers/first"; -export const handleComment = async (): Promise => { - const context = getBotContext(); - const config = getBotConfig(); +export const handleComment = async (context: BotContext): Promise => { + const config = context.botConfig; const logger = getLogger(); const payload = context.payload as Payload; @@ -22,11 +21,11 @@ export const handleComment = async (): Promise => { const commentedCommands = commentParser(body); if (commentedCommands.length === 0) { - await verifyFirstCheck(); + await verifyFirstCheck(context); return; } - const allCommands = userCommands(); + const allCommands = userCommands(context); for (const command of commentedCommands) { const userCommand = allCommands.find((i) => i.id == command); @@ -34,7 +33,7 @@ export const handleComment = async (): Promise => { const { id, handler, callback, successComment, failureComment } = userCommand; logger.info(`Running a comment handler: ${handler.name}`); - const { payload: _payload } = getBotContext(); + const { payload: _payload } = context; const issue = (_payload as Payload).issue; if (!issue) continue; diff --git a/src/handlers/comment/handlers/allow.ts b/src/handlers/comment/handlers/allow.ts index aa867985c..caa05893e 100644 --- a/src/handlers/comment/handlers/allow.ts +++ b/src/handlers/comment/handlers/allow.ts @@ -1,10 +1,9 @@ import { upsertAccessControl } from "../../../adapters/supabase"; -import { getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { getUserPermission } from "../../../helpers"; -import { Payload } from "../../../types"; +import { BotContext, Payload } from "../../../types"; -export const setAccess = async (body: string) => { - const context = getBotContext(); +export const setAccess = async (context: BotContext, body: string) => { const logger = getLogger(); const payload = context.payload as Payload; const sender = payload.sender.login; diff --git a/src/handlers/comment/handlers/ask.ts b/src/handlers/comment/handlers/ask.ts index 63777d4ae..6520985d4 100644 --- a/src/handlers/comment/handlers/ask.ts +++ b/src/handlers/comment/handlers/ask.ts @@ -1,5 +1,5 @@ -import { getBotContext, getLogger } from "../../../bindings"; -import { Payload, StreamlinedComment, UserType } from "../../../types"; +import { getLogger } from "../../../bindings"; +import { BotContext, Payload, StreamlinedComment, UserType } from "../../../types"; import { getAllIssueComments, getAllLinkedIssuesAndPullsInBody } from "../../../helpers"; import { CreateChatCompletionRequestMessage } from "openai/resources/chat"; import { askGPT, decideContextGPT, sysMsg } from "../../../helpers/gpt"; @@ -8,8 +8,7 @@ import { ErrorDiff } from "../../../utils/helpers"; /** * @param body The question to ask */ -export const ask = async (body: string) => { - const context = getBotContext(); +export const ask = async (context: BotContext, body: string) => { const logger = getLogger(); const payload = context.payload as Payload; diff --git a/src/handlers/comment/handlers/assign.ts b/src/handlers/comment/handlers/assign.ts index e50831a64..87cbeb622 100644 --- a/src/handlers/comment/handlers/assign.ts +++ b/src/handlers/comment/handlers/assign.ts @@ -1,6 +1,6 @@ import { addAssignees, getAssignedIssues, getAvailableOpenedPullRequests, getAllIssueComments, calculateWeight, calculateDuration } from "../../../helpers"; -import { getBotConfig, getBotContext, getLogger } from "../../../bindings"; -import { Payload, LabelItem, Comment, IssueType, Issue } from "../../../types"; +import { getLogger } from "../../../bindings"; +import { Payload, LabelItem, Comment, IssueType, Issue, BotContext } from "../../../types"; import { deadLinePrefix } from "../../shared"; import { getWalletAddress, getWalletMultiplier } from "../../../adapters/supabase"; import { tableComment } from "./table"; @@ -8,10 +8,10 @@ import { bountyInfo } from "../../wildcard"; import { ASSIGN_COMMAND_ENABLED, GLOBAL_STRINGS } from "../../../configs"; import { isParentIssue } from "../../pricing"; -export const assign = async (body: string) => { - const { payload: _payload } = getBotContext(); +export const assign = async (context: BotContext, body: string) => { + const { payload: _payload } = context; const logger = getLogger(); - const config = getBotConfig(); + const config = context.botConfig; const payload = _payload as Payload; const { repository, organization } = payload; diff --git a/src/handlers/comment/handlers/first.ts b/src/handlers/comment/handlers/first.ts index 77e898420..30fa196ff 100644 --- a/src/handlers/comment/handlers/first.ts +++ b/src/handlers/comment/handlers/first.ts @@ -1,17 +1,16 @@ -import { getBotConfig, getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { upsertCommentToIssue } from "../../../helpers"; -import { Payload } from "../../../types"; +import { BotContext, Payload } from "../../../types"; import { generateHelpMenu } from "./help"; -export const verifyFirstCheck = async (): Promise => { - const context = getBotContext(); +export const verifyFirstCheck = async (context: BotContext): Promise => { const logger = getLogger(); const payload = context.payload as Payload; let msg = ""; if (!payload.issue) return; const { newContributorGreeting: { header, helpMenu, footer, enabled }, - } = getBotConfig(); + } = context.botConfig; try { const response_issue = await context.octokit.rest.search.issuesAndPullRequests({ q: `is:issue repo:${payload.repository.owner.login}/${payload.repository.name} commenter:${payload.sender.login}`, @@ -37,7 +36,7 @@ export const verifyFirstCheck = async (): Promise => { msg += `${header}\n`; } if (helpMenu) { - msg += `${generateHelpMenu()}\n@${payload.sender.login}\n`; + msg += `${generateHelpMenu(context)}\n@${payload.sender.login}\n`; } if (footer) { msg += `${footer}`; diff --git a/src/handlers/comment/handlers/help.ts b/src/handlers/comment/handlers/help.ts index 7e2c11bd4..bd168dd18 100644 --- a/src/handlers/comment/handlers/help.ts +++ b/src/handlers/comment/handlers/help.ts @@ -1,11 +1,11 @@ import { userCommands } from "."; -import { getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { ASSIGN_COMMAND_ENABLED } from "../../../configs"; -import { IssueType, Payload } from "../../../types"; +import { BotContext, IssueType, Payload } from "../../../types"; import { IssueCommentCommands } from "../commands"; -export const listAvailableCommands = async (body: string) => { - const { payload: _payload } = getBotContext(); +export const listAvailableCommands = async (context: BotContext, body: string) => { + const { payload: _payload } = context; const logger = getLogger(); if (body != IssueCommentCommands.HELP && body.replace(/`/g, "") != IssueCommentCommands.HELP) { logger.info(`Skipping to list available commands. body: ${body}`); @@ -24,12 +24,12 @@ export const listAvailableCommands = async (body: string) => { return; } - return generateHelpMenu(); + return generateHelpMenu(context); }; -export const generateHelpMenu = () => { +export const generateHelpMenu = (context: BotContext) => { let helpMenu = "### Available commands\n```"; - const commands = userCommands(); + const commands = userCommands(context); commands.map((command) => { // if first command, add a new line if (command.id === commands[0].id) { diff --git a/src/handlers/comment/handlers/index.ts b/src/handlers/comment/handlers/index.ts index 490b0b934..d84eb974c 100644 --- a/src/handlers/comment/handlers/index.ts +++ b/src/handlers/comment/handlers/index.ts @@ -1,4 +1,4 @@ -import { Comment, Payload, UserCommands } from "../../../types"; +import { BotContext, Comment, Payload, UserCommands } from "../../../types"; import { IssueCommentCommands } from "../commands"; import { assign } from "./assign"; import { listAvailableCommands } from "./help"; @@ -23,7 +23,7 @@ import { getAllIssueAssignEvents, calculateWeight, } from "../../../helpers"; -import { getBotConfig, getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { handleIssueClosed, incentivesCalculation, @@ -88,20 +88,20 @@ export const commentParser = (body: string): IssueCommentCommands[] => { * Callback for issues closed - Processor */ -export const issueClosedCallback = async (): Promise => { - const { payload: _payload } = getBotContext(); +export const issueClosedCallback = async (context: BotContext): Promise => { + const { payload: _payload } = context; const issue = (_payload as Payload).issue; if (!issue) return; try { // assign function incentivesCalculation to a variable - const calculateIncentives = await incentivesCalculation(); + const calculateIncentives = await incentivesCalculation(context); const creatorReward = await calculateIssueCreatorReward(calculateIncentives); const assigneeReward = await calculateIssueAssigneeReward(calculateIncentives); const conversationRewards = await calculateIssueConversationReward(calculateIncentives); const pullRequestReviewersReward = await calculatePullRequestReviewsReward(calculateIncentives); - const { error } = await handleIssueClosed(creatorReward, assigneeReward, conversationRewards, pullRequestReviewersReward, calculateIncentives); + const { error } = await handleIssueClosed(context, creatorReward, assigneeReward, conversationRewards, pullRequestReviewersReward, calculateIncentives); if (error) { throw new Error(error); @@ -115,10 +115,10 @@ export const issueClosedCallback = async (): Promise => { * Callback for issues created - Processor */ -export const issueCreatedCallback = async (): Promise => { +export const issueCreatedCallback = async (context: BotContext): Promise => { const logger = getLogger(); - const { payload: _payload } = getBotContext(); - const config = getBotConfig(); + const { payload: _payload } = context; + const config = context.botConfig; const issue = (_payload as Payload).issue; if (!issue) return; const labels = issue.labels; @@ -156,11 +156,11 @@ export const issueCreatedCallback = async (): Promise => { * Callback for issues reopened - Processor */ -export const issueReopenedCallback = async (): Promise => { - const { payload: _payload } = getBotContext(); +export const issueReopenedCallback = async (context: BotContext): Promise => { + const { payload: _payload } = context; const { payout: { permitBaseUrl }, - } = getBotConfig(); + } = context.botConfig; const logger = getLogger(); const issue = (_payload as Payload).issue; const repository = (_payload as Payload).repository; @@ -245,8 +245,8 @@ const commandCallback = async (issue_number: number, comment: string, action: st await upsertCommentToIssue(issue_number, comment, action, reply_to); }; -export const userCommands = (): UserCommands[] => { - const config = getBotConfig(); +export const userCommands = (context: BotContext): UserCommands[] => { + const config = context.botConfig; return [ { diff --git a/src/handlers/comment/handlers/multiplier.ts b/src/handlers/comment/handlers/multiplier.ts index a7cc674eb..469c2b17a 100644 --- a/src/handlers/comment/handlers/multiplier.ts +++ b/src/handlers/comment/handlers/multiplier.ts @@ -1,10 +1,9 @@ import { getAccessLevel, upsertWalletMultiplier } from "../../../adapters/supabase"; -import { getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { getUserPermission } from "../../../helpers"; -import { Payload } from "../../../types"; +import { BotContext, Payload } from "../../../types"; -export const multiplier = async (body: string) => { - const context = getBotContext(); +export const multiplier = async (context: BotContext, body: string) => { const logger = getLogger(); const payload = context.payload as Payload; const sender = payload.sender.login; diff --git a/src/handlers/comment/handlers/payout.ts b/src/handlers/comment/handlers/payout.ts index d5aabc7d6..e53b53858 100644 --- a/src/handlers/comment/handlers/payout.ts +++ b/src/handlers/comment/handlers/payout.ts @@ -1,5 +1,5 @@ -import { getBotContext, getLogger } from "../../../bindings"; -import { Payload } from "../../../types"; +import { getLogger } from "../../../bindings"; +import { BotContext, Payload } from "../../../types"; import { IssueCommentCommands } from "../commands"; import { calculateIssueAssigneeReward, @@ -12,8 +12,8 @@ import { import { getAllIssueComments, getUserPermission } from "../../../helpers"; import { GLOBAL_STRINGS } from "../../../configs"; -export const payout = async (body: string) => { - const { payload: _payload } = getBotContext(); +export const payout = async (context: BotContext, body: string) => { + const { payload: _payload } = context; const logger = getLogger(); if (body != IssueCommentCommands.PAYOUT && body.replace(/`/g, "") != IssueCommentCommands.PAYOUT) { logger.info(`Skipping to payout. body: ${body}`); @@ -46,18 +46,17 @@ export const payout = async (body: string) => { } // assign function incentivesCalculation to a variable - const calculateIncentives = await incentivesCalculation(); + const calculateIncentives = await incentivesCalculation(context); const creatorReward = await calculateIssueCreatorReward(calculateIncentives); const assigneeReward = await calculateIssueAssigneeReward(calculateIncentives); const conversationRewards = await calculateIssueConversationReward(calculateIncentives); const pullRequestReviewersReward = await calculatePullRequestReviewsReward(calculateIncentives); - return await handleIssueClosed(creatorReward, assigneeReward, conversationRewards, pullRequestReviewersReward, calculateIncentives); + return await handleIssueClosed(context, creatorReward, assigneeReward, conversationRewards, pullRequestReviewersReward, calculateIncentives); }; -export const autoPay = async (body: string) => { - const context = getBotContext(); +export const autoPay = async (context: BotContext, body: string) => { const _payload = context.payload; const logger = getLogger(); diff --git a/src/handlers/comment/handlers/query.ts b/src/handlers/comment/handlers/query.ts index 3334225b3..4519e75f7 100644 --- a/src/handlers/comment/handlers/query.ts +++ b/src/handlers/comment/handlers/query.ts @@ -1,9 +1,8 @@ import { getAllAccessLevels, getWalletInfo } from "../../../adapters/supabase"; -import { getBotContext, getLogger } from "../../../bindings"; -import { Payload } from "../../../types"; +import { getLogger } from "../../../bindings"; +import { BotContext, Payload } from "../../../types"; -export const query = async (body: string) => { - const context = getBotContext(); +export const query = async (context: BotContext, body: string) => { const logger = getLogger(); const payload = context.payload as Payload; const sender = payload.sender.login; diff --git a/src/handlers/comment/handlers/unassign.ts b/src/handlers/comment/handlers/unassign.ts index 91aae184e..172639891 100644 --- a/src/handlers/comment/handlers/unassign.ts +++ b/src/handlers/comment/handlers/unassign.ts @@ -1,11 +1,11 @@ import { removeAssignees } from "../../../helpers"; -import { getBotContext, getLogger } from "../../../bindings"; -import { Payload } from "../../../types"; +import { getLogger } from "../../../bindings"; +import { BotContext, Payload } from "../../../types"; import { IssueCommentCommands } from "../commands"; import { closePullRequestForAnIssue } from "../../assign/index"; -export const unassign = async (body: string) => { - const { payload: _payload } = getBotContext(); +export const unassign = async (context: BotContext, body: string) => { + const { payload: _payload } = context; const logger = getLogger(); if (body != IssueCommentCommands.STOP && body.replace(/`/g, "") != IssueCommentCommands.STOP) { logger.info(`Skipping to unassign. body: ${body}`); @@ -28,7 +28,7 @@ export const unassign = async (body: string) => { logger.debug(`Unassigning sender: ${payload.sender.login.toLowerCase()}, assignee: ${assignees[0].login.toLowerCase()}, shouldUnassign: ${shouldUnassign}`); if (shouldUnassign) { - await closePullRequestForAnIssue(); + await closePullRequestForAnIssue(context); await removeAssignees( issue_number, assignees.map((i) => i.login) diff --git a/src/handlers/comment/handlers/wallet.ts b/src/handlers/comment/handlers/wallet.ts index 6cabfd357..f1ea4d6b5 100644 --- a/src/handlers/comment/handlers/wallet.ts +++ b/src/handlers/comment/handlers/wallet.ts @@ -1,8 +1,8 @@ import { ethers } from "ethers"; import { upsertWalletAddress } from "../../../adapters/supabase"; -import { getBotConfig, getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { resolveAddress } from "../../../helpers"; -import { Payload } from "../../../types"; +import { BotContext, Payload } from "../../../types"; import { formatEthAddress } from "../../../utils"; import { IssueCommentCommands } from "../commands"; import { constants } from "ethers"; @@ -22,9 +22,9 @@ const extractEnsName = (text: string): string | undefined => { return undefined; }; -export const registerWallet = async (body: string) => { - const { payload: _payload } = getBotContext(); - const config = getBotConfig(); +export const registerWallet = async (context: BotContext, body: string) => { + const { payload: _payload } = context; + const config = context.botConfig; const logger = getLogger(); const payload = _payload as Payload; const sender = payload.sender.login; diff --git a/src/handlers/issue/pre.ts b/src/handlers/issue/pre.ts index bebda5dce..91d7bbf63 100644 --- a/src/handlers/issue/pre.ts +++ b/src/handlers/issue/pre.ts @@ -1,10 +1,9 @@ import { extractImportantWords, upsertCommentToIssue, measureSimilarity } from "../../helpers"; -import { getBotContext, getLogger } from "../../bindings"; -import { Issue, Payload } from "../../types"; +import { getLogger } from "../../bindings"; +import { BotContext, Issue, Payload } from "../../types"; -export const findDuplicateOne = async () => { +export const findDuplicateOne = async (context: BotContext) => { const logger = getLogger(); - const context = getBotContext(); const payload = context.payload as Payload; const issue = payload.issue; diff --git a/src/handlers/payout/action.ts b/src/handlers/payout/action.ts index 0afe9c424..5e94037d1 100644 --- a/src/handlers/payout/action.ts +++ b/src/handlers/payout/action.ts @@ -1,6 +1,6 @@ import { BigNumber, ethers } from "ethers"; import { getPenalty, getWalletAddress, getWalletMultiplier, removePenalty } from "../../adapters/supabase"; -import { getBotConfig, getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { addLabelToIssue, checkUserPermissionForRepoAndOrg, @@ -14,7 +14,7 @@ import { getAllIssueAssignEvents, addCommentToIssue, } from "../../helpers"; -import { UserType, Payload, StateReason, Comment, User, Incentives, Issue } from "../../types"; +import { UserType, Payload, StateReason, Comment, User, Incentives, Issue, BotContext } from "../../types"; import { shortenEthAddress } from "../../utils"; import { bountyInfo } from "../wildcard"; import Decimal from "decimal.js"; @@ -61,14 +61,13 @@ export interface RewardByUser { * Collect the information required for the permit generation and error handling */ -export const incentivesCalculation = async (): Promise => { - const context = getBotContext(); +export const incentivesCalculation = async (context: BotContext): Promise => { const { payout: { paymentToken, rpc, permitBaseUrl, networkId, privateKey }, mode: { incentiveMode, paymentPermitMaxPrice }, price: { incentives, issueCreatorMultiplier, baseMultiplier }, accessControl, - } = getBotConfig(); + } = context.botConfig; const logger = getLogger(); const payload = context.payload as Payload; const issue = payload.issue; @@ -309,6 +308,7 @@ export const calculateIssueAssigneeReward = async (incentivesCalculation: Incent }; export const handleIssueClosed = async ( + context: BotContext, creatorReward: RewardsResponse, assigneeReward: RewardsResponse, conversationRewards: RewardsResponse, @@ -316,7 +316,7 @@ export const handleIssueClosed = async ( incentivesCalculation: IncentivesCalculationResult ): Promise<{ error: string }> => { const logger = getLogger(); - const { comments } = getBotConfig(); + const { comments } = context.botConfig; const issueNumber = incentivesCalculation.issue.number; let commentersComment = "", diff --git a/src/handlers/payout/post.ts b/src/handlers/payout/post.ts index 18d9aa1df..2f810c95e 100644 --- a/src/handlers/payout/post.ts +++ b/src/handlers/payout/post.ts @@ -1,8 +1,8 @@ import { getWalletAddress } from "../../adapters/supabase"; -import { getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { getAllIssueComments, getAllPullRequestReviews, getIssueDescription, parseComments } from "../../helpers"; import { getLatestPullRequest, gitLinkedPrParser } from "../../helpers/parser"; -import { Incentives, MarkdownItem, Payload, UserType } from "../../types"; +import { BotContext, Incentives, MarkdownItem, Payload, UserType } from "../../types"; import { RewardsResponse, commentParser } from "../comment"; import Decimal from "decimal.js"; import { bountyInfo } from "../wildcard"; @@ -24,11 +24,9 @@ const ItemsToExclude: string[] = [MarkdownItem.BlockQuote]; * Incentivize the contributors based on their contribution. * The default formula has been defined in https://github.com/ubiquity/ubiquibot/issues/272 */ -export const calculateIssueConversationReward = async (calculateIncentives: IncentivesCalculationResult): Promise => { +export const calculateIssueConversationReward = async (context: BotContext, calculateIncentives: IncentivesCalculationResult): Promise => { const title = `Conversation`; const logger = getLogger(); - - const context = getBotContext(); const payload = context.payload as Payload; const issue = payload.issue; @@ -169,9 +167,8 @@ export const calculateIssueCreatorReward = async (incentivesCalculation: Incenti }; }; -export const calculatePullRequestReviewsReward = async (incentivesCalculation: IncentivesCalculationResult): Promise => { +export const calculatePullRequestReviewsReward = async (context: BotContext, incentivesCalculation: IncentivesCalculationResult): Promise => { const logger = getLogger(); - const context = getBotContext(); const title = "Reviewer"; const linkedPullRequest = await gitLinkedPrParser({ diff --git a/src/handlers/pricing/action.ts b/src/handlers/pricing/action.ts index 0b8982eaa..11885b13c 100644 --- a/src/handlers/pricing/action.ts +++ b/src/handlers/pricing/action.ts @@ -1,13 +1,12 @@ -import { getBotConfig, getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { GLOBAL_STRINGS } from "../../configs"; import { addCommentToIssue, addLabelToIssue, clearAllPriceLabelsOnIssue, createLabel, getLabel, calculateWeight } from "../../helpers"; -import { Payload } from "../../types"; +import { BotContext, Payload } from "../../types"; import { handleLabelsAccess } from "../access"; import { getTargetPriceLabel } from "../shared"; -export const pricingLabelLogic = async (): Promise => { - const context = getBotContext(); - const config = getBotConfig(); +export const pricingLabelLogic = async (context: BotContext): Promise => { + const config = context.botConfig; const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue) return; @@ -23,7 +22,7 @@ export const pricingLabelLogic = async (): Promise => { } return; } - const valid = await handleLabelsAccess(); + const valid = await handleLabelsAccess(context); if (!valid && config.accessControl.label) { return; @@ -36,7 +35,7 @@ export const pricingLabelLogic = async (): Promise => { const minTimeLabel = timeLabels.length > 0 ? timeLabels.reduce((a, b) => (calculateWeight(a) < calculateWeight(b) ? a : b)).name : undefined; const minPriorityLabel = priorityLabels.length > 0 ? priorityLabels.reduce((a, b) => (calculateWeight(a) < calculateWeight(b) ? a : b)).name : undefined; - const targetPriceLabel = getTargetPriceLabel(minTimeLabel, minPriorityLabel); + const targetPriceLabel = getTargetPriceLabel(context, minTimeLabel, minPriorityLabel); if (targetPriceLabel) { if (labels.map((i) => i.name).includes(targetPriceLabel)) { logger.info(`Skipping... already exists`); diff --git a/src/handlers/pricing/pre.ts b/src/handlers/pricing/pre.ts index 4d048d1ca..ae80d14de 100644 --- a/src/handlers/pricing/pre.ts +++ b/src/handlers/pricing/pre.ts @@ -1,13 +1,14 @@ -import { getBotConfig, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { calculateWeight, createLabel, listLabelsForRepo } from "../../helpers"; +import { BotContext } from "../../types"; import { calculateBountyPrice } from "../shared"; /** * @dev This just checks all the labels in the config have been set in gh issue * If there's something missing, they will be added */ -export const validatePriceLabels = async (): Promise => { - const config = getBotConfig(); +export const validatePriceLabels = async (context: BotContext): Promise => { + const config = context.botConfig; const logger = getLogger(); const { assistivePricing } = config.mode; diff --git a/src/handlers/pull-request/create-devpool-pr.ts b/src/handlers/pull-request/create-devpool-pr.ts index 08046bfbc..e457af14e 100644 --- a/src/handlers/pull-request/create-devpool-pr.ts +++ b/src/handlers/pull-request/create-devpool-pr.ts @@ -1,10 +1,8 @@ -import { getBotContext, getLogger } from "../../bindings"; -import { GithubContent, Payload } from "../../types"; +import { getLogger } from "../../bindings"; +import { BotContext, GithubContent, Payload } from "../../types"; -export const createDevPoolPR = async () => { +export const createDevPoolPR = async (context: BotContext) => { const logger = getLogger(); - - const context = getBotContext(); const payload = context.payload as Payload; const devPoolOwner = "ubiquity"; diff --git a/src/handlers/push/index.ts b/src/handlers/push/index.ts index 340143439..2d90d1a2d 100644 --- a/src/handlers/push/index.ts +++ b/src/handlers/push/index.ts @@ -1,6 +1,6 @@ -import { getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { createCommitComment, getFileContent } from "../../helpers"; -import { CommitsPayload, PushPayload, WideConfigSchema } from "../../types"; +import { BotContext, CommitsPayload, PushPayload, WideConfigSchema } from "../../types"; import { parseYAML } from "../../utils/private"; import { updateBaseRate } from "./update-base"; import { validate } from "../../utils/ajv"; @@ -22,10 +22,8 @@ function getCommitChanges(commits: CommitsPayload[]) { return changes; } -export const runOnPush = async () => { +export const runOnPush = async (context: BotContext) => { const logger = getLogger(); - - const context = getBotContext(); const payload = context.payload as PushPayload; // if zero sha, push is a pr change @@ -49,10 +47,8 @@ export const runOnPush = async () => { } }; -export const validateConfigChange = async () => { +export const validateConfigChange = async (context: BotContext) => { const logger = getLogger(); - - const context = getBotContext(); const payload = context.payload as PushPayload; if (!payload.ref.startsWith("refs/heads/")) { diff --git a/src/handlers/shared/pricing.ts b/src/handlers/shared/pricing.ts index 0a543bc7c..9671cc08d 100644 --- a/src/handlers/shared/pricing.ts +++ b/src/handlers/shared/pricing.ts @@ -1,22 +1,22 @@ -import { getBotConfig } from "../../bindings"; import { calculateWeight } from "../../helpers"; +import { BotContext } from "../../types"; -export const calculateBountyPrice = (timeValue: number, priorityValue: number, baseValue?: number): number => { - const botConfig = getBotConfig(); +export const calculateBountyPrice = (context: BotContext, timeValue: number, priorityValue: number, baseValue?: number): number => { + const botConfig = context.botConfig; const base = baseValue ?? botConfig.price.baseMultiplier; const priority = priorityValue / 10; // floats cause bad math const price = 1000 * base * timeValue * priority; return price; }; -export const getTargetPriceLabel = (timeLabel: string | undefined, priorityLabel: string | undefined): string | undefined => { - const botConfig = getBotConfig(); +export const getTargetPriceLabel = (context: BotContext, timeLabel: string | undefined, priorityLabel: string | undefined): string | undefined => { + const botConfig = context.botConfig; let targetPriceLabel: string | undefined = undefined; if (timeLabel && priorityLabel) { const timeWeight = calculateWeight(botConfig.price.timeLabels.find((item) => item.name === timeLabel)); const priorityWeight = calculateWeight(botConfig.price.priorityLabels.find((item) => item.name === priorityLabel)); if (timeWeight && priorityWeight) { - const bountyPrice = calculateBountyPrice(timeWeight, priorityWeight); + const bountyPrice = calculateBountyPrice(context, timeWeight, priorityWeight); targetPriceLabel = `Price: ${bountyPrice} USD`; } } diff --git a/src/tests/message-test.ts b/src/tests/message-test.ts index b311f0200..0806eb8ac 100644 --- a/src/tests/message-test.ts +++ b/src/tests/message-test.ts @@ -4,7 +4,7 @@ const chatIds = ["tg1", "tg2", "tg3"]; // SHOULD update chatIds with valid ones export async function messageTests(context: BotContext) { /**@method telegramNotifier - call unformatted issue */ - await telegramNotifier({ + await telegramNotifier(context, { chatIds: chatIds, action: `new issue`, title: `Optimize CI/CD Build Speed`, @@ -12,10 +12,10 @@ export async function messageTests(context: BotContext) { id: `10`, ref: `https://github.com/ubiquity/ubiquity-dollar/issues/10`, user: `pavlovcik`, - }, context); + }); /**@method telegramNotifier - call unformatted pull */ - await telegramNotifier({ + await telegramNotifier(context, { chatIds: chatIds, action: `new pull`, title: `Enhancement/styles`, @@ -23,10 +23,10 @@ export async function messageTests(context: BotContext) { id: `246`, ref: `https://github.com/ubiquity/ubiquity-dollar/pull/246`, user: `pavlovcik`, - }, context); + }); /**@method telegramFormattedNotifier - call formatted issue */ - await telegramFormattedNotifier({ + await telegramFormattedNotifier(context, { chatIds: chatIds, text: `new issue: Optimize CI/CD Build Speed ` + @@ -35,10 +35,10 @@ export async function messageTests(context: BotContext) { `pavlovcik\n` + `I worked through getting the build process to work by force \nmoving all dev dependencies into dependencies, but \nnow the build process is extremely slow on vercel.`, parseMode: "HTML", - }, context); + }); /**@method telegramFormattedNotifier - call formatted pull */ - await telegramFormattedNotifier({ + await telegramFormattedNotifier(context, { chatIds: chatIds, text: `new pull: Enhancement/styles ` + @@ -47,5 +47,5 @@ export async function messageTests(context: BotContext) { `pavlovcik\n` + `Small enhancements but mostly renamed the \ninternal smart contract references, and \nadded support for DAI and USDT in the inventory.`, parseMode: "HTML", - }, context); + }); } From 2f43501ac5032c0eb90cb9d576208b208c768ec3 Mon Sep 17 00:00:00 2001 From: sadaf Date: Wed, 27 Sep 2023 00:31:40 +0530 Subject: [PATCH 4/9] feat(context): - passing context in param for all functions --- src/bindings/event.ts | 4 +- src/handlers/access/labels-access.ts | 6 +- src/handlers/assign/action.ts | 6 +- src/handlers/assign/auto.ts | 2 +- src/handlers/comment/handlers/ask.ts | 10 +-- src/handlers/comment/handlers/assign.ts | 14 ++-- src/handlers/comment/handlers/first.ts | 2 +- src/handlers/comment/handlers/index.ts | 33 ++++---- src/handlers/comment/handlers/payout.ts | 8 +- src/handlers/comment/handlers/unassign.ts | 1 + src/handlers/comment/handlers/wallet.ts | 2 +- src/handlers/issue/pre.ts | 1 + src/handlers/payout/action.ts | 30 +++---- src/handlers/payout/post.ts | 16 ++-- src/handlers/pricing/action.ts | 14 ++-- src/handlers/pricing/pre.ts | 6 +- src/handlers/push/index.ts | 3 +- src/handlers/push/update-base.ts | 11 ++- src/handlers/wildcard/analytics.ts | 20 ++--- src/handlers/wildcard/unassign.ts | 34 ++++---- src/handlers/wildcard/weekly.ts | 10 +-- src/handlers/wildcard/weekly/action.ts | 8 +- src/helpers/commit.ts | 6 +- src/helpers/ens.ts | 7 +- src/helpers/file.ts | 9 +-- src/helpers/gpt.ts | 18 ++--- src/helpers/issue.ts | 96 +++++++++-------------- src/helpers/label.ts | 26 +++--- src/helpers/parser.ts | 6 +- src/helpers/permit.ts | 12 +-- src/helpers/shared.ts | 6 +- src/helpers/user.ts | 10 +-- 32 files changed, 205 insertions(+), 232 deletions(-) diff --git a/src/bindings/event.ts b/src/bindings/event.ts index 32455ff17..0e4ac8442 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -57,7 +57,7 @@ export const bindEvents = async (context: BotContext): Promise => { if (botConfigError) { logger.error(botConfigError.toString()); if (eventName === GithubEvent.PUSH_EVENT) { - await validateConfigChange(); + await validateConfigChange(context); } return; } @@ -95,7 +95,7 @@ export const bindEvents = async (context: BotContext): Promise => { } // Check if we should skip the event - const { skip, reason } = shouldSkip(); + const { skip, reason } = shouldSkip(context); if (skip) { logger.info(`Skipping the event. reason: ${reason}`); return; diff --git a/src/handlers/access/labels-access.ts b/src/handlers/access/labels-access.ts index 83a4a4fae..4b2b4d9a5 100644 --- a/src/handlers/access/labels-access.ts +++ b/src/handlers/access/labels-access.ts @@ -33,12 +33,12 @@ export const handleLabelsAccess = async (context: BotContext) => { if (payload.action === "labeled") { // remove the label - await removeLabel(labelName); + await removeLabel(context, labelName); } else if (payload.action === "unlabeled") { // add the label - await addLabelToIssue(labelName); + await addLabelToIssue(context, labelName); } - await addCommentToIssue(`@${sender}, You are not allowed to ${eventName} ${labelName}`, payload.issue.number); + await addCommentToIssue(context, `@${sender}, You are not allowed to ${eventName} ${labelName}`, payload.issue.number); logger.info(`@${sender} is not allowed to ${eventName} ${labelName}`); return false; } diff --git a/src/handlers/assign/action.ts b/src/handlers/assign/action.ts index 7540e918d..c00f9a475 100644 --- a/src/handlers/assign/action.ts +++ b/src/handlers/assign/action.ts @@ -63,7 +63,7 @@ export const commentWithAssignMessage = async (context: BotContext): Promise => { @@ -82,8 +82,8 @@ export const closePullRequestForAnIssue = async (context: BotContext): Promise#${prs[i].prNumber} `; } - await addCommentToIssue(comment, payload.issue.number); + await addCommentToIssue(context, comment, payload.issue.number); }; diff --git a/src/handlers/assign/auto.ts b/src/handlers/assign/auto.ts index 4f6523fac..2e4a6fcf6 100644 --- a/src/handlers/assign/auto.ts +++ b/src/handlers/assign/auto.ts @@ -52,7 +52,7 @@ export const checkPullRequests = async (context: BotContext) => { const assignedUsernames = issue.assignees.map((assignee) => assignee.login); if (!assignedUsernames.includes(opener)) { - await addAssignees(+linkedIssueNumber, [opener]); + await addAssignees(context, +linkedIssueNumber, [opener]); logger.debug(`Assigned pull request #${pull.number} opener to issue ${linkedIssueNumber}.`); } } diff --git a/src/handlers/comment/handlers/ask.ts b/src/handlers/comment/handlers/ask.ts index 6520985d4..e48d80ba6 100644 --- a/src/handlers/comment/handlers/ask.ts +++ b/src/handlers/comment/handlers/ask.ts @@ -35,9 +35,9 @@ export const ask = async (context: BotContext, body: string) => { const [, body] = matches; // standard comments - const comments = await getAllIssueComments(issue.number); + const comments = await getAllIssueComments(context, issue.number); // raw so we can grab the tag - const commentsRaw = await getAllIssueComments(issue.number, "raw"); + const commentsRaw = await getAllIssueComments(context, issue.number, "raw"); if (!comments) { logger.info(`Error getting issue comments`); @@ -61,7 +61,7 @@ export const ask = async (context: BotContext, body: string) => { }); // returns the conversational context from all linked issues and prs - const links = await getAllLinkedIssuesAndPullsInBody(issue.number); + const links = await getAllLinkedIssuesAndPullsInBody(context, issue.number); if (typeof links === "string") { logger.info(`Error getting linked issues or prs: ${links}`); @@ -71,7 +71,7 @@ export const ask = async (context: BotContext, body: string) => { } // let chatgpt deduce what is the most relevant context - const gptDecidedContext = await decideContextGPT(chatHistory, streamlined, linkedPRStreamlined, linkedIssueStreamlined); + const gptDecidedContext = await decideContextGPT(context, chatHistory, streamlined, linkedPRStreamlined, linkedIssueStreamlined); if (linkedIssueStreamlined.length == 0 && linkedPRStreamlined.length == 0) { // No external context to add @@ -107,7 +107,7 @@ export const ask = async (context: BotContext, body: string) => { ); } - const gptResponse = await askGPT(body, chatHistory); + const gptResponse = await askGPT(context, body, chatHistory); if (typeof gptResponse === "string") { return gptResponse; diff --git a/src/handlers/comment/handlers/assign.ts b/src/handlers/comment/handlers/assign.ts index 87cbeb622..7cd6d8aec 100644 --- a/src/handlers/comment/handlers/assign.ts +++ b/src/handlers/comment/handlers/assign.ts @@ -38,10 +38,10 @@ export const assign = async (context: BotContext, body: string) => { return GLOBAL_STRINGS.ignoreStartCommandForParentIssueComment; } - const openedPullRequests = await getAvailableOpenedPullRequests(payload.sender.login); + const openedPullRequests = await getAvailableOpenedPullRequests(context, payload.sender.login); logger.info(`Opened Pull Requests with approved reviews or with no reviews but over 24 hours have passed: ${JSON.stringify(openedPullRequests)}`); - const assignedIssues = await getAssignedIssues(payload.sender.login); + const assignedIssues = await getAssignedIssues(context, payload.sender.login); logger.info(`Max issue allowed is ${config.assign.bountyHunterMax}`); // check for max and enforce max @@ -109,7 +109,7 @@ export const assign = async (context: BotContext, body: string) => { if (!assignees.map((i) => i.login).includes(payload.sender.login)) { logger.info(`Adding the assignee: ${payload.sender.login}`); - await addAssignees(issue.number, [payload.sender.login]); + await addAssignees(context, issue.number, [payload.sender.login]); } let days: number | undefined; @@ -124,17 +124,17 @@ export const assign = async (context: BotContext, body: string) => { // double check whether the assign message has been already posted or not logger.info(`Creating an issue comment: ${comment.commit}`); - const issueComments = await getAllIssueComments(issue.number); + const issueComments = await getAllIssueComments(context, issue.number); const comments = issueComments.sort((a: Comment, b: Comment) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); const latestComment = comments.length > 0 ? comments[0].body : undefined; if (latestComment && comment.commit != latestComment) { - const { multiplier, reason, bounty } = await getMultiplierInfoToDisplay(payload.sender.login, id?.toString(), issue); + const { multiplier, reason, bounty } = await getMultiplierInfoToDisplay(context, payload.sender.login, id?.toString(), issue); return tableComment({ ...comment, multiplier, reason, bounty, isBountyStale, days }) + comment.tips; } return; }; -const getMultiplierInfoToDisplay = async (senderLogin: string, org_id: string, issue: Issue) => { +const getMultiplierInfoToDisplay = async (context: BotContext, senderLogin: string, org_id: string, issue: Issue) => { const { reason, value } = await getWalletMultiplier(senderLogin, org_id); const multiplier = value?.toFixed(2) || "1.00"; @@ -153,7 +153,7 @@ const getMultiplierInfoToDisplay = async (senderLogin: string, org_id: string, i _multiplierToDisplay = multiplier; _reasonToDisplay = reason; _bountyToDisplay = `Permit generation disabled because price label is not set.`; - const issueDetailed = bountyInfo(issue); + const issueDetailed = bountyInfo(context, issue); if (issueDetailed.priceLabel) { _bountyToDisplay = (+issueDetailed.priceLabel.substring(7, issueDetailed.priceLabel.length - 4) * value).toString() + " USD"; } diff --git a/src/handlers/comment/handlers/first.ts b/src/handlers/comment/handlers/first.ts index 30fa196ff..c2bf354c8 100644 --- a/src/handlers/comment/handlers/first.ts +++ b/src/handlers/comment/handlers/first.ts @@ -41,7 +41,7 @@ export const verifyFirstCheck = async (context: BotContext): Promise => { if (footer) { msg += `${footer}`; } - await upsertCommentToIssue(payload.issue.number, msg, payload.action, payload.comment); + await upsertCommentToIssue(context, payload.issue.number, msg, payload.action, payload.comment); } } } catch (error: unknown) { diff --git a/src/handlers/comment/handlers/index.ts b/src/handlers/comment/handlers/index.ts index d84eb974c..6d0b1d6a6 100644 --- a/src/handlers/comment/handlers/index.ts +++ b/src/handlers/comment/handlers/index.ts @@ -96,10 +96,10 @@ export const issueClosedCallback = async (context: BotContext): Promise => // assign function incentivesCalculation to a variable const calculateIncentives = await incentivesCalculation(context); - const creatorReward = await calculateIssueCreatorReward(calculateIncentives); + const creatorReward = await calculateIssueCreatorReward(context, calculateIncentives); const assigneeReward = await calculateIssueAssigneeReward(calculateIncentives); - const conversationRewards = await calculateIssueConversationReward(calculateIncentives); - const pullRequestReviewersReward = await calculatePullRequestReviewsReward(calculateIncentives); + const conversationRewards = await calculateIssueConversationReward(context, calculateIncentives); + const pullRequestReviewersReward = await calculatePullRequestReviewsReward(context, calculateIncentives); const { error } = await handleIssueClosed(context, creatorReward, assigneeReward, conversationRewards, pullRequestReviewersReward, calculateIncentives); @@ -107,7 +107,7 @@ export const issueClosedCallback = async (context: BotContext): Promise => throw new Error(error); } } catch (err: unknown) { - return await addCommentToIssue(ErrorDiff(err), issue.number); + return await addCommentToIssue(context, ErrorDiff(err), issue.number); } }; @@ -138,17 +138,17 @@ export const issueCreatedCallback = async (context: BotContext): Promise = timeLabels.length > 0 ? timeLabels.reduce((a, b) => (calculateWeight(a) < calculateWeight(b) ? a : b)).name : config.price.defaultLabels[0]; const minPriorityLabel = priorityLabels.length > 0 ? priorityLabels.reduce((a, b) => (calculateWeight(a) < calculateWeight(b) ? a : b)).name : config.price.defaultLabels[1]; - if (!timeLabels.length) await addLabelToIssue(minTimeLabel); - if (!priorityLabels.length) await addLabelToIssue(minPriorityLabel); + if (!timeLabels.length) await addLabelToIssue(context, minTimeLabel); + if (!priorityLabels.length) await addLabelToIssue(context, minPriorityLabel); - const targetPriceLabel = getTargetPriceLabel(minTimeLabel, minPriorityLabel); + const targetPriceLabel = getTargetPriceLabel(context, minTimeLabel, minPriorityLabel); if (targetPriceLabel && !labels.map((i) => i.name).includes(targetPriceLabel)) { - const exist = await getLabel(targetPriceLabel); - if (!exist) await createLabel(targetPriceLabel, "price"); - await addLabelToIssue(targetPriceLabel); + const exist = await getLabel(context, targetPriceLabel); + if (!exist) await createLabel(context, targetPriceLabel, "price"); + await addLabelToIssue(context, targetPriceLabel); } } catch (err: unknown) { - await addCommentToIssue(ErrorDiff(err), issue.number); + await addCommentToIssue(context, ErrorDiff(err), issue.number); } }; @@ -167,7 +167,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise if (!issue) return; try { // find permit comment from the bot - const comments = await getAllIssueComments(issue.number); + const comments = await getAllIssueComments(context, issue.number); const claimUrlRegex = new RegExp(`\\((${permitBaseUrl}\\?claim=\\S+)\\)`); const permitCommentIdx = comments.findIndex((e) => e.user.type === "Bot" && e.body.match(claimUrlRegex)); if (permitCommentIdx === -1) { @@ -205,7 +205,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise const tokenSymbol = await getTokenSymbol(tokenAddress, rpc); // find latest assignment before the permit comment - const events = await getAllIssueAssignEvents(issue.number); + const events = await getAllIssueAssignEvents(context, issue.number); if (events.length === 0) { logger.error(`No assignment found`); return; @@ -222,6 +222,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise } await addCommentToIssue( + context, `@${assignee} please be sure to review this conversation and implement any necessary fixes. Unless this is closed as completed, its payment of **${formattedAmount} ${tokenSymbol}** will be deducted from your next bounty.`, issue.number ); @@ -229,7 +230,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise logger.info(`Skipped penalty because amount is 0`); } } catch (err: unknown) { - await addCommentToIssue(ErrorDiff(err), issue.number); + await addCommentToIssue(context, ErrorDiff(err), issue.number); } }; @@ -241,8 +242,8 @@ export const issueReopenedCallback = async (context: BotContext): Promise * @param comment - Comment string */ -const commandCallback = async (issue_number: number, comment: string, action: string, reply_to?: Comment) => { - await upsertCommentToIssue(issue_number, comment, action, reply_to); +const commandCallback = async (context: BotContext ,issue_number: number, comment: string, action: string, reply_to?: Comment) => { + await upsertCommentToIssue(context, issue_number, comment, action, reply_to); }; export const userCommands = (context: BotContext): UserCommands[] => { diff --git a/src/handlers/comment/handlers/payout.ts b/src/handlers/comment/handlers/payout.ts index e53b53858..24178363e 100644 --- a/src/handlers/comment/handlers/payout.ts +++ b/src/handlers/comment/handlers/payout.ts @@ -34,7 +34,7 @@ export const payout = async (context: BotContext, body: string) => { return; } - const IssueComments = await getAllIssueComments(issue.number); + const IssueComments = await getAllIssueComments(context, issue.number); if (IssueComments.length === 0) { return `Permit generation failed due to internal GitHub Error`; } @@ -48,10 +48,10 @@ export const payout = async (context: BotContext, body: string) => { // assign function incentivesCalculation to a variable const calculateIncentives = await incentivesCalculation(context); - const creatorReward = await calculateIssueCreatorReward(calculateIncentives); + const creatorReward = await calculateIssueCreatorReward(context, calculateIncentives); const assigneeReward = await calculateIssueAssigneeReward(calculateIncentives); - const conversationRewards = await calculateIssueConversationReward(calculateIncentives); - const pullRequestReviewersReward = await calculatePullRequestReviewsReward(calculateIncentives); + const conversationRewards = await calculateIssueConversationReward(context, calculateIncentives); + const pullRequestReviewersReward = await calculatePullRequestReviewsReward(context, calculateIncentives); return await handleIssueClosed(context, creatorReward, assigneeReward, conversationRewards, pullRequestReviewersReward, calculateIncentives); }; diff --git a/src/handlers/comment/handlers/unassign.ts b/src/handlers/comment/handlers/unassign.ts index 172639891..e1cdcbc4f 100644 --- a/src/handlers/comment/handlers/unassign.ts +++ b/src/handlers/comment/handlers/unassign.ts @@ -30,6 +30,7 @@ export const unassign = async (context: BotContext, body: string) => { if (shouldUnassign) { await closePullRequestForAnIssue(context); await removeAssignees( + context, issue_number, assignees.map((i) => i.login) ); diff --git a/src/handlers/comment/handlers/wallet.ts b/src/handlers/comment/handlers/wallet.ts index f1ea4d6b5..1f2eeb144 100644 --- a/src/handlers/comment/handlers/wallet.ts +++ b/src/handlers/comment/handlers/wallet.ts @@ -44,7 +44,7 @@ export const registerWallet = async (context: BotContext, body: string) => { if (!address && ensName) { logger.info(`Trying to resolve address from Ens name: ${ensName}`); - address = await resolveAddress(ensName); + address = await resolveAddress(context, ensName); if (!address) { logger.info(`Resolving address from Ens name failed, EnsName: ${ensName}`); return `Resolving address from Ens name failed, Try again`; diff --git a/src/handlers/issue/pre.ts b/src/handlers/issue/pre.ts index 91d7bbf63..06f3cc93b 100644 --- a/src/handlers/issue/pre.ts +++ b/src/handlers/issue/pre.ts @@ -30,6 +30,7 @@ export const findDuplicateOne = async (context: BotContext) => { const similarity = await measureSimilarity(issue, result as Issue); if (similarity > parseInt(process.env.SIMILARITY_THRESHOLD || "80")) { await upsertCommentToIssue( + context, issue.number, `Similar issue (${result.title}) found at ${result.html_url}.\nSimilarity is about ${similarity}%`, "created" diff --git a/src/handlers/payout/action.ts b/src/handlers/payout/action.ts index 5e94037d1..09c0a00fa 100644 --- a/src/handlers/payout/action.ts +++ b/src/handlers/payout/action.ts @@ -87,9 +87,9 @@ export const incentivesCalculation = async (context: BotContext): Promise e.user.type === UserType.Bot && e.body.match(claimUrlRegex)); @@ -121,7 +121,7 @@ export const incentivesCalculation = async (context: BotContext): Promise = {}; for (const issueComment of issueComments) { @@ -100,17 +100,17 @@ export const calculateIssueConversationReward = async (context: BotContext, calc return { error: "", title, reward, fallbackReward }; }; -export const calculateIssueCreatorReward = async (incentivesCalculation: IncentivesCalculationResult): Promise => { +export const calculateIssueCreatorReward = async (context: BotContext, incentivesCalculation: IncentivesCalculationResult): Promise => { const title = `Task Creator`; const logger = getLogger(); - const issueDetailed = bountyInfo(incentivesCalculation.issue); + const issueDetailed = bountyInfo(context, incentivesCalculation.issue); if (!issueDetailed.isBounty) { logger.info(`incentivizeCreatorComment: its not a bounty`); return { error: `incentivizeCreatorComment: its not a bounty` }; } - const comments = await getAllIssueComments(incentivesCalculation.issue.number); + const comments = await getAllIssueComments(context, incentivesCalculation.issue.number); const permitComments = comments.filter( (content) => content.body.includes(title) && content.body.includes("https://pay.ubq.fi?claim=") && content.user.type == UserType.Bot ); @@ -126,7 +126,7 @@ export const calculateIssueCreatorReward = async (incentivesCalculation: Incenti return { error: "incentivizeCreatorComment: skipping payment permit generation because `assignee` is `undefined`." }; } - const description = await getIssueDescription(incentivesCalculation.issue.number, "html"); + const description = await getIssueDescription(context, incentivesCalculation.issue.number, "html"); if (!description) { logger.info(`Skipping to generate a permit url because issue description is empty. description: ${description}`); return { error: `Skipping to generate a permit url because issue description is empty. description: ${description}` }; @@ -177,14 +177,14 @@ export const calculatePullRequestReviewsReward = async (context: BotContext, inc issue_number: incentivesCalculation.issue.number, }); - const latestLinkedPullRequest = await getLatestPullRequest(linkedPullRequest); + const latestLinkedPullRequest = await getLatestPullRequest(context, linkedPullRequest); if (!latestLinkedPullRequest) { logger.debug(`calculatePullRequestReviewsReward: No linked pull requests found`); return { error: `calculatePullRequestReviewsReward: No linked pull requests found` }; } - const comments = await getAllIssueComments(incentivesCalculation.issue.number); + const comments = await getAllIssueComments(context, incentivesCalculation.issue.number); const permitComments = comments.filter( (content) => content.body.includes(title) && content.body.includes("https://pay.ubq.fi?claim=") && content.user.type == UserType.Bot ); @@ -201,7 +201,7 @@ export const calculatePullRequestReviewsReward = async (context: BotContext, inc } const prReviews = await getAllPullRequestReviews(context, latestLinkedPullRequest.number, "full"); - const prComments = await getAllIssueComments(latestLinkedPullRequest.number, "full"); + const prComments = await getAllIssueComments(context, latestLinkedPullRequest.number, "full"); logger.info(`Getting the PR reviews done. comments: ${JSON.stringify(prReviews)}`); const prReviewsByUser: Record = {}; for (const review of prReviews) { diff --git a/src/handlers/pricing/action.ts b/src/handlers/pricing/action.ts index 11885b13c..3077e16f9 100644 --- a/src/handlers/pricing/action.ts +++ b/src/handlers/pricing/action.ts @@ -17,8 +17,8 @@ export const pricingLabelLogic = async (context: BotContext): Promise => { logger.error("Identified as parent issue. Disabling price label."); const issuePrices = labels.filter((label) => label.name.toString().startsWith("Price:")); if (issuePrices.length) { - await addCommentToIssue(GLOBAL_STRINGS.skipPriceLabelGenerationComment, payload.issue.number); - await clearAllPriceLabelsOnIssue(); + await addCommentToIssue(context, GLOBAL_STRINGS.skipPriceLabelGenerationComment, payload.issue.number); + await clearAllPriceLabelsOnIssue(context); } return; } @@ -41,18 +41,18 @@ export const pricingLabelLogic = async (context: BotContext): Promise => { logger.info(`Skipping... already exists`); } else { logger.info(`Adding price label to issue`); - await clearAllPriceLabelsOnIssue(); + await clearAllPriceLabelsOnIssue(context); - const exist = await getLabel(targetPriceLabel); + const exist = await getLabel(context, targetPriceLabel); if (assistivePricing && !exist) { logger.info(`${targetPriceLabel} doesn't exist on the repo, creating...`); - await createLabel(targetPriceLabel, "price"); + await createLabel(context, targetPriceLabel, "price"); } - await addLabelToIssue(targetPriceLabel); + await addLabelToIssue(context, targetPriceLabel); } } else { - await clearAllPriceLabelsOnIssue(); + await clearAllPriceLabelsOnIssue(context); logger.info(`Skipping action...`); } }; diff --git a/src/handlers/pricing/pre.ts b/src/handlers/pricing/pre.ts index ae80d14de..a0ff03186 100644 --- a/src/handlers/pricing/pre.ts +++ b/src/handlers/pricing/pre.ts @@ -23,7 +23,7 @@ export const validatePriceLabels = async (context: BotContext): Promise => const aiLabels: string[] = []; for (const timeLabel of config.price.timeLabels) { for (const priorityLabel of config.price.priorityLabels) { - const targetPrice = calculateBountyPrice(calculateWeight(timeLabel), calculateWeight(priorityLabel), config.price.baseMultiplier); + const targetPrice = calculateBountyPrice(context, calculateWeight(timeLabel), calculateWeight(priorityLabel), config.price.baseMultiplier); const targetPriceLabel = `Price: ${targetPrice} USD`; aiLabels.push(targetPriceLabel); } @@ -33,7 +33,7 @@ export const validatePriceLabels = async (context: BotContext): Promise => logger.debug(`Got needed labels for setting up price, neededLabels: ${neededLabels.toString()}`); // List all the labels for a repository - const repoLabels = await listLabelsForRepo(); + const repoLabels = await listLabelsForRepo(context); // Get the missing labels const missingLabels = neededLabels.filter((label) => !repoLabels.map((i) => i.name).includes(label)); @@ -41,7 +41,7 @@ export const validatePriceLabels = async (context: BotContext): Promise => // Create missing labels if (missingLabels.length > 0) { logger.info(`Creating missing labels: ${missingLabels}`); - await Promise.all(missingLabels.map((label) => createLabel(label))); + await Promise.all(missingLabels.map((label) => createLabel(context, label))); logger.info(`Creating missing labels done`); } }; diff --git a/src/handlers/push/index.ts b/src/handlers/push/index.ts index 2d90d1a2d..a244088a6 100644 --- a/src/handlers/push/index.ts +++ b/src/handlers/push/index.ts @@ -73,6 +73,7 @@ export const validateConfigChange = async (context: BotContext) => { } const configFileContent = await getFileContent( + context, payload.repository.owner.login, payload.repository.name, payload.ref.split("refs/heads/")[1], @@ -85,7 +86,7 @@ export const validateConfigChange = async (context: BotContext) => { const config = parseYAML(decodedConfig); const { valid, error } = validate(WideConfigSchema, config); if (!valid) { - await createCommitComment(`@${payload.sender.login} Config validation failed! ${error}`, commitSha, BASE_RATE_FILE); + await createCommitComment(context, `@${payload.sender.login} Config validation failed! ${error}`, commitSha, BASE_RATE_FILE); } } } diff --git a/src/handlers/push/update-base.ts b/src/handlers/push/update-base.ts index da67c8e6c..354f9acf6 100644 --- a/src/handlers/push/update-base.ts +++ b/src/handlers/push/update-base.ts @@ -1,10 +1,9 @@ -import { Context } from "probot"; import { getLogger } from "../../bindings"; import { getPreviousFileContent, listLabelsForRepo, updateLabelsFromBaseRate } from "../../helpers"; -import { Label, PushPayload } from "../../types"; +import { BotContext, Label, PushPayload } from "../../types"; import { parseYAML } from "../../utils/private"; -export const updateBaseRate = async (context: Context, payload: PushPayload, filePath: string) => { +export const updateBaseRate = async (context: BotContext, payload: PushPayload, filePath: string) => { const logger = getLogger(); // Get default branch from ref const branch = payload.ref?.split("refs/heads/")[1]; @@ -12,7 +11,7 @@ export const updateBaseRate = async (context: Context, payload: PushPayload, fil const repo = payload.repository.name; // get previous config - const preFileContent = await getPreviousFileContent(owner, repo, branch, filePath); + const preFileContent = await getPreviousFileContent(context, owner, repo, branch, filePath); if (!preFileContent) { logger.debug("Getting previous file content failed"); @@ -29,12 +28,12 @@ export const updateBaseRate = async (context: Context, payload: PushPayload, fil const previousBaseRate = previousConfig["priceMultiplier"]; // fetch all labels - const repoLabels = await listLabelsForRepo(); + const repoLabels = await listLabelsForRepo(context); if (repoLabels.length === 0) { logger.debug("No labels on this repo"); return; } - await updateLabelsFromBaseRate(owner, repo, context, repoLabels as Label[], previousBaseRate); + await updateLabelsFromBaseRate(context, owner, repo, repoLabels as Label[], previousBaseRate); }; diff --git a/src/handlers/wildcard/analytics.ts b/src/handlers/wildcard/analytics.ts index 62f24edf9..9955142e2 100644 --- a/src/handlers/wildcard/analytics.ts +++ b/src/handlers/wildcard/analytics.ts @@ -1,7 +1,7 @@ import { getMaxIssueNumber, upsertIssue, upsertUser } from "../../adapters/supabase"; -import { getBotConfig, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { listIssuesForRepo, getUser, calculateWeight } from "../../helpers"; -import { Issue, IssueType, User, UserProfile } from "../../types"; +import { BotContext, Issue, IssueType, User, UserProfile } from "../../types"; import { getTargetPriceLabel } from "../shared"; /** @@ -9,7 +9,7 @@ import { getTargetPriceLabel } from "../shared"; * @param issue - The issue object * @returns If bounty - true, If issue - false */ -export const bountyInfo = ( +export const bountyInfo = (context: BotContext, issue: Issue ): { isBounty: boolean; @@ -17,7 +17,7 @@ export const bountyInfo = ( priorityLabel: string | undefined; priceLabel: string | undefined; } => { - const config = getBotConfig(); + const config = context.botConfig; const labels = issue.labels; const timeLabels = config.price.timeLabels.filter((item) => labels.map((i) => i.name).includes(item.name)); const priorityLabels = config.price.priorityLabels.filter((item) => labels.map((i) => i.name).includes(item.name)); @@ -27,7 +27,7 @@ export const bountyInfo = ( const minTimeLabel = timeLabels.length > 0 ? timeLabels.reduce((a, b) => (calculateWeight(a) < calculateWeight(b) ? a : b)).name : undefined; const minPriorityLabel = priorityLabels.length > 0 ? priorityLabels.reduce((a, b) => (calculateWeight(a) < calculateWeight(b) ? a : b)).name : undefined; - const priceLabel = getTargetPriceLabel(minTimeLabel, minPriorityLabel); + const priceLabel = getTargetPriceLabel(context, minTimeLabel, minPriorityLabel); return { isBounty, @@ -40,11 +40,11 @@ export const bountyInfo = ( /** * Collects all the analytics information by scanning the issues opened | closed */ -export const collectAnalytics = async (): Promise => { +export const collectAnalytics = async (context: BotContext): Promise => { const logger = getLogger(); const { mode: { disableAnalytics }, - } = getBotConfig(); + } = context.botConfig; if (disableAnalytics) { logger.info(`Skipping to collect analytics, reason: mode=${disableAnalytics}`); return; @@ -56,12 +56,12 @@ export const collectAnalytics = async (): Promise => { const perPage = 30; let curPage = 1; while (!fetchDone) { - const issues = await listIssuesForRepo(IssueType.ALL, perPage, curPage); + const issues = await listIssuesForRepo(context, IssueType.ALL, perPage, curPage); // need to skip checking the closed issues already stored in the db and filter them by doing a sanitation checks. // sanitation checks would be basically checking labels of the issue // whether the issue has both `priority` label and `timeline` label - const bounties = issues.filter((issue) => bountyInfo(issue as Issue).isBounty); + const bounties = issues.filter((issue) => bountyInfo(context, issue as Issue).isBounty); // collect assignees from both type of issues (opened/closed) const assignees = bounties.filter((bounty) => bounty.assignee).map((bounty) => bounty.assignee as User); @@ -90,7 +90,7 @@ export const collectAnalytics = async (): Promise => { logger.info(`Upserting bounties: ${bountiesToUpsert.map((i) => i.title).toString()}`); await Promise.all( bountiesToUpsert.map((i) => { - const additions = bountyInfo(i as Issue); + const additions = bountyInfo(context, i as Issue); if (additions.timelabel && additions.priorityLabel && additions.priceLabel) return upsertIssue(i as Issue, { labels: { diff --git a/src/handlers/wildcard/unassign.ts b/src/handlers/wildcard/unassign.ts index ec057ce73..7f3480717 100644 --- a/src/handlers/wildcard/unassign.ts +++ b/src/handlers/wildcard/unassign.ts @@ -1,4 +1,4 @@ -import { getBotConfig, getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { GLOBAL_STRINGS } from "../../configs/strings"; import { addCommentToIssue, @@ -9,39 +9,38 @@ import { listAllIssuesForRepo, removeAssignees, } from "../../helpers"; -import { Comment, Issue, IssueType, Payload, UserType } from "../../types"; +import { BotContext, Comment, Issue, IssueType, Payload, UserType } from "../../types"; import { deadLinePrefix } from "../shared"; /** * @dev Check out the bounties which haven't been completed within the initial timeline * and try to release the bounty back to dev pool */ -export const checkBountiesToUnassign = async () => { +export const checkBountiesToUnassign = async (context: BotContext) => { const logger = getLogger(); logger.info(`Getting all the issues...`); // List all the issues in the repository. It may include `pull_request` // because GitHub's REST API v3 considers every pull request an issue - const issues_opened = await listAllIssuesForRepo(IssueType.OPEN); + const issues_opened = await listAllIssuesForRepo(context, IssueType.OPEN); const assigned_issues = issues_opened.filter((issue) => issue.assignee); // Checking the bounties in parallel - const res = await Promise.all(assigned_issues.map(async (issue) => checkBountyToUnassign(issue as Issue))); + const res = await Promise.all(assigned_issues.map(async (issue) => checkBountyToUnassign(context, issue as Issue))); logger.info(`Checking expired bounties done! total: ${res.length}, unassigned: ${res.filter((i) => i).length}`); }; -const checkBountyToUnassign = async (issue: Issue): Promise => { - const context = getBotContext(); +const checkBountyToUnassign = async (context: BotContext, issue: Issue): Promise => { const payload = context.payload as Payload; const logger = getLogger(); const { unassign: { followUpTime, disqualifyTime }, - } = getBotConfig(); + } = context.botConfig; logger.info(`Checking the bounty to unassign, issue_number: ${issue.number}`); const { unassignComment, askUpdate } = GLOBAL_STRINGS; const assignees = issue.assignees.map((i) => i.login); - const comments = await getAllIssueComments(issue.number); + const comments = await getAllIssueComments(context, issue.number); if (!comments || comments.length == 0) return false; const askUpdateComments = comments @@ -50,9 +49,9 @@ const checkBountyToUnassign = async (issue: Issue): Promise => { const lastAskTime = askUpdateComments.length > 0 ? new Date(askUpdateComments[0].created_at).getTime() : new Date(issue.created_at).getTime(); const curTimestamp = new Date().getTime(); - const lastActivity = await lastActivityTime(issue, comments); + const lastActivity = await lastActivityTime(context, issue, comments); const passedDuration = curTimestamp - lastActivity.getTime(); - const pullRequest = await getOpenedPullRequestsForAnIssue(issue.number, issue.assignee.login); + const pullRequest = await getOpenedPullRequestsForAnIssue(context, issue.number, issue.assignee.login); if (pullRequest.length > 0) { const reviewRequests = await getReviewRequests(context, pullRequest[0].number, payload.repository.owner.login, payload.repository.name); @@ -67,8 +66,8 @@ const checkBountyToUnassign = async (issue: Issue): Promise => { `Unassigning... lastActivityTime: ${lastActivity.getTime()}, curTime: ${curTimestamp}, passedDuration: ${passedDuration}, followUpTime: ${followUpTime}, disqualifyTime: ${disqualifyTime}` ); // remove assignees from the issue - await removeAssignees(issue.number, assignees); - await addCommentToIssue(`@${assignees[0]} - ${unassignComment} \nLast activity time: ${lastActivity}`, issue.number); + await removeAssignees(context, issue.number, assignees); + await addCommentToIssue(context, `@${assignees[0]} - ${unassignComment} \nLast activity time: ${lastActivity}`, issue.number); return true; } else if (passedDuration >= followUpTime) { @@ -82,6 +81,7 @@ const checkBountyToUnassign = async (issue: Issue): Promise => { ); } else { await addCommentToIssue( + context, `${askUpdate} @${assignees[0]}? If you would like to release the bounty back to the DevPool, please comment \`/stop\` \nLast activity time: ${lastActivity}`, issue.number ); @@ -92,7 +92,7 @@ const checkBountyToUnassign = async (issue: Issue): Promise => { return false; }; -const lastActivityTime = async (issue: Issue, comments: Comment[]): Promise => { +const lastActivityTime = async (context: BotContext,issue: Issue, comments: Comment[]): Promise => { const logger = getLogger(); logger.info(`Checking the latest activity for the issue, issue_number: ${issue.number}`); const assignees = issue.assignees.map((i) => i.login); @@ -110,14 +110,14 @@ const lastActivityTime = async (issue: Issue, comments: Comment[]): Promise 0) activities.push(new Date(lastCommentsOfHunterForIssue[0].created_at)); - const openedPrsForIssue = await getOpenedPullRequestsForAnIssue(issue.number, assignees[0]); + const openedPrsForIssue = await getOpenedPullRequestsForAnIssue(context, issue.number, assignees[0]); const pr = openedPrsForIssue.length > 0 ? openedPrsForIssue[0] : undefined; // get last commit and last comment on the linked pr if (pr) { - const commits = (await getCommitsOnPullRequest(pr.number)) + const commits = (await getCommitsOnPullRequest(context, pr.number)) .filter((it) => it.commit.committer?.date) .sort((a, b) => new Date(b.commit.committer?.date ?? 0).getTime() - new Date(a.commit.committer?.date ?? 0).getTime()); - const prComments = (await getAllIssueComments(pr.number)) + const prComments = (await getAllIssueComments(context, pr.number)) .filter((comment) => comment.user.login === assignees[0]) .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); diff --git a/src/handlers/wildcard/weekly.ts b/src/handlers/wildcard/weekly.ts index 8d9dbdc70..be13e83f2 100644 --- a/src/handlers/wildcard/weekly.ts +++ b/src/handlers/wildcard/weekly.ts @@ -1,14 +1,14 @@ import { run } from "./weekly/action"; import { getLastWeeklyTime, updateLastWeeklyTime } from "../../adapters/supabase"; -import { getBotConfig, getBotContext } from "../../bindings"; +import { BotContext } from "../../types"; const SEVEN_DAYS = 7 * 24 * 60 * 60 * 1000; // 7 days in milliseconds -export const checkWeeklyUpdate = async () => { - const { log } = getBotContext(); +export const checkWeeklyUpdate = async (context: BotContext) => { + const { log } = context; const { mode: { disableAnalytics }, - } = getBotConfig(); + } = context.botConfig; if (disableAnalytics) { log.info(`Skipping to collect the weekly analytics, reason: mode=${disableAnalytics}`); return; @@ -16,7 +16,7 @@ export const checkWeeklyUpdate = async () => { const curTime = new Date(); const lastTime = await getLastWeeklyTime(); if (lastTime == undefined || new Date(lastTime.getTime() + SEVEN_DAYS) < curTime) { - await run(); + await run(context); await updateLastWeeklyTime(curTime); } else { log.info(`Skipping to collect the weekly analytics because 7 days have not passed`); diff --git a/src/handlers/wildcard/weekly/action.ts b/src/handlers/wildcard/weekly/action.ts index 09e06e878..cb4ba0f6f 100644 --- a/src/handlers/wildcard/weekly/action.ts +++ b/src/handlers/wildcard/weekly/action.ts @@ -6,10 +6,9 @@ import path from "path"; import axios from "axios"; import Jimp from "jimp"; import nodeHtmlToImage from "node-html-to-image"; -import { getBotConfig, getBotContext } from "../../../bindings"; import { telegramPhotoNotifier } from "../../../adapters"; import { Context } from "probot"; -import { Payload } from "../../../types"; +import { BotContext, Payload } from "../../../types"; import { fetchImage } from "../../../utils/web-assets"; import { weeklyConfig } from "../../../configs/weekly"; import { ProximaNovaRegularBase64 } from "../../../assets/fonts/proxima-nova-regular-b64"; @@ -340,8 +339,7 @@ const processTelegram = async (caption: string) => { }); }; -export const run = async () => { - const context = getBotContext(); +export const run = async (context: BotContext) => { const payload = context.payload as Payload; const repository = payload.repository.full_name; const eventsList = await fetchEvents(context); @@ -350,7 +348,7 @@ export const run = async () => { await htmlImage(summaryInfo); await compositeImage(); - const { telegram } = getBotConfig(); + const { telegram } = context.botConfig; if (telegram.token) { await processTelegram(dataPadded); } else { diff --git a/src/helpers/commit.ts b/src/helpers/commit.ts index 678b4d774..e034e3416 100644 --- a/src/helpers/commit.ts +++ b/src/helpers/commit.ts @@ -1,8 +1,6 @@ -import { getBotContext } from "../bindings"; -import { Payload } from "../types"; +import { BotContext, Payload } from "../types"; -export async function createCommitComment(body: string, commitSha: string, path?: string, owner?: string, repo?: string) { - const context = getBotContext(); +export async function createCommitComment(context: BotContext,body: string, commitSha: string, path?: string, owner?: string, repo?: string) { const payload = context.payload as Payload; if (!owner) { owner = payload.repository.owner.login; diff --git a/src/helpers/ens.ts b/src/helpers/ens.ts index a9344c41a..90f1c79f5 100644 --- a/src/helpers/ens.ts +++ b/src/helpers/ens.ts @@ -1,14 +1,13 @@ import { ethers } from "ethers"; -import { getBotConfig } from "../bindings"; - +import { BotContext } from "../types"; /** * Gets the Ethereum address associated with an ENS (Ethereum Name Service) name * @param ensName - The ENS name, i.e. alice12345.crypto */ -export const resolveAddress = async (ensName: string): Promise => { +export const resolveAddress = async (context: BotContext, ensName: string): Promise => { const { payout: { rpc }, - } = getBotConfig(); + } = context.botConfig; const provider = new ethers.providers.JsonRpcProvider(rpc); const address = await provider.resolveName(ensName); return address; diff --git a/src/helpers/file.ts b/src/helpers/file.ts index b21905098..16f11740d 100644 --- a/src/helpers/file.ts +++ b/src/helpers/file.ts @@ -1,9 +1,9 @@ -import { getBotContext, getLogger } from "../bindings"; +import { getLogger } from "../bindings"; +import { BotContext } from "../types"; // Get the previous file content -export async function getPreviousFileContent(owner: string, repo: string, branch: string, filePath: string) { +export async function getPreviousFileContent(context: BotContext,owner: string, repo: string, branch: string, filePath: string) { const logger = getLogger(); - const context = getBotContext(); try { // Get the latest commit of the branch @@ -60,9 +60,8 @@ export async function getPreviousFileContent(owner: string, repo: string, branch } } -export async function getFileContent(owner: string, repo: string, branch: string, filePath: string, commitSha?: string): Promise { +export async function getFileContent(context: BotContext,owner: string, repo: string, branch: string, filePath: string, commitSha?: string): Promise { const logger = getLogger(); - const context = getBotContext(); try { if (!commitSha) { diff --git a/src/helpers/gpt.ts b/src/helpers/gpt.ts index 046503d79..c63a32a7d 100644 --- a/src/helpers/gpt.ts +++ b/src/helpers/gpt.ts @@ -1,5 +1,5 @@ -import { getBotConfig, getBotContext, getLogger } from "../bindings"; -import { Payload, StreamlinedComment, UserType } from "../types"; +import { getLogger } from "../bindings"; +import { BotContext, Payload, StreamlinedComment, UserType } from "../types"; import { getAllIssueComments, getAllLinkedIssuesAndPullsInBody } from "../helpers"; import OpenAI from "openai"; import { CreateChatCompletionRequestMessage } from "openai/resources/chat"; @@ -62,12 +62,12 @@ Example:[ * @param linkedIssueStreamlined an array of comments in the form of { login: string, body: string } */ export const decideContextGPT = async ( + context: BotContext, chatHistory: CreateChatCompletionRequestMessage[], streamlined: StreamlinedComment[], linkedPRStreamlined: StreamlinedComment[], linkedIssueStreamlined: StreamlinedComment[] ) => { - const context = getBotContext(); const logger = getLogger(); const payload = context.payload as Payload; @@ -78,9 +78,9 @@ export const decideContextGPT = async ( } // standard comments - const comments = await getAllIssueComments(issue.number); + const comments = await getAllIssueComments(context, issue.number); // raw so we can grab the tag - const commentsRaw = await getAllIssueComments(issue.number, "raw"); + const commentsRaw = await getAllIssueComments(context, issue.number, "raw"); if (!comments) { logger.info(`Error getting issue comments`); @@ -104,7 +104,7 @@ export const decideContextGPT = async ( }); // returns the conversational context from all linked issues and prs - const links = await getAllLinkedIssuesAndPullsInBody(issue.number); + const links = await getAllLinkedIssuesAndPullsInBody(context, issue.number); if (typeof links === "string") { logger.info(`Error getting linked issues or prs: ${links}`); @@ -133,7 +133,7 @@ export const decideContextGPT = async ( ); // we'll use the first response to determine the context of future calls - const res = await askGPT("", chatHistory); + const res = await askGPT(context, "", chatHistory); return res; }; @@ -143,9 +143,9 @@ export const decideContextGPT = async ( * @param question the question to ask * @param chatHistory the conversational context to provide to GPT */ -export const askGPT = async (question: string, chatHistory: CreateChatCompletionRequestMessage[]) => { +export const askGPT = async (context: BotContext,question: string, chatHistory: CreateChatCompletionRequestMessage[]) => { const logger = getLogger(); - const config = getBotConfig(); + const config = context.botConfig; if (!config.ask.apiKey) { logger.info(`No OpenAI API Key provided`); diff --git a/src/helpers/issue.ts b/src/helpers/issue.ts index e014994fe..4226482fa 100644 --- a/src/helpers/issue.ts +++ b/src/helpers/issue.ts @@ -1,10 +1,9 @@ import { Context } from "probot"; -import { getBotConfig, getBotContext, getLogger } from "../bindings"; -import { AssignEvent, Comment, IssueType, Payload, StreamlinedComment, UserType } from "../types"; +import { getLogger } from "../bindings"; +import { AssignEvent, BotContext, Comment, IssueType, Payload, StreamlinedComment, UserType } from "../types"; import { checkRateLimitGit } from "../utils"; -export const clearAllPriceLabelsOnIssue = async (): Promise => { - const context = getBotContext(); +export const clearAllPriceLabelsOnIssue = async (context: BotContext): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -27,8 +26,7 @@ export const clearAllPriceLabelsOnIssue = async (): Promise => { } }; -export const addLabelToIssue = async (labelName: string) => { - const context = getBotContext(); +export const addLabelToIssue = async (context: BotContext,labelName: string) => { const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue) { @@ -49,13 +47,13 @@ export const addLabelToIssue = async (labelName: string) => { }; export const listIssuesForRepo = async ( + context: BotContext, state: "open" | "closed" | "all" = "open", per_page = 30, page = 1, sort: "created" | "updated" | "comments" = "created", direction: "desc" | "asc" = "desc" ) => { - const context = getBotContext(); const payload = context.payload as Payload; const response = await context.octokit.issues.listForRepo({ @@ -77,13 +75,13 @@ export const listIssuesForRepo = async ( } }; -export const listAllIssuesForRepo = async (state: "open" | "closed" | "all" = "open") => { +export const listAllIssuesForRepo = async (context: BotContext,state: "open" | "closed" | "all" = "open") => { const issuesArr = []; let fetchDone = false; const perPage = 100; let curPage = 1; while (!fetchDone) { - const issues = await listIssuesForRepo(state, perPage, curPage); + const issues = await listIssuesForRepo(context, state, perPage, curPage); // push the objects to array issuesArr.push(...issues); @@ -95,8 +93,7 @@ export const listAllIssuesForRepo = async (state: "open" | "closed" | "all" = "o return issuesArr; }; -export const addCommentToIssue = async (msg: string, issue_number: number) => { - const context = getBotContext(); +export const addCommentToIssue = async (context: BotContext,msg: string, issue_number: number) => { const logger = getLogger(); const payload = context.payload as Payload; @@ -112,8 +109,7 @@ export const addCommentToIssue = async (msg: string, issue_number: number) => { } }; -export const updateCommentOfIssue = async (msg: string, issue_number: number, reply_to: Comment) => { - const context = getBotContext(); +export const updateCommentOfIssue = async (context: BotContext,msg: string, issue_number: number, reply_to: Comment) => { const logger = getLogger(); const payload = context.payload as Payload; @@ -147,23 +143,22 @@ export const updateCommentOfIssue = async (msg: string, issue_number: number, re }); } else { logger.info(`Falling back to add comment. Couldn't find response to edit for comment_id: ${reply_to.id}`); - await addCommentToIssue(msg, issue_number); + await addCommentToIssue(context, msg, issue_number); } } catch (e: unknown) { logger.debug(`Upading a comment failed!, reason: ${e}`); } }; -export const upsertCommentToIssue = async (issue_number: number, comment: string, action: string, reply_to?: Comment) => { +export const upsertCommentToIssue = async (context: BotContext,issue_number: number, comment: string, action: string, reply_to?: Comment) => { if (action == "edited" && reply_to) { - await updateCommentOfIssue(comment, issue_number, reply_to); + await updateCommentOfIssue(context, comment, issue_number, reply_to); } else { - await addCommentToIssue(comment, issue_number); + await addCommentToIssue(context, comment, issue_number); } }; -export const getCommentsOfIssue = async (issue_number: number): Promise => { - const context = getBotContext(); +export const getCommentsOfIssue = async (context: BotContext, issue_number: number): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -183,8 +178,7 @@ export const getCommentsOfIssue = async (issue_number: number): Promise => { - const context = getBotContext(); +export const getIssueDescription = async (context: BotContext, issue_number: number, format: "raw" | "html" | "text" = "raw"): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -217,8 +211,7 @@ export const getIssueDescription = async (issue_number: number, format: "raw" | return result; }; -export const getAllIssueComments = async (issue_number: number, format: "raw" | "html" | "text" | "full" = "raw"): Promise => { - const context = getBotContext(); +export const getAllIssueComments = async (context: BotContext, issue_number: number, format: "raw" | "html" | "text" | "full" = "raw"): Promise => { const payload = context.payload as Payload; const result: Comment[] = []; @@ -254,8 +247,7 @@ export const getAllIssueComments = async (issue_number: number, format: "raw" | return result; }; -export const getAllIssueAssignEvents = async (issue_number: number): Promise => { - const context = getBotContext(); +export const getAllIssueAssignEvents = async (context: BotContext, issue_number: number): Promise => { const payload = context.payload as Payload; const result: AssignEvent[] = []; @@ -288,8 +280,7 @@ export const getAllIssueAssignEvents = async (issue_number: number): Promise (new Date(a.created_at) > new Date(b.created_at) ? -1 : 1)); }; -export const wasIssueReopened = async (issue_number: number): Promise => { - const context = getBotContext(); +export const wasIssueReopened = async (context: BotContext, issue_number: number): Promise => { const payload = context.payload as Payload; let shouldFetch = true; @@ -321,8 +312,7 @@ export const wasIssueReopened = async (issue_number: number): Promise = return false; }; -export const removeAssignees = async (issue_number: number, assignees: string[]): Promise => { - const context = getBotContext(); +export const removeAssignees = async (context: BotContext, issue_number: number, assignees: string[]): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -404,8 +394,7 @@ export const getUserPermission = async (username: string, context: Context): Pro } }; -export const addAssignees = async (issue_number: number, assignees: string[]): Promise => { - const context = getBotContext(); +export const addAssignees = async (context: BotContext, issue_number: number, assignees: string[]): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -421,8 +410,7 @@ export const addAssignees = async (issue_number: number, assignees: string[]): P } }; -export const deleteLabel = async (label: string): Promise => { - const context = getBotContext(); +export const deleteLabel = async (context: BotContext, label: string): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -443,8 +431,7 @@ export const deleteLabel = async (label: string): Promise => { } }; -export const removeLabel = async (name: string) => { - const context = getBotContext(); +export const removeLabel = async (context: BotContext, name: string) => { const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue) { @@ -499,12 +486,11 @@ export const getPullRequests = async (context: Context, state: "open" | "closed" } }; -export const closePullRequest = async (pull_number: number) => { - const context = getBotContext(); +export const closePullRequest = async (context: BotContext, pull_number: number) => { const payload = context.payload as Payload; const logger = getLogger(); try { - await getBotContext().octokit.rest.pulls.update({ + await context.octokit.rest.pulls.update({ owner: payload.repository.owner.login, repo: payload.repository.name, pull_number, @@ -603,13 +589,13 @@ export const getPullByNumber = async (context: Context, pull_number: number) => }; // Get issues assigned to a username -export const getAssignedIssues = async (username: string) => { +export const getAssignedIssues = async (context: BotContext, username: string) => { const issuesArr = []; let fetchDone = false; const perPage = 30; let curPage = 1; while (!fetchDone) { - const issues = await listIssuesForRepo(IssueType.OPEN, perPage, curPage); + const issues = await listIssuesForRepo(context, IssueType.OPEN, perPage, curPage); // push the objects to array issuesArr.push(...issues); @@ -624,8 +610,8 @@ export const getAssignedIssues = async (username: string) => { return assigned_issues; }; -export const getOpenedPullRequestsForAnIssue = async (issueNumber: number, userName: string) => { - const pulls = await getOpenedPullRequests(userName); +export const getOpenedPullRequestsForAnIssue = async (context: BotContext, issueNumber: number, userName: string) => { + const pulls = await getOpenedPullRequests(context, userName); return pulls.filter((pull) => { if (!pull.body) return false; @@ -639,16 +625,14 @@ export const getOpenedPullRequestsForAnIssue = async (issueNumber: number, userN }); }; -export const getOpenedPullRequests = async (username: string) => { - const context = getBotContext(); +export const getOpenedPullRequests = async (context: BotContext, username: string) => { const prs = await getAllPullRequests(context, "open"); return prs.filter((pr) => !pr.draft && (pr.user?.login === username || !username)); }; -export const getCommitsOnPullRequest = async (pullNumber: number) => { +export const getCommitsOnPullRequest = async (context: BotContext, pullNumber: number) => { const logger = getLogger(); - const context = getBotContext(); - const payload = getBotContext().payload as Payload; + const payload = context.payload as Payload; try { const { data: commits } = await context.octokit.rest.pulls.listCommits({ owner: payload.repository.owner.login, @@ -662,14 +646,13 @@ export const getCommitsOnPullRequest = async (pullNumber: number) => { } }; -export const getAvailableOpenedPullRequests = async (username: string) => { - const context = getBotContext(); +export const getAvailableOpenedPullRequests = async (context: BotContext, username: string) => { const { unassign: { timeRangeForMaxIssue, timeRangeForMaxIssueEnabled }, - } = await getBotConfig(); + } = await context.botConfig; if (!timeRangeForMaxIssueEnabled) return []; - const opened_prs = await getOpenedPullRequests(username); + const opened_prs = await getOpenedPullRequests(context, username); const result = []; @@ -690,8 +673,7 @@ export const getAvailableOpenedPullRequests = async (username: string) => { }; // Strips out all links from the body of an issue or pull request and fetches the conversational context from each linked issue or pull request -export const getAllLinkedIssuesAndPullsInBody = async (issueNumber: number) => { - const context = getBotContext(); +export const getAllLinkedIssuesAndPullsInBody = async (context: BotContext, issueNumber: number) => { const logger = getLogger(); const issue = await getIssueByNumber(context, issueNumber); @@ -742,8 +724,8 @@ export const getAllLinkedIssuesAndPullsInBody = async (issueNumber: number) => { login: "system", body: `=============== Pull Request #${pr.number}: ${pr.title} + ===============\n ${pr.body}}`, }); - const prComments = await getAllIssueComments(linkedPrs[i]); - const prCommentsRaw = await getAllIssueComments(linkedPrs[i], "raw"); + const prComments = await getAllIssueComments(context, linkedPrs[i]); + const prCommentsRaw = await getAllIssueComments(context, linkedPrs[i], "raw"); prComments.forEach(async (comment, i) => { if (comment.user.type == UserType.User || prCommentsRaw[i].body.includes("")) { linkedPRStreamlined.push({ @@ -764,8 +746,8 @@ export const getAllLinkedIssuesAndPullsInBody = async (issueNumber: number) => { login: "system", body: `=============== Issue #${issue.number}: ${issue.title} + ===============\n ${issue.body} `, }); - const issueComments = await getAllIssueComments(linkedIssues[i]); - const issueCommentsRaw = await getAllIssueComments(linkedIssues[i], "raw"); + const issueComments = await getAllIssueComments(context, linkedIssues[i]); + const issueCommentsRaw = await getAllIssueComments(context, linkedIssues[i], "raw"); issueComments.forEach(async (comment, i) => { if (comment.user.type == UserType.User || issueCommentsRaw[i].body.includes("")) { linkedIssueStreamlined.push({ diff --git a/src/helpers/label.ts b/src/helpers/label.ts index a02d6c5eb..1ff13dc50 100644 --- a/src/helpers/label.ts +++ b/src/helpers/label.ts @@ -1,13 +1,11 @@ -import { Context } from "probot"; -import { getBotConfig, getBotContext, getLogger } from "../bindings"; +import { getLogger } from "../bindings"; import { COLORS } from "../configs"; import { calculateBountyPrice } from "../handlers"; -import { Label, Payload } from "../types"; +import { BotContext, Label, Payload } from "../types"; import { deleteLabel } from "./issue"; import { calculateWeight } from "../helpers"; -export const listLabelsForRepo = async (per_page?: number, page?: number): Promise => { - const context = getBotContext(); +export const listLabelsForRepo = async (context: BotContext, per_page?: number, page?: number): Promise => { const payload = context.payload as Payload; const res = await context.octokit.rest.issues.listLabelsForRepo({ @@ -24,8 +22,7 @@ export const listLabelsForRepo = async (per_page?: number, page?: number): Promi throw new Error(`Failed to fetch lists of labels, code: ${res.status}`); }; -export const createLabel = async (name: string, labelType?: keyof typeof COLORS): Promise => { - const context = getBotContext(); +export const createLabel = async (context: BotContext,name: string, labelType?: keyof typeof COLORS): Promise => { const logger = getLogger(); const payload = context.payload as Payload; try { @@ -40,8 +37,7 @@ export const createLabel = async (name: string, labelType?: keyof typeof COLORS) } }; -export const getLabel = async (name: string): Promise => { - const context = getBotContext(); +export const getLabel = async (context: BotContext, name: string): Promise => { const logger = getLogger(); const payload = context.payload as Payload; try { @@ -59,20 +55,20 @@ export const getLabel = async (name: string): Promise => { }; // Function to update labels based on the base rate difference -export const updateLabelsFromBaseRate = async (owner: string, repo: string, context: Context, labels: Label[], previousBaseRate: number) => { +export const updateLabelsFromBaseRate = async (context: BotContext, owner: string, repo: string, labels: Label[], previousBaseRate: number) => { const logger = getLogger(); - const config = getBotConfig(); + const config = context.botConfig; const newLabels: string[] = []; const previousLabels: string[] = []; for (const timeLabel of config.price.timeLabels) { for (const priorityLabel of config.price.priorityLabels) { - const targetPrice = calculateBountyPrice(calculateWeight(timeLabel), calculateWeight(priorityLabel), config.price.baseMultiplier); + const targetPrice = calculateBountyPrice(context, calculateWeight(timeLabel), calculateWeight(priorityLabel), config.price.baseMultiplier); const targetPriceLabel = `Price: ${targetPrice} USD`; newLabels.push(targetPriceLabel); - const previousTargetPrice = calculateBountyPrice(calculateWeight(timeLabel), calculateWeight(priorityLabel), previousBaseRate); + const previousTargetPrice = calculateBountyPrice(context, calculateWeight(timeLabel), calculateWeight(priorityLabel), previousBaseRate); const previousTargetPriceLabel = `Price: ${previousTargetPrice} USD`; previousLabels.push(previousTargetPriceLabel); } @@ -92,11 +88,11 @@ export const updateLabelsFromBaseRate = async (owner: string, repo: string, cont const labelData = labels.find((obj) => obj["name"] === label) as Label; const index = uniquePreviousLabels.findIndex((obj) => obj === label); - const exist = await getLabel(uniqueNewLabels[index]); + const exist = await getLabel(context, uniqueNewLabels[index]); if (exist) { // we have to delete first logger.debug(`Deleted ${uniqueNewLabels[index]}, updating it`); - await deleteLabel(uniqueNewLabels[index]); + await deleteLabel(context, uniqueNewLabels[index]); } // we can update safely diff --git a/src/helpers/parser.ts b/src/helpers/parser.ts index 42821a5b5..8a9429fc2 100644 --- a/src/helpers/parser.ts +++ b/src/helpers/parser.ts @@ -1,7 +1,8 @@ import axios from "axios"; import { HTMLElement, parse } from "node-html-parser"; import { getPullByNumber } from "./issue"; -import { getBotContext, getLogger } from "../bindings"; +import { getLogger } from "../bindings"; +import { BotContext } from "../types"; interface GitParser { owner: string; @@ -75,8 +76,7 @@ export const gitLinkedPrParser = async ({ owner, repo, issue_number }: GitParser } }; -export const getLatestPullRequest = async (prs: LinkedPR[]) => { - const context = getBotContext(); +export const getLatestPullRequest = async (context: BotContext,prs: LinkedPR[]) => { let linkedPullRequest = null; for (const _pr of prs) { if (Number.isNaN(_pr.prNumber)) return null; diff --git a/src/helpers/permit.ts b/src/helpers/permit.ts index 064b8918c..fe0aeb6d1 100644 --- a/src/helpers/permit.ts +++ b/src/helpers/permit.ts @@ -1,9 +1,9 @@ import { MaxUint256, PermitTransferFrom, SignatureTransfer } from "@uniswap/permit2-sdk"; import { BigNumber, ethers } from "ethers"; -import { getBotConfig, getBotContext, getLogger } from "../bindings"; +import { getLogger } from "../bindings"; import { keccak256, toUtf8Bytes } from "ethers/lib/utils"; import Decimal from "decimal.js"; -import { Payload } from "../types"; +import { BotContext, Payload } from "../types"; import { savePermit } from "../adapters/supabase"; const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; // same on all networks @@ -53,6 +53,7 @@ type TxData = { * @returns Permit2 url including base64 encocded data */ export const generatePermit2Signature = async ( + context: BotContext, spender: string, amountInEth: Decimal, identifier: string, @@ -60,7 +61,7 @@ export const generatePermit2Signature = async ( ): Promise<{ txData: TxData; payoutUrl: string }> => { const { payout: { networkId, privateKey, permitBaseUrl, rpc, paymentToken }, - } = getBotConfig(); + } = context.botConfig; const logger = getLogger(); const provider = new ethers.providers.JsonRpcProvider(rpc); const adminWallet = new ethers.Wallet(privateKey, provider); @@ -106,10 +107,9 @@ export const generatePermit2Signature = async ( return { txData, payoutUrl }; }; -export const savePermitToDB = async (bountyHunterId: number, txData: TxData): Promise => { +export const savePermitToDB = async (context: BotContext, bountyHunterId: number, txData: TxData): Promise => { const logger = getLogger(); - const context = getBotContext(); const payload = context.payload as Payload; const issue = payload.issue; const repository = payload.repository; @@ -119,7 +119,7 @@ export const savePermitToDB = async (bountyHunterId: number, txData: TxData): Pr throw new Error("Cannot save permit to DB, missing issue, repository or organization"); } - const { payout } = getBotConfig(); + const { payout } = context.botConfig; const { networkId } = payout; const permit: InsertPermit = { diff --git a/src/helpers/shared.ts b/src/helpers/shared.ts index 86e1599eb..03ff273b5 100644 --- a/src/helpers/shared.ts +++ b/src/helpers/shared.ts @@ -1,11 +1,9 @@ import ms from "ms"; -import { getBotContext } from "../bindings"; -import { LabelItem, Payload, UserType } from "../types"; +import { BotContext, LabelItem, Payload, UserType } from "../types"; const contextNamesToSkip = ["workflow_run"]; -export const shouldSkip = (): { skip: boolean; reason: string } => { - const context = getBotContext(); +export const shouldSkip = (context: BotContext): { skip: boolean; reason: string } => { const { name } = context; const payload = context.payload as Payload; const res: { skip: boolean; reason: string } = { skip: false, reason: "" }; diff --git a/src/helpers/user.ts b/src/helpers/user.ts index 5f151f241..27e7e6dba 100644 --- a/src/helpers/user.ts +++ b/src/helpers/user.ts @@ -1,13 +1,12 @@ -import { getBotContext, getLogger } from "../bindings"; -import { User } from "../types"; +import { getLogger } from "../bindings"; +import { BotContext, User } from "../types"; /** * @dev Gets the publicly available information about `username` * * @param username The username you're getting information for */ -export const getUser = async (username: string): Promise => { - const context = getBotContext(); +export const getUser = async (context: BotContext, username: string): Promise => { const logger = getLogger(); try { @@ -33,8 +32,7 @@ export const getUser = async (username: string): Promise => { * * @returns The role name of a user in the organization. "admin" || "member" || "billing_manager" */ -export const getOrgMembershipOfUser = async (org: string, username: string): Promise => { - const context = getBotContext(); +export const getOrgMembershipOfUser = async (context: BotContext,org: string, username: string): Promise => { const logger = getLogger(); let membership: string | undefined = undefined; From 6451f7efc8b99505ac40d3ba1c320af4fc4259b9 Mon Sep 17 00:00:00 2001 From: sadaf Date: Wed, 27 Sep 2023 08:04:39 +0530 Subject: [PATCH 5/9] fix(type): fixing more typescript errors --- src/bindings/event.ts | 8 ++++---- src/handlers/comment/action.ts | 10 +++++----- src/handlers/wildcard/analytics.ts | 2 +- src/types/handlers.ts | 7 ++++--- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/bindings/event.ts b/src/bindings/event.ts index 0e4ac8442..7cefef243 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -113,18 +113,18 @@ export const bindEvents = async (context: BotContext): Promise => { // Run pre-handlers logger.info(`Running pre handlers: ${pre.map((fn) => fn.name)}, event: ${eventName}`); for (const preAction of pre) { - await preAction(); + await preAction(context); } // Run main handlers logger.info(`Running main handlers: ${action.map((fn) => fn.name)}, event: ${eventName}`); for (const mainAction of action) { - await mainAction(); + await mainAction(context); } // Run post-handlers logger.info(`Running post handlers: ${post.map((fn) => fn.name)}, event: ${eventName}`); for (const postAction of post) { - await postAction(); + await postAction(context); } // Skip wildcard handlers for installation event and push event @@ -132,7 +132,7 @@ export const bindEvents = async (context: BotContext): Promise => { // Run wildcard handlers logger.info(`Running wildcard handlers: ${wildcardProcessors.map((fn) => fn.name)}`); for (const wildcardProcessor of wildcardProcessors) { - await wildcardProcessor(); + await wildcardProcessor(context); } } }; diff --git a/src/handlers/comment/action.ts b/src/handlers/comment/action.ts index 1d4f1e6d1..419152748 100644 --- a/src/handlers/comment/action.ts +++ b/src/handlers/comment/action.ts @@ -41,20 +41,20 @@ export const handleComment = async (context: BotContext): Promise => { if (!feature?.enabled && id !== IssueCommentCommands.HELP) { logger.info(`Skipping '${id}' because it is disabled on this repo.`); - await callback(issue.number, `Skipping \`${id}\` because it is disabled on this repo.`, payload.action, payload.comment); + await callback(context, issue.number, `Skipping \`${id}\` because it is disabled on this repo.`, payload.action, payload.comment); continue; } try { - const response = await handler(body); + const response = await handler(context, body); const callbackComment = response ?? successComment ?? ""; - if (callbackComment) await callback(issue.number, callbackComment, payload.action, payload.comment); + if (callbackComment) await callback(context, issue.number, callbackComment, payload.action, payload.comment); } catch (err: unknown) { // Use failureComment for failed command if it is available if (failureComment) { - await callback(issue.number, failureComment, payload.action, payload.comment); + await callback(context, issue.number, failureComment, payload.action, payload.comment); } - await callback(issue.number, ErrorDiff(err), payload.action, payload.comment); + await callback(context, issue.number, ErrorDiff(err), payload.action, payload.comment); } } else { logger.info(`Skipping for a command: ${command}`); diff --git a/src/handlers/wildcard/analytics.ts b/src/handlers/wildcard/analytics.ts index 9955142e2..4fb4d405b 100644 --- a/src/handlers/wildcard/analytics.ts +++ b/src/handlers/wildcard/analytics.ts @@ -71,7 +71,7 @@ export const collectAnalytics = async (context: BotContext): Promise => { const assigneesToUpsert = assignees.filter((assignee, pos) => tmp.indexOf(assignee.login) == pos); const userProfilesToUpsert = await Promise.all( assigneesToUpsert.map(async (assignee) => { - const res = await getUser(assignee.login); + const res = await getUser(context, assignee.login); return res as UserProfile; }) ); diff --git a/src/types/handlers.ts b/src/types/handlers.ts index 5a79f4dd0..bd4854fd2 100644 --- a/src/types/handlers.ts +++ b/src/types/handlers.ts @@ -1,8 +1,9 @@ +import { BotContext } from "./config"; import { Comment } from "./payload"; -export type CommandsHandler = (args: string) => Promise; -export type ActionHandler = (args?: string) => Promise; -export type CallbackHandler = (issue_number: number, text: string, action: string, reply_to?: Comment) => Promise; +export type CommandsHandler = (context: BotContext, args: string) => Promise; +export type ActionHandler = (context: BotContext,args?: string) => Promise; +export type CallbackHandler = (context: BotContext,issue_number: number, text: string, action: string, reply_to?: Comment) => Promise; export type PreActionHandler = ActionHandler; export type PostActionHandler = ActionHandler; From 1477564f1723a3eae4c1766c37c127c3d0703742 Mon Sep 17 00:00:00 2001 From: sadaf Date: Fri, 6 Oct 2023 00:14:18 +0530 Subject: [PATCH 6/9] fix(summarize-test): removing summarize-test.ts --- src/tests/summarize-test.ts | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/tests/summarize-test.ts diff --git a/src/tests/summarize-test.ts b/src/tests/summarize-test.ts deleted file mode 100644 index 621548a8c..000000000 --- a/src/tests/summarize-test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { run } from "../handlers/wildcard/weekly/action"; - -run() - .then((res) => { - console.log(res); - }) - .catch((err) => { - console.log(err); - }); From 48dad9bdb3d7b213d226a5c9fadfc08aba5f8d99 Mon Sep 17 00:00:00 2001 From: sadaf Date: Sat, 7 Oct 2023 19:07:50 +0530 Subject: [PATCH 7/9] feat(event): fixing error with event.ts --- src/bindings/event.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bindings/event.ts b/src/bindings/event.ts index 7cefef243..f3dad5f54 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -2,6 +2,7 @@ import { createAdapters } from "../adapters"; import { processors, wildcardProcessors } from "../handlers/processors"; import { shouldSkip } from "../helpers"; import { BotContext, GithubEvent, Payload, PayloadSchema, LogLevel } from "../types"; +import { Context as ProbotContext } from "probot"; import { Adapters } from "../types/adapters"; import { ajv } from "../utils"; import { loadConfig } from "./config"; @@ -23,7 +24,8 @@ export const getLogger = (): Logger => logger; const NO_VALIDATION = [GithubEvent.INSTALLATION_ADDED_EVENT as string, GithubEvent.PUSH_EVENT as string]; -export const bindEvents = async (context: BotContext): Promise => { +export const bindEvents = async (_context: ProbotContext): Promise => { + const context = _context as BotContext; const { id, name } = context; const payload = context.payload as Payload; const allowedEvents = Object.values(GithubEvent) as string[]; From 6b9954d8b17f4dc5437eeae490daded772ff8528 Mon Sep 17 00:00:00 2001 From: sadaf Date: Sat, 7 Oct 2023 20:53:13 +0530 Subject: [PATCH 8/9] reafactor(merge): fixing error and formatting after merge --- src/adapters/supabase/helpers/log.ts | 16 +++++++--------- src/bindings/config.ts | 4 +--- src/bindings/event.ts | 5 ++--- src/handlers/assign/action.ts | 2 -- src/handlers/comment/handlers/authorize.ts | 9 ++++----- src/handlers/comment/handlers/help.ts | 3 --- src/handlers/comment/handlers/index.ts | 4 ++-- src/handlers/label/index.ts | 7 +++---- src/handlers/payout/action.ts | 7 +++---- src/handlers/payout/post.ts | 2 +- src/handlers/pricing/action.ts | 10 +++++----- src/handlers/wildcard/analytics.ts | 3 ++- src/handlers/wildcard/unassign.ts | 4 ++-- src/helpers/commit.ts | 2 +- src/helpers/file.ts | 11 +++++++++-- src/helpers/gpt.ts | 2 +- src/helpers/issue.ts | 14 +++++++------- src/helpers/label.ts | 6 +++--- src/helpers/parser.ts | 2 +- src/helpers/payout.ts | 7 +++---- src/helpers/user.ts | 2 +- src/types/handlers.ts | 4 ++-- 22 files changed, 60 insertions(+), 66 deletions(-) diff --git a/src/adapters/supabase/helpers/log.ts b/src/adapters/supabase/helpers/log.ts index 3d7cb56af..5b19c3ec3 100644 --- a/src/adapters/supabase/helpers/log.ts +++ b/src/adapters/supabase/helpers/log.ts @@ -1,6 +1,6 @@ import axios from "axios"; -import { getAdapters, getBotContext, Logger } from "../../../bindings"; -import { Payload, LogLevel, LogNotification } from "../../../types"; +import { getAdapters, Logger } from "../../../bindings"; +import { BotContext, Payload, LogLevel, LogNotification } from "../../../types"; import { getOrgAndRepoFromPath } from "../../../utils/private"; import jwt from "jsonwebtoken"; interface Log { @@ -57,7 +57,6 @@ export class GitHubLogger implements Logger { this.context = context; this.logNotification = logNotification; - } async sendLogsToSupabase({ repo, org, commentId, issueNumber, logMessage, level, timestamp }: Log) { @@ -88,8 +87,7 @@ export class GitHubLogger implements Logger { } } - private sendDataWithJwt(message: string | object, errorPayload?: string | object) { - const context = getBotContext(); + private sendDataWithJwt(context: BotContext, message: string | object, errorPayload?: string | object) { const payload = context.payload as Payload; const { comment, issue, repository } = payload; @@ -234,9 +232,9 @@ export class GitHubLogger implements Logger { this.save(message, LogLevel.INFO, errorPayload); } - warn(message: string | object, errorPayload?: string | object) { + warn(context: BotContext, message: string | object, errorPayload?: string | object) { this.save(message, LogLevel.WARN, errorPayload); - this.sendDataWithJwt(message, errorPayload) + this.sendDataWithJwt(context, message, errorPayload) .then((response) => { this.save(`Log Notification Success: ${response}`, LogLevel.DEBUG, ""); }) @@ -249,9 +247,9 @@ export class GitHubLogger implements Logger { this.save(message, LogLevel.DEBUG, errorPayload); } - error(message: string | object, errorPayload?: string | object) { + error(context: BotContext, message: string | object, errorPayload?: string | object) { this.save(message, LogLevel.ERROR, errorPayload); - this.sendDataWithJwt(message, errorPayload) + this.sendDataWithJwt(context, message, errorPayload) .then((response) => { this.save(`Log Notification Success: ${response}`, LogLevel.DEBUG, ""); }) diff --git a/src/bindings/config.ts b/src/bindings/config.ts index 55d0fb8be..43b5718fa 100644 --- a/src/bindings/config.ts +++ b/src/bindings/config.ts @@ -65,9 +65,7 @@ export const loadConfig = async (context: Context): Promise => { permitBaseUrl: process.env.PERMIT_BASE_URL || permitBaseUrl, }, unassign: { - timeRangeForMaxIssue: process.env.DEFAULT_TIME_RANGE_FOR_MAX_ISSUE - ? Number(process.env.DEFAULT_TIME_RANGE_FOR_MAX_ISSUE) - : timeRangeForMaxIssue, + timeRangeForMaxIssue: process.env.DEFAULT_TIME_RANGE_FOR_MAX_ISSUE ? Number(process.env.DEFAULT_TIME_RANGE_FOR_MAX_ISSUE) : timeRangeForMaxIssue, timeRangeForMaxIssueEnabled: process.env.DEFAULT_TIME_RANGE_FOR_MAX_ISSUE_ENABLED ? process.env.DEFAULT_TIME_RANGE_FOR_MAX_ISSUE_ENABLED == "true" : timeRangeForMaxIssueEnabled, diff --git a/src/bindings/event.ts b/src/bindings/event.ts index 0e97b272c..fd0f3de3a 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -50,9 +50,8 @@ export const bindEvents = async (_context: ProbotContext): Promise => { options.app, context.botConfig?.log?.logEnvironment ?? "development", context.botConfig?.log?.level ?? LogLevel.DEBUG, - context.botConfig?.log?.retryLimit ?? 0 - context.botConfig?.log?.logNotification - + context.botConfig?.log?.retryLimit ?? 0, + context.botConfig?.logNotification ); // contributors will see logs in console while on development env if (!logger) { return; diff --git a/src/handlers/assign/action.ts b/src/handlers/assign/action.ts index ec59c5cbc..1a5b1e2ed 100644 --- a/src/handlers/assign/action.ts +++ b/src/handlers/assign/action.ts @@ -63,9 +63,7 @@ export const commentWithAssignMessage = async (context: BotContext): Promise => { diff --git a/src/handlers/comment/handlers/authorize.ts b/src/handlers/comment/handlers/authorize.ts index 03918cded..9a1693954 100644 --- a/src/handlers/comment/handlers/authorize.ts +++ b/src/handlers/comment/handlers/authorize.ts @@ -1,12 +1,11 @@ import { _approveLabelChange, getLabelChanges } from "../../../adapters/supabase"; -import { getBotContext, getLogger } from "../../../bindings"; +import { getLogger } from "../../../bindings"; import { getUserPermission } from "../../../helpers"; -import { Payload } from "../../../types"; +import { BotContext, Payload } from "../../../types"; import { ErrorDiff } from "../../../utils/helpers"; import { bountyInfo } from "../../wildcard"; -export const approveLabelChange = async () => { - const context = getBotContext(); +export const approveLabelChange = async (context: BotContext) => { const logger = getLogger(); const payload = context.payload as Payload; const sender = payload.sender.login; @@ -29,7 +28,7 @@ export const approveLabelChange = async () => { return ErrorDiff(`You are not an admin/billing_manager and do not have the required permissions to access this function.`); } - const issueDetailed = bountyInfo(issue); + const issueDetailed = bountyInfo(context, issue); if (!issueDetailed.priceLabel || !issueDetailed.priorityLabel || !issueDetailed.timelabel) { logger.info(`Skipping... its not a bounty`); diff --git a/src/handlers/comment/handlers/help.ts b/src/handlers/comment/handlers/help.ts index 3c144f3e1..f956eb6fc 100644 --- a/src/handlers/comment/handlers/help.ts +++ b/src/handlers/comment/handlers/help.ts @@ -1,6 +1,5 @@ import { userCommands } from "."; import { getLogger } from "../../../bindings"; -import { ASSIGN_COMMAND_ENABLED } from "../../../configs"; import { BotContext, IssueType, Payload } from "../../../types"; import { IssueCommentCommands } from "../commands"; @@ -27,9 +26,7 @@ export const listAvailableCommands = async (context: BotContext, body: string) = return generateHelpMenu(context); }; - export const generateHelpMenu = (context: BotContext) => { - const startEnabled = context.botConfig.command.find((command) => command.name === "start"); let helpMenu = "### Available commands\n```"; diff --git a/src/handlers/comment/handlers/index.ts b/src/handlers/comment/handlers/index.ts index f5b416b82..ebd339a49 100644 --- a/src/handlers/comment/handlers/index.ts +++ b/src/handlers/comment/handlers/index.ts @@ -225,7 +225,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise } await addCommentToIssue( - context, + context, `@${assignee} please be sure to review this conversation and implement any necessary fixes. Unless this is closed as completed, its payment of **${formattedAmount} ${tokenSymbol}** will be deducted from your next bounty.`, issue.number ); @@ -245,7 +245,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise * @param comment - Comment string */ -const commandCallback = async (context: BotContext ,issue_number: number, comment: string, action: string, reply_to?: Comment) => { +const commandCallback = async (context: BotContext, issue_number: number, comment: string, action: string, reply_to?: Comment) => { await upsertCommentToIssue(context, issue_number, comment, action, reply_to); }; diff --git a/src/handlers/label/index.ts b/src/handlers/label/index.ts index 491d49f74..7adc7b1aa 100644 --- a/src/handlers/label/index.ts +++ b/src/handlers/label/index.ts @@ -1,11 +1,10 @@ import { saveLabelChange } from "../../adapters/supabase"; -import { getBotContext, getLogger } from "../../bindings"; +import { getLogger } from "../../bindings"; import { hasLabelEditPermission } from "../../helpers"; -import { Payload } from "../../types"; +import { BotContext, Payload } from "../../types"; -export const watchLabelChange = async () => { +export const watchLabelChange = async (context: BotContext) => { const logger = getLogger(); - const context = getBotContext(); const payload = context.payload as Payload; diff --git a/src/handlers/payout/action.ts b/src/handlers/payout/action.ts index b095ef93c..a2cab8707 100644 --- a/src/handlers/payout/action.ts +++ b/src/handlers/payout/action.ts @@ -412,7 +412,6 @@ export const handleIssueClosed = async ( priceArray: [creatorReward.reward[0].priceInEth.toString()], debug: creatorReward.reward[0].debug, }); - } else if (creatorReward && creatorReward.reward && creatorReward.reward[0].account === "0x") { logger.info(`Skipping to generate a permit url for missing account. fallback: ${creatorReward.fallbackReward}`); } @@ -503,20 +502,20 @@ export const handleIssueClosed = async ( reward.priceInEth = price.mul(multiplier); } - const { payoutUrl, txData } = await generatePermit2Signature(reward.account, reward.priceInEth, reward.issueId, reward.userId?.toString()); + const { payoutUrl, txData } = await generatePermit2Signature(context, reward.account, reward.priceInEth, reward.issueId, reward.userId?.toString()); const price = `${reward.priceInEth} ${incentivesCalculation.tokenSymbol.toUpperCase()}`; const comment = createDetailsTable(price, payoutUrl, reward.user, detailsValue, reward.debug); - await savePermitToDB(Number(reward.userId), txData); + await savePermitToDB(context, Number(reward.userId), txData); permitComment += comment; logger.info(`Skipping to generate a permit url for missing accounts. fallback: ${JSON.stringify(conversationRewards.fallbackReward)}`); logger.info(`Skipping to generate a permit url for missing accounts. fallback: ${JSON.stringify(pullRequestReviewersReward.fallbackReward)}`); } - if (permitComment) await addCommentToIssue(permitComment.trim() + comments.promotionComment, issueNumber); + if (permitComment) await addCommentToIssue(context, permitComment.trim() + comments.promotionComment, issueNumber); await deleteLabel(context, incentivesCalculation.issueDetailed.priceLabel); await addLabelToIssue(context, "Permitted"); diff --git a/src/handlers/payout/post.ts b/src/handlers/payout/post.ts index 149430c88..957e8e798 100644 --- a/src/handlers/payout/post.ts +++ b/src/handlers/payout/post.ts @@ -108,7 +108,7 @@ export const calculateIssueCreatorReward = async (context: BotContext, incentive logger.info(`incentivizeCreatorComment: its not a bounty`); return { error: `incentivizeCreatorComment: its not a bounty` }; } - + const assignees = incentivesCalculation.issue.assignees ?? []; const assignee = assignees.length > 0 ? assignees[0] : undefined; if (!assignee) { diff --git a/src/handlers/pricing/action.ts b/src/handlers/pricing/action.ts index ccde808e7..98c127241 100644 --- a/src/handlers/pricing/action.ts +++ b/src/handlers/pricing/action.ts @@ -42,7 +42,7 @@ export const pricingLabelLogic = async (context: BotContext): Promise => { if (_targetPriceLabel) { // get all issue events of type "labeled" and the event label includes Price - let labeledEvents = await getAllLabeledEvents(); + let labeledEvents = await getAllLabeledEvents(context); if (!labeledEvents) return; labeledEvents = labeledEvents.filter((event) => event.label?.name.includes("Price")); @@ -54,15 +54,15 @@ export const pricingLabelLogic = async (context: BotContext): Promise => { } else { // add price label to issue becuase wrong price has been added by bot logger.info(`Adding price label to issue`); - await clearAllPriceLabelsOnIssue(); + await clearAllPriceLabelsOnIssue(context); - const exist = await getLabel(targetPriceLabel); + const exist = await getLabel(context, targetPriceLabel); if (assistivePricing && !exist) { logger.info(`${targetPriceLabel} doesn't exist on the repo, creating...`); - await createLabel(targetPriceLabel, "price"); + await createLabel(context, targetPriceLabel, "price"); } - await addLabelToIssue(targetPriceLabel); + await addLabelToIssue(context, targetPriceLabel); } } else { // add price if there is none diff --git a/src/handlers/wildcard/analytics.ts b/src/handlers/wildcard/analytics.ts index 787228384..008072071 100644 --- a/src/handlers/wildcard/analytics.ts +++ b/src/handlers/wildcard/analytics.ts @@ -8,7 +8,8 @@ import { BotContext, Issue, IssueType, User, UserProfile } from "../../types"; * @param issue - The issue object * @returns If bounty - true, If issue - false */ -export const bountyInfo = (context: BotContext, +export const bountyInfo = ( + context: BotContext, issue: Issue ): { isBounty: boolean; diff --git a/src/handlers/wildcard/unassign.ts b/src/handlers/wildcard/unassign.ts index 7f3480717..61dd177cd 100644 --- a/src/handlers/wildcard/unassign.ts +++ b/src/handlers/wildcard/unassign.ts @@ -81,7 +81,7 @@ const checkBountyToUnassign = async (context: BotContext, issue: Issue): Promise ); } else { await addCommentToIssue( - context, + context, `${askUpdate} @${assignees[0]}? If you would like to release the bounty back to the DevPool, please comment \`/stop\` \nLast activity time: ${lastActivity}`, issue.number ); @@ -92,7 +92,7 @@ const checkBountyToUnassign = async (context: BotContext, issue: Issue): Promise return false; }; -const lastActivityTime = async (context: BotContext,issue: Issue, comments: Comment[]): Promise => { +const lastActivityTime = async (context: BotContext, issue: Issue, comments: Comment[]): Promise => { const logger = getLogger(); logger.info(`Checking the latest activity for the issue, issue_number: ${issue.number}`); const assignees = issue.assignees.map((i) => i.login); diff --git a/src/helpers/commit.ts b/src/helpers/commit.ts index e034e3416..ab13e42f1 100644 --- a/src/helpers/commit.ts +++ b/src/helpers/commit.ts @@ -1,6 +1,6 @@ import { BotContext, Payload } from "../types"; -export async function createCommitComment(context: BotContext,body: string, commitSha: string, path?: string, owner?: string, repo?: string) { +export async function createCommitComment(context: BotContext, body: string, commitSha: string, path?: string, owner?: string, repo?: string) { const payload = context.payload as Payload; if (!owner) { owner = payload.repository.owner.login; diff --git a/src/helpers/file.ts b/src/helpers/file.ts index 16f11740d..aa4016632 100644 --- a/src/helpers/file.ts +++ b/src/helpers/file.ts @@ -2,7 +2,7 @@ import { getLogger } from "../bindings"; import { BotContext } from "../types"; // Get the previous file content -export async function getPreviousFileContent(context: BotContext,owner: string, repo: string, branch: string, filePath: string) { +export async function getPreviousFileContent(context: BotContext, owner: string, repo: string, branch: string, filePath: string) { const logger = getLogger(); try { @@ -60,7 +60,14 @@ export async function getPreviousFileContent(context: BotContext,owner: string, } } -export async function getFileContent(context: BotContext,owner: string, repo: string, branch: string, filePath: string, commitSha?: string): Promise { +export async function getFileContent( + context: BotContext, + owner: string, + repo: string, + branch: string, + filePath: string, + commitSha?: string +): Promise { const logger = getLogger(); try { diff --git a/src/helpers/gpt.ts b/src/helpers/gpt.ts index c63a32a7d..2ee9cd3aa 100644 --- a/src/helpers/gpt.ts +++ b/src/helpers/gpt.ts @@ -143,7 +143,7 @@ export const decideContextGPT = async ( * @param question the question to ask * @param chatHistory the conversational context to provide to GPT */ -export const askGPT = async (context: BotContext,question: string, chatHistory: CreateChatCompletionRequestMessage[]) => { +export const askGPT = async (context: BotContext, question: string, chatHistory: CreateChatCompletionRequestMessage[]) => { const logger = getLogger(); const config = context.botConfig; diff --git a/src/helpers/issue.ts b/src/helpers/issue.ts index e142dd1b0..35de686c4 100644 --- a/src/helpers/issue.ts +++ b/src/helpers/issue.ts @@ -40,8 +40,8 @@ export const getAllIssueEvents = async (context: BotContext) => { return events; }; -export const getAllLabeledEvents = async () => { - const events = await getAllIssueEvents(); +export const getAllLabeledEvents = async (context: BotContext) => { + const events = await getAllIssueEvents(context); if (!events) return null; return events.filter((event) => event.event === "labeled"); }; @@ -69,7 +69,7 @@ export const clearAllPriceLabelsOnIssue = async (context: BotContext): Promise { +export const addLabelToIssue = async (context: BotContext, labelName: string) => { const logger = getLogger(); const payload = context.payload as Payload; if (!payload.issue) { @@ -118,7 +118,7 @@ export const listIssuesForRepo = async ( } }; -export const listAllIssuesForRepo = async (context: BotContext,state: "open" | "closed" | "all" = "open") => { +export const listAllIssuesForRepo = async (context: BotContext, state: "open" | "closed" | "all" = "open") => { const issuesArr = []; let fetchDone = false; const perPage = 100; @@ -136,7 +136,7 @@ export const listAllIssuesForRepo = async (context: BotContext,state: "open" | " return issuesArr; }; -export const addCommentToIssue = async (context: BotContext,msg: string, issue_number: number) => { +export const addCommentToIssue = async (context: BotContext, msg: string, issue_number: number) => { const logger = getLogger(); const payload = context.payload as Payload; @@ -152,7 +152,7 @@ export const addCommentToIssue = async (context: BotContext,msg: string, issue_n } }; -export const updateCommentOfIssue = async (context: BotContext,msg: string, issue_number: number, reply_to: Comment) => { +export const updateCommentOfIssue = async (context: BotContext, msg: string, issue_number: number, reply_to: Comment) => { const logger = getLogger(); const payload = context.payload as Payload; @@ -193,7 +193,7 @@ export const updateCommentOfIssue = async (context: BotContext,msg: string, issu } }; -export const upsertCommentToIssue = async (context: BotContext,issue_number: number, comment: string, action: string, reply_to?: Comment) => { +export const upsertCommentToIssue = async (context: BotContext, issue_number: number, comment: string, action: string, reply_to?: Comment) => { if (action == "edited" && reply_to) { await updateCommentOfIssue(context, comment, issue_number, reply_to); } else { diff --git a/src/helpers/label.ts b/src/helpers/label.ts index abf98a18e..d12ec3cc9 100644 --- a/src/helpers/label.ts +++ b/src/helpers/label.ts @@ -1,6 +1,6 @@ -import { getLogger } from "../bindings"; import { calculateBountyPrice } from "../handlers"; -import { BotContext, Label, Payload, getLogger } from "../types"; +import { BotContext, Label, Payload } from "../types"; +import { getLogger } from "../bindings"; import { deleteLabel } from "./issue"; import { calculateWeight } from "../helpers"; @@ -28,7 +28,7 @@ export const listLabelsForRepo = async (context: BotContext, per_page?: number, throw new Error(`Failed to fetch lists of labels, code: ${res.status}`); }; -export const createLabel = async (context: BotContext,name: string, labelType?: keyof typeof COLORS): Promise => { +export const createLabel = async (context: BotContext, name: string, labelType?: keyof typeof COLORS): Promise => { const logger = getLogger(); const payload = context.payload as Payload; try { diff --git a/src/helpers/parser.ts b/src/helpers/parser.ts index 8a9429fc2..f4c6de3b7 100644 --- a/src/helpers/parser.ts +++ b/src/helpers/parser.ts @@ -76,7 +76,7 @@ export const gitLinkedPrParser = async ({ owner, repo, issue_number }: GitParser } }; -export const getLatestPullRequest = async (context: BotContext,prs: LinkedPR[]) => { +export const getLatestPullRequest = async (context: BotContext, prs: LinkedPR[]) => { let linkedPullRequest = null; for (const _pr of prs) { if (Number.isNaN(_pr.prNumber)) return null; diff --git a/src/helpers/payout.ts b/src/helpers/payout.ts index c6f4a06f2..42d8aa071 100644 --- a/src/helpers/payout.ts +++ b/src/helpers/payout.ts @@ -12,9 +12,9 @@ */ import { Static } from "@sinclair/typebox"; -import { PayoutConfigSchema } from "../types"; +import { BotContext, PayoutConfigSchema } from "../types"; import { getUserPermission } from "./issue"; -import { getBotContext, getLogger } from "../bindings"; +import { getLogger } from "../bindings"; import { getAccessLevel } from "../adapters/supabase"; // available tokens for payouts @@ -48,8 +48,7 @@ export const getPayoutConfigByNetworkId = (networkId: number): PayoutConfigParti }; }; -export const hasLabelEditPermission = async (label: string, caller: string, repository: string) => { - const context = getBotContext(); +export const hasLabelEditPermission = async (context: BotContext, label: string, caller: string, repository: string) => { const logger = getLogger(); const permissionLevel = await getUserPermission(caller, context); diff --git a/src/helpers/user.ts b/src/helpers/user.ts index 27e7e6dba..211b4131e 100644 --- a/src/helpers/user.ts +++ b/src/helpers/user.ts @@ -32,7 +32,7 @@ export const getUser = async (context: BotContext, username: string): Promise => { +export const getOrgMembershipOfUser = async (context: BotContext, org: string, username: string): Promise => { const logger = getLogger(); let membership: string | undefined = undefined; diff --git a/src/types/handlers.ts b/src/types/handlers.ts index bd4854fd2..47c6df62f 100644 --- a/src/types/handlers.ts +++ b/src/types/handlers.ts @@ -2,8 +2,8 @@ import { BotContext } from "./config"; import { Comment } from "./payload"; export type CommandsHandler = (context: BotContext, args: string) => Promise; -export type ActionHandler = (context: BotContext,args?: string) => Promise; -export type CallbackHandler = (context: BotContext,issue_number: number, text: string, action: string, reply_to?: Comment) => Promise; +export type ActionHandler = (context: BotContext, args?: string) => Promise; +export type CallbackHandler = (context: BotContext, issue_number: number, text: string, action: string, reply_to?: Comment) => Promise; export type PreActionHandler = ActionHandler; export type PostActionHandler = ActionHandler; From bee6ac669b611247883f2c6529e9090d1e772fe7 Mon Sep 17 00:00:00 2001 From: sadaf Date: Tue, 24 Oct 2023 13:39:28 +0530 Subject: [PATCH 9/9] fix(conflicts): fixing errors caused due to newer commits and syncing branch with development --- src/adapters/supabase/helpers/client.ts | 50 ++++++++++----------- src/bindings/config.ts | 5 +-- src/bindings/event.ts | 10 ++--- src/handlers/access/labels-access.ts | 2 +- src/handlers/assign/action.ts | 4 +- src/handlers/assign/auto.ts | 2 +- src/handlers/comment/handlers/allow.ts | 8 ++-- src/handlers/comment/handlers/authorize.ts | 2 +- src/handlers/comment/handlers/index.ts | 10 ++--- src/handlers/comment/handlers/multiplier.ts | 6 +-- src/handlers/comment/handlers/payout.ts | 2 +- src/handlers/comment/handlers/query.ts | 4 +- src/handlers/comment/handlers/wallet.ts | 2 +- src/handlers/issue/pre.ts | 6 +-- src/handlers/label/index.ts | 2 +- src/handlers/payout/action.ts | 14 +++--- src/handlers/payout/post.ts | 2 +- src/handlers/pricing/action.ts | 2 +- src/handlers/wildcard/analytics.ts | 4 +- src/handlers/wildcard/weekly.ts | 2 +- src/helpers/issue.ts | 33 +++++++------- src/helpers/label.ts | 2 +- src/helpers/parser.ts | 8 ++-- src/helpers/payout.ts | 2 +- src/helpers/permit.ts | 2 +- src/helpers/similarity.ts | 22 ++++++--- src/utils/private.ts | 8 ++-- 27 files changed, 111 insertions(+), 105 deletions(-) diff --git a/src/adapters/supabase/helpers/client.ts b/src/adapters/supabase/helpers/client.ts index b8a3b23da..4085a7d10 100644 --- a/src/adapters/supabase/helpers/client.ts +++ b/src/adapters/supabase/helpers/client.ts @@ -1,6 +1,6 @@ import { createClient, SupabaseClient } from "@supabase/supabase-js"; import { getAdapters, getLogger } from "../../../bindings"; -import { Issue, UserProfile } from "../../../types"; +import { BotContext, Issue, UserProfile } from "../../../types"; import { Database } from "../types"; import { InsertPermit, Permit } from "../../../helpers"; import { BigNumber, BigNumberish } from "ethers"; @@ -54,27 +54,27 @@ export const getLastWeeklyTime = async (): Promise => { /** * @dev Updates the last weekly update timestamp */ -export const updateLastWeeklyTime = async (time: Date): Promise => { +export const updateLastWeeklyTime = async (context: BotContext, time: Date): Promise => { const logger = getLogger(); const { supabase } = getAdapters(); const { data, error } = await supabase.from("weekly").select("last_time"); if (error) { - logger.error(`Checking last time failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Checking last time failed, error: ${JSON.stringify(error)}`); throw new Error(`Checking last time failed, error: ${JSON.stringify(error)}`); } if (data && data.length > 0) { const { data, error } = await supabase.from("weekly").update({ last_time: time.toUTCString() }).neq("last_time", time.toUTCString()); if (error) { - logger.error(`Updating last time failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Updating last time failed, error: ${JSON.stringify(error)}`); throw new Error(`Updating last time failed, error: ${JSON.stringify(error)}`); } logger.info(`Updating last time is done, data: ${data}`); } else { const { data, error } = await supabase.from("weekly").insert({ last_time: time.toUTCString() }); if (error) { - logger.error(`Creating last time failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Creating last time failed, error: ${JSON.stringify(error)}`); throw new Error(`Creating last time failed, error: ${JSON.stringify(error)}`); } logger.info(`Creating last time is done, data: ${data}`); @@ -138,12 +138,12 @@ const getDbDataFromUserProfile = (userProfile: UserProfile, additions?: UserProf * Performs an UPSERT on the issues table. * @param issue The issue entity fetched from github event. */ -export const upsertIssue = async (issue: Issue, additions: IssueAdditions): Promise => { +export const upsertIssue = async (context: BotContext, issue: Issue, additions: IssueAdditions): Promise => { const logger = getLogger(); const { supabase } = getAdapters(); const { data, error } = await supabase.from("issues").select("id").eq("issue_number", issue.number); if (error) { - logger.error(`Checking issue failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Checking issue failed, error: ${JSON.stringify(error)}`); throw new Error(`Checking issue failed, error: ${JSON.stringify(error)}`); } @@ -154,14 +154,14 @@ export const upsertIssue = async (issue: Issue, additions: IssueAdditions): Prom .upsert({ id: key, ...getDbDataFromIssue(issue, additions) }) .select(); if (_error) { - logger.error(`Upserting an issue failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Upserting an issue failed, error: ${JSON.stringify(_error)}`); throw new Error(`Upserting an issue failed, error: ${JSON.stringify(_error)}`); } logger.info(`Upserting an issue done, { data: ${_data}, error: ${_error}`); } else { const { data: _data, error: _error } = await supabase.from("issues").insert(getDbDataFromIssue(issue, additions)); if (_error) { - logger.error(`Creating a new issue record failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Creating a new issue record failed, error: ${JSON.stringify(_error)}`); throw new Error(`Creating a new issue record failed, error: ${JSON.stringify(_error)}`); } logger.info(`Creating a new issue record done, { data: ${_data}, error: ${_error}`); @@ -172,26 +172,26 @@ export const upsertIssue = async (issue: Issue, additions: IssueAdditions): Prom * Performs an UPSERT on the users table. * @param user The user entity fetched from github event. */ -export const upsertUser = async (user: UserProfile): Promise => { +export const upsertUser = async (context: BotContext, user: UserProfile): Promise => { const logger = getLogger(); const { supabase } = getAdapters(); const { data, error } = await supabase.from("users").select("user_login").eq("user_login", user.login); if (error) { - logger.error(`Checking user failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Checking user failed, error: ${JSON.stringify(error)}`); throw new Error(`Checking user failed, error: ${JSON.stringify(error)}`); } if (data && data.length > 0) { const { data: _data, error: _error } = await supabase.from("users").upsert(getDbDataFromUserProfile(user)).select(); if (_error) { - logger.error(`Upserting a user failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Upserting a user failed, error: ${JSON.stringify(_error)}`); throw new Error(`Upserting a user failed, error: ${JSON.stringify(_error)}`); } logger.info(`Upserting a user done, { data: ${JSON.stringify(_data)} }`); } else { const { data: _data, error: _error } = await supabase.from("users").insert(getDbDataFromUserProfile(user)); if (_error) { - logger.error(`Creating a new user record failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Creating a new user record failed, error: ${JSON.stringify(_error)}`); throw new Error(`Creating a new user record failed, error: ${JSON.stringify(_error)}`); } logger.info(`Creating a new user record done, { data: ${JSON.stringify(_data)} }`); @@ -203,13 +203,13 @@ export const upsertUser = async (user: UserProfile): Promise => { * @param username The user name you want to upsert a wallet address for * @param address The account address */ -export const upsertWalletAddress = async (username: string, address: string): Promise => { +export const upsertWalletAddress = async (context: BotContext, username: string, address: string): Promise => { const logger = getLogger(); const { supabase } = getAdapters(); const { data, error } = await supabase.from("wallets").select("user_name").eq("user_name", username); if (error) { - logger.error(`Checking wallet address failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Checking wallet address failed, error: ${JSON.stringify(error)}`); throw new Error(`Checking wallet address failed, error: ${JSON.stringify(error)}`); } @@ -220,7 +220,7 @@ export const upsertWalletAddress = async (username: string, address: string): Pr updated_at: new Date().toUTCString(), }); if (_error) { - logger.error(`Upserting a wallet address failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Upserting a wallet address failed, error: ${JSON.stringify(_error)}`); throw new Error(`Upserting a wallet address failed, error: ${JSON.stringify(_error)}`); } logger.info(`Upserting a wallet address done, { data: ${JSON.stringify(_data)} }`); @@ -232,7 +232,7 @@ export const upsertWalletAddress = async (username: string, address: string): Pr updated_at: new Date().toUTCString(), }); if (error) { - logger.error(`Creating a new wallet_table record failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Creating a new wallet_table record failed, error: ${JSON.stringify(error)}`); throw new Error(`Creating a new wallet_table record failed, error: ${JSON.stringify(error)}`); } logger.info(`Creating a new wallet_table record done, { data: ${JSON.stringify(data)}, address: $address }`); @@ -244,13 +244,13 @@ export const upsertWalletAddress = async (username: string, address: string): Pr * @param username The user name you want to upsert a wallet address for * @param address The account multiplier */ -export const upsertWalletMultiplier = async (username: string, multiplier: string, reason: string, org_id: string): Promise => { +export const upsertWalletMultiplier = async (context: BotContext, username: string, multiplier: string, reason: string, org_id: string): Promise => { const logger = getLogger(); const { supabase } = getAdapters(); const { data, error } = await supabase.from("multiplier").select("user_id").eq("user_id", `${username}_${org_id}`); if (error) { - logger.error(`Checking wallet multiplier failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Checking wallet multiplier failed, error: ${JSON.stringify(error)}`); throw new Error(`Checking wallet multiplier failed, error: ${JSON.stringify(error)}`); } @@ -262,7 +262,7 @@ export const upsertWalletMultiplier = async (username: string, multiplier: strin updated_at: new Date().toUTCString(), }); if (_error) { - logger.error(`Upserting a wallet multiplier failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Upserting a wallet multiplier failed, error: ${JSON.stringify(_error)}`); throw new Error(`Upserting a wallet multiplier failed, error: ${JSON.stringify(_error)}`); } logger.info(`Upserting a wallet multiplier done, { data: ${JSON.stringify(_data)} }`); @@ -275,7 +275,7 @@ export const upsertWalletMultiplier = async (username: string, multiplier: strin updated_at: new Date().toUTCString(), }); if (_error) { - logger.error(`Creating a new multiplier record failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Creating a new multiplier record failed, error: ${JSON.stringify(_error)}`); throw new Error(`Creating a new multiplier record failed, error: ${JSON.stringify(_error)}`); } logger.info(`Creating a new multiplier record done, { data: ${JSON.stringify(_data)} }`); @@ -289,13 +289,13 @@ export const upsertWalletMultiplier = async (username: string, multiplier: strin * @param access Access granting * @param bool Disabling or enabling */ -export const upsertAccessControl = async (username: string, repository: string, access: string, bool: boolean): Promise => { +export const upsertAccessControl = async (context: BotContext, username: string, repository: string, access: string, bool: boolean): Promise => { const logger = getLogger(); const { supabase } = getAdapters(); const { data, error } = await supabase.from("access").select("user_name").eq("user_name", username).eq("repository", repository); if (error) { - logger.error(`Checking access control failed, error: ${JSON.stringify(error)}`); + logger.error(context, `Checking access control failed, error: ${JSON.stringify(error)}`); throw new Error(`Checking access control failed, error: ${JSON.stringify(error)}`); } @@ -309,7 +309,7 @@ export const upsertAccessControl = async (username: string, repository: string, if (data && data.length > 0) { const { data: _data, error: _error } = await supabase.from("access").upsert(properties); if (_error) { - logger.error(`Upserting a access control failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Upserting a access control failed, error: ${JSON.stringify(_error)}`); throw new Error(`Upserting a access control failed, error: ${JSON.stringify(_error)}`); } logger.info(`Upserting a access control done, { data: ${JSON.stringify(_data)} }`); @@ -323,7 +323,7 @@ export const upsertAccessControl = async (username: string, repository: string, ...properties, }); if (_error) { - logger.error(`Creating a new access control record failed, error: ${JSON.stringify(_error)}`); + logger.error(context, `Creating a new access control record failed, error: ${JSON.stringify(_error)}`); throw new Error(`Creating a new access control record failed, error: ${JSON.stringify(_error)}`); } logger.info(`Creating a new access control record done, { data: ${JSON.stringify(_data)} }`); diff --git a/src/bindings/config.ts b/src/bindings/config.ts index 43b5718fa..457bb8591 100644 --- a/src/bindings/config.ts +++ b/src/bindings/config.ts @@ -1,12 +1,11 @@ import ms from "ms"; -import { BotConfig, BotConfigSchema, LogLevel } from "../types"; +import { BotContext, BotConfig, BotConfigSchema, LogLevel } from "../types"; import { getPayoutConfigByNetworkId } from "../helpers"; import { ajv } from "../utils"; -import { Context } from "probot"; import { getScalarKey, getWideConfig } from "../utils/private"; -export const loadConfig = async (context: Context): Promise => { +export const loadConfig = async (context: BotContext): Promise => { const { baseMultiplier, timeLabels, diff --git a/src/bindings/event.ts b/src/bindings/event.ts index fd0f3de3a..8c544cca6 100644 --- a/src/bindings/event.ts +++ b/src/bindings/event.ts @@ -15,8 +15,8 @@ export const getAdapters = () => adapters; export type Logger = { info: (msg: string | object, options?: JSON) => void; debug: (msg: string | object, options?: JSON) => void; - warn: (msg: string | object, options?: JSON) => void; - error: (msg: string | object, options?: JSON) => void; + warn: (context: BotContext, msg: string | object, options?: JSON) => void; + error: (context: BotContext, msg: string | object, options?: JSON) => void; }; let logger: Logger; @@ -58,7 +58,7 @@ export const bindEvents = async (_context: ProbotContext): Promise => { } if (botConfigError) { - logger.error(botConfigError.toString()); + logger.error(context, botConfigError.toString()); if (eventName === GithubEvent.PUSH_EVENT) { await validateConfigChange(context); } @@ -93,7 +93,7 @@ export const bindEvents = async (_context: ProbotContext): Promise => { const valid = validate(payload); if (!valid) { logger.info("Payload schema validation failed!!!", payload); - if (validate.errors) logger.warn(validate.errors); + if (validate.errors) logger.warn(context, validate.errors); return; } @@ -108,7 +108,7 @@ export const bindEvents = async (_context: ProbotContext): Promise => { // Get the handlers for the action const handlers = processors[eventName]; if (!handlers) { - logger.warn(`No handler configured for event: ${eventName}`); + logger.warn(context, `No handler configured for event: ${eventName}`); return; } diff --git a/src/handlers/access/labels-access.ts b/src/handlers/access/labels-access.ts index 4b2b4d9a5..3a688f96b 100644 --- a/src/handlers/access/labels-access.ts +++ b/src/handlers/access/labels-access.ts @@ -13,7 +13,7 @@ export const handleLabelsAccess = async (context: BotContext) => { if (!payload.label?.name) return; const sender = payload.sender.login; const repo = payload.repository; - const permissionLevel = await getUserPermission(sender, context); + const permissionLevel = await getUserPermission(context, sender); // event in plain english const eventName = payload.action === "labeled" ? "add" : "remove"; const labelName = payload.label.name; diff --git a/src/handlers/assign/action.ts b/src/handlers/assign/action.ts index 1a5b1e2ed..2da5a9c0f 100644 --- a/src/handlers/assign/action.ts +++ b/src/handlers/assign/action.ts @@ -63,7 +63,7 @@ export const commentWithAssignMessage = async (context: BotContext): Promise => { @@ -71,7 +71,7 @@ export const closePullRequestForAnIssue = async (context: BotContext): Promise { // Loop through the pull requests and assign them to their respective issues if needed for (const pull of pulls) { - const linkedIssue = await gitLinkedIssueParser({ + const linkedIssue = await gitLinkedIssueParser(context, { owner: payload.repository.owner.login, repo: payload.repository.name, pull_number: pull.number, diff --git a/src/handlers/comment/handlers/allow.ts b/src/handlers/comment/handlers/allow.ts index caa05893e..a43b9b5e0 100644 --- a/src/handlers/comment/handlers/allow.ts +++ b/src/handlers/comment/handlers/allow.ts @@ -30,7 +30,7 @@ export const setAccess = async (context: BotContext, body: string) => { else if (part === "true" || part === "false") bool = part; }); if (!accessType || !username || !bool) { - logger.error("Invalid body for allow command"); + logger.error(context, "Invalid body for allow command"); return `Invalid syntax for allow \n usage: '/allow set-(access type) @user true|false' \n ex-1 /allow set-multiplier @user false`; } // Check if access control demand is valid @@ -41,7 +41,7 @@ export const setAccess = async (context: BotContext, body: string) => { // check if sender is admin // passing in context so we don't have to make another request to get the user - const permissionLevel = await getUserPermission(sender, context); + const permissionLevel = await getUserPermission(context, sender); // if sender is not admin, return if (permissionLevel !== "admin") { @@ -52,10 +52,10 @@ export const setAccess = async (context: BotContext, body: string) => { // convert accessType to valid table const tableName = `${accessType}_access`; - await upsertAccessControl(username, repo.full_name, tableName, bool === "true"); + await upsertAccessControl(context, username, repo.full_name, tableName, bool === "true"); return `Updated access for @${username} successfully!\t Access: **${accessType}** for "${repo.full_name}"`; } else { - logger.error("Invalid body for allow command"); + logger.error(context, "Invalid body for allow command"); return `Invalid syntax for allow \n usage: '/allow set-(access type) @user true|false' \n ex-1 /allow set-multiplier @user false`; } }; diff --git a/src/handlers/comment/handlers/authorize.ts b/src/handlers/comment/handlers/authorize.ts index 9a1693954..33a4c5be7 100644 --- a/src/handlers/comment/handlers/authorize.ts +++ b/src/handlers/comment/handlers/authorize.ts @@ -20,7 +20,7 @@ export const approveLabelChange = async (context: BotContext) => { // check if sender is admin // passing in context so we don't have to make another request to get the user - const permissionLevel = await getUserPermission(sender, context); + const permissionLevel = await getUserPermission(context, sender); // if sender is not admin, return if (permissionLevel !== "admin" && permissionLevel !== "billing_manager") { diff --git a/src/handlers/comment/handlers/index.ts b/src/handlers/comment/handlers/index.ts index ebd339a49..66c1e4006 100644 --- a/src/handlers/comment/handlers/index.ts +++ b/src/handlers/comment/handlers/index.ts @@ -181,13 +181,13 @@ export const issueReopenedCallback = async (context: BotContext): Promise const permitComment = comments[permitCommentIdx]; const permitUrl = permitComment.body.match(claimUrlRegex); if (!permitUrl || permitUrl.length < 2) { - logger.error(`Permit URL not found`); + logger.error(context, `Permit URL not found`); return; } const url = new URL(permitUrl[1]); const claimBase64 = url.searchParams.get("claim"); if (!claimBase64) { - logger.error(`Permit claim search parameter not found`); + logger.error(context, `Permit claim search parameter not found`); return; } let networkId = url.searchParams.get("network"); @@ -199,7 +199,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise try { claim = JSON.parse(Buffer.from(claimBase64, "base64").toString("utf-8")); } catch (err: unknown) { - logger.error(`Error parsing claim: ${err}`); + logger.error(context, `Error parsing claim: ${err}`); return; } const amount = BigNumber.from(claim.permit.permitted.amount); @@ -210,7 +210,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise // find latest assignment before the permit comment const events = await getAllIssueAssignEvents(context, issue.number); if (events.length === 0) { - logger.error(`No assignment found`); + logger.error(context, `No assignment found`); return; } const assignee = events[0].assignee.login; @@ -220,7 +220,7 @@ export const issueReopenedCallback = async (context: BotContext): Promise try { await addPenalty(assignee, repository.full_name, tokenAddress, networkId.toString(), amount); } catch (err) { - logger.error(`Error writing penalty to db: ${err}`); + logger.error(context, `Error writing penalty to db: ${err}`); return; } diff --git a/src/handlers/comment/handlers/multiplier.ts b/src/handlers/comment/handlers/multiplier.ts index 469c2b17a..109a9a7e6 100644 --- a/src/handlers/comment/handlers/multiplier.ts +++ b/src/handlers/comment/handlers/multiplier.ts @@ -54,7 +54,7 @@ export const multiplier = async (context: BotContext, body: string) => { username = username || sender; // check if sender is admin or billing_manager // passing in context so we don't have to make another request to get the user - const permissionLevel = await getUserPermission(sender, context); + const permissionLevel = await getUserPermission(context, sender); // if sender is not admin or billing_manager, check db for access if (permissionLevel !== "admin" && permissionLevel !== "billing_manager") { @@ -69,7 +69,7 @@ export const multiplier = async (context: BotContext, body: string) => { } logger.info(`Upserting to the wallet table, username: ${username}, bountyMultiplier: ${bountyMultiplier}, reason: ${reason}}`); - await upsertWalletMultiplier(username, bountyMultiplier?.toString(), reason, id?.toString()); + await upsertWalletMultiplier(context, username, bountyMultiplier?.toString(), reason, id?.toString()); if (bountyMultiplier > 1) { return `Successfully changed the payout multiplier for @${username} to ${bountyMultiplier}. The reason ${ reason ? `provided is "${reason}"` : "is not provided" @@ -80,7 +80,7 @@ export const multiplier = async (context: BotContext, body: string) => { }.`; } } else { - logger.error("Invalid body for bountyMultiplier command"); + logger.error(context, "Invalid body for bountyMultiplier command"); return `Invalid syntax for wallet command \n example usage: "/multiplier @user 0.5 'Multiplier reason'"`; } }; diff --git a/src/handlers/comment/handlers/payout.ts b/src/handlers/comment/handlers/payout.ts index 24178363e..3d6c26624 100644 --- a/src/handlers/comment/handlers/payout.ts +++ b/src/handlers/comment/handlers/payout.ts @@ -67,7 +67,7 @@ export const autoPay = async (context: BotContext, body: string) => { const res = body.match(pattern); if (res) { - const userPermission = await getUserPermission(payload.sender.login, context); + const userPermission = await getUserPermission(context, payload.sender.login); if (userPermission !== "admin" && userPermission !== "billing_manager") { return "You must be an `admin` or `billing_manager` to toggle automatic payments for completed issues."; } diff --git a/src/handlers/comment/handlers/query.ts b/src/handlers/comment/handlers/query.ts index 60e0e99de..a2d2e86f5 100644 --- a/src/handlers/comment/handlers/query.ts +++ b/src/handlers/comment/handlers/query.ts @@ -29,7 +29,7 @@ export const query = async (context: BotContext, body: string) => { if (!data) { logger.info(`Access info does not exist for @${user}`); try { - await upsertAccessControl(user, repo.full_name, "time_access", true); + await upsertAccessControl(context, user, repo.full_name, "time_access", true); data = { multiplier: false, priority: false, @@ -56,7 +56,7 @@ export const query = async (context: BotContext, body: string) => { `; } } else { - logger.error("Invalid body for query command"); + logger.error(context, "Invalid body for query command"); return `Invalid syntax for query command \n usage /query @user`; } }; diff --git a/src/handlers/comment/handlers/wallet.ts b/src/handlers/comment/handlers/wallet.ts index 1f2eeb144..f4773eb99 100644 --- a/src/handlers/comment/handlers/wallet.ts +++ b/src/handlers/comment/handlers/wallet.ts @@ -79,7 +79,7 @@ export const registerWallet = async (context: BotContext, body: string) => { logger.info("Skipping to register a wallet address because user is trying to set their address to null address"); return `Cannot set address to null address`; } - await upsertWalletAddress(sender, address); + await upsertWalletAddress(context, sender, address); return `Updated the wallet address for @${sender} successfully!\t Your new address: ${formatEthAddress(address)}`; } diff --git a/src/handlers/issue/pre.ts b/src/handlers/issue/pre.ts index 06f3cc93b..f8c438d84 100644 --- a/src/handlers/issue/pre.ts +++ b/src/handlers/issue/pre.ts @@ -8,7 +8,7 @@ export const findDuplicateOne = async (context: BotContext) => { const issue = payload.issue; if (!issue?.body) return; - const importantWords = await extractImportantWords(issue); + const importantWords = await extractImportantWords(context, issue); const perPage = 10; let curPage = 1; @@ -27,7 +27,7 @@ export const findDuplicateOne = async (context: BotContext) => { for (const result of response.data.items) { if (!result.body) continue; if (result.id === issue.id) continue; - const similarity = await measureSimilarity(issue, result as Issue); + const similarity = await measureSimilarity(context, issue, result as Issue); if (similarity > parseInt(process.env.SIMILARITY_THRESHOLD || "80")) { await upsertCommentToIssue( context, @@ -43,7 +43,7 @@ export const findDuplicateOne = async (context: BotContext) => { else curPage++; } } catch (e: unknown) { - logger.error(`Could not find any issues, reason: ${e}`); + logger.error(context, `Could not find any issues, reason: ${e}`); } } }; diff --git a/src/handlers/label/index.ts b/src/handlers/label/index.ts index 7adc7b1aa..cfd321113 100644 --- a/src/handlers/label/index.ts +++ b/src/handlers/label/index.ts @@ -22,7 +22,7 @@ export const watchLabelChange = async (context: BotContext) => { } // check if user is authorized to make the change - const hasAccess = await hasLabelEditPermission(currentLabel, triggerUser, repository.full_name); + const hasAccess = await hasLabelEditPermission(context, currentLabel, triggerUser, repository.full_name); await saveLabelChange(triggerUser, full_name, previousLabel, currentLabel, hasAccess); logger.debug("watchLabelChange: label name change saved to db"); diff --git a/src/handlers/payout/action.ts b/src/handlers/payout/action.ts index a2cab8707..16a5cee04 100644 --- a/src/handlers/payout/action.ts +++ b/src/handlers/payout/action.ts @@ -84,7 +84,7 @@ export const incentivesCalculation = async (context: BotContext): Promise => { const labelNames = labels.map((i) => i.name); logger.info(`Checking if the issue is a parent issue.`); if (payload.issue.body && isParentIssue(payload.issue.body)) { - logger.error("Identified as parent issue. Disabling price label."); + logger.error(context, "Identified as parent issue. Disabling price label."); const issuePrices = labels.filter((label) => label.name.toString().startsWith("Price:")); if (issuePrices.length) { await addCommentToIssue(context, GLOBAL_STRINGS.skipPriceLabelGenerationComment, payload.issue.number); diff --git a/src/handlers/wildcard/analytics.ts b/src/handlers/wildcard/analytics.ts index 008072071..7abe6c276 100644 --- a/src/handlers/wildcard/analytics.ts +++ b/src/handlers/wildcard/analytics.ts @@ -84,7 +84,7 @@ export const collectAnalytics = async (context: BotContext): Promise => { .toString()}` ); - await Promise.all(userProfilesToUpsert.map((i) => upsertUser(i))); + await Promise.all(userProfilesToUpsert.map((i) => upsertUser(context, i))); // No need to update the record for the bounties already closed const bountiesToUpsert = bounties.filter((bounty) => (bounty.state === IssueType.CLOSED ? bounty.number > maximumIssueNumber : true)); @@ -93,7 +93,7 @@ export const collectAnalytics = async (context: BotContext): Promise => { bountiesToUpsert.map((i) => { const additions = bountyInfo(context, i as Issue); if (additions.timelabel && additions.priorityLabel && additions.priceLabel) - return upsertIssue(i as Issue, { + return upsertIssue(context, i as Issue, { labels: { timeline: additions.timelabel, priority: additions.priorityLabel, diff --git a/src/handlers/wildcard/weekly.ts b/src/handlers/wildcard/weekly.ts index be13e83f2..cb02577fa 100644 --- a/src/handlers/wildcard/weekly.ts +++ b/src/handlers/wildcard/weekly.ts @@ -17,7 +17,7 @@ export const checkWeeklyUpdate = async (context: BotContext) => { const lastTime = await getLastWeeklyTime(); if (lastTime == undefined || new Date(lastTime.getTime() + SEVEN_DAYS) < curTime) { await run(context); - await updateLastWeeklyTime(curTime); + await updateLastWeeklyTime(context, curTime); } else { log.info(`Skipping to collect the weekly analytics because 7 days have not passed`); } diff --git a/src/helpers/issue.ts b/src/helpers/issue.ts index 4db95affa..44544b2fb 100644 --- a/src/helpers/issue.ts +++ b/src/helpers/issue.ts @@ -34,7 +34,7 @@ export const getAllIssueEvents = async (context: BotContext) => { } } catch (e: unknown) { shouldFetch = false; - logger.error(`Getting all issue events failed, reason: ${e}`); + logger.error(context, `Getting all issue events failed, reason: ${e}`); return null; } return events; @@ -201,20 +201,19 @@ export const upsertCommentToIssue = async (context: BotContext, issue_number: nu } }; -export const upsertLastCommentToIssue = async (issue_number: number, commentBody: string) => { +export const upsertLastCommentToIssue = async (context: BotContext, issue_number: number, commentBody: string) => { const logger = getLogger(); try { - const comments = await getAllIssueComments(issue_number); + const comments = await getAllIssueComments(context, issue_number); - if (comments.length > 0 && comments[comments.length - 1].body !== commentBody) await addCommentToIssue(commentBody, issue_number); + if (comments.length > 0 && comments[comments.length - 1].body !== commentBody) await addCommentToIssue(context, commentBody, issue_number); } catch (e: unknown) { logger.debug(`Upserting last comment failed! reason: ${e}`); } }; -export const getCommentsOfIssue = async (issue_number: number): Promise => { - const context = getBotContext(); +export const getCommentsOfIssue = async (context: BotContext, issue_number: number): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -384,15 +383,15 @@ export const removeAssignees = async (context: BotContext, issue_number: number, } }; -export const checkUserPermissionForRepoAndOrg = async (username: string, context: Context): Promise => { - const permissionForRepo = await checkUserPermissionForRepo(username, context); - const permissionForOrg = await checkUserPermissionForOrg(username, context); - const userPermission = await getUserPermission(username, context); +export const checkUserPermissionForRepoAndOrg = async (context: BotContext, username: string): Promise => { + const permissionForRepo = await checkUserPermissionForRepo(context, username); + const permissionForOrg = await checkUserPermissionForOrg(context, username); + const userPermission = await getUserPermission(context, username); return permissionForOrg || permissionForRepo || userPermission === "admin" || userPermission === "billing_manager"; }; -export const checkUserPermissionForRepo = async (username: string, context: Context): Promise => { +export const checkUserPermissionForRepo = async (context: BotContext, username: string): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -405,12 +404,12 @@ export const checkUserPermissionForRepo = async (username: string, context: Cont return res.status === 204; } catch (e: unknown) { - logger.error(`Checking if user permisson for repo failed! reason: ${e}`); + logger.error(context, `Checking if user permisson for repo failed! reason: ${e}`); return false; } }; -export const checkUserPermissionForOrg = async (username: string, context: Context): Promise => { +export const checkUserPermissionForOrg = async (context: BotContext, username: string): Promise => { const logger = getLogger(); const payload = context.payload as Payload; if (!payload.organization) return false; @@ -423,12 +422,12 @@ export const checkUserPermissionForOrg = async (username: string, context: Conte // skipping status check due to type error of checkMembershipForUser function of octokit return true; } catch (e: unknown) { - logger.error(`Checking if user permisson for org failed! reason: ${e}`); + logger.error(context, `Checking if user permisson for org failed! reason: ${e}`); return false; } }; -export const getUserPermission = async (username: string, context: Context): Promise => { +export const getUserPermission = async (context: BotContext, username: string): Promise => { const logger = getLogger(); const payload = context.payload as Payload; @@ -601,7 +600,7 @@ export const getPullRequestReviews = async ( } }; -export const getReviewRequests = async (context: Context, pull_number: number, owner: string, repo: string) => { +export const getReviewRequests = async (context: BotContext, pull_number: number, owner: string, repo: string) => { const logger = getLogger(); try { const response = await context.octokit.pulls.listRequestedReviewers({ @@ -611,7 +610,7 @@ export const getReviewRequests = async (context: Context, pull_number: number, o }); return response.data; } catch (e: unknown) { - logger.error(`Error: could not get requested reviewers, reason: ${e}`); + logger.error(context, `Error: could not get requested reviewers, reason: ${e}`); return null; } }; diff --git a/src/helpers/label.ts b/src/helpers/label.ts index d12ec3cc9..31b3a430b 100644 --- a/src/helpers/label.ts +++ b/src/helpers/label.ts @@ -118,6 +118,6 @@ export const updateLabelsFromBaseRate = async (context: BotContext, owner: strin } } } catch (error: unknown) { - logger.error(`Error updating labels, error: ${error}`); + logger.error(context, `Error updating labels, error: ${error}`); } }; diff --git a/src/helpers/parser.ts b/src/helpers/parser.ts index f4c6de3b7..bc4da48eb 100644 --- a/src/helpers/parser.ts +++ b/src/helpers/parser.ts @@ -18,7 +18,7 @@ export interface LinkedPR { prHref: string; } -export const gitLinkedIssueParser = async ({ owner, repo, pull_number }: GitParser) => { +export const gitLinkedIssueParser = async (context: BotContext, { owner, repo, pull_number }: GitParser) => { const logger = getLogger(); try { const { data } = await axios.get(`https://github.com/${owner}/${repo}/pull/${pull_number}`); @@ -33,12 +33,12 @@ export const gitLinkedIssueParser = async ({ owner, repo, pull_number }: GitPars const issueUrl = linkedIssues[0].querySelector("a")?.attrs?.href || ""; return issueUrl; } catch (error) { - logger.error(`${JSON.stringify(error)}`); + logger.error(context, `${JSON.stringify(error)}`); return null; } }; -export const gitLinkedPrParser = async ({ owner, repo, issue_number }: GitParser): Promise => { +export const gitLinkedPrParser = async (context: BotContext, { owner, repo, issue_number }: GitParser): Promise => { const logger = getLogger(); try { const prData = []; @@ -71,7 +71,7 @@ export const gitLinkedPrParser = async ({ owner, repo, issue_number }: GitParser return prData; } catch (error) { - logger.error(`${JSON.stringify(error)}`); + logger.error(context, `${JSON.stringify(error)}`); return []; } }; diff --git a/src/helpers/payout.ts b/src/helpers/payout.ts index 42d8aa071..428141940 100644 --- a/src/helpers/payout.ts +++ b/src/helpers/payout.ts @@ -50,7 +50,7 @@ export const getPayoutConfigByNetworkId = (networkId: number): PayoutConfigParti export const hasLabelEditPermission = async (context: BotContext, label: string, caller: string, repository: string) => { const logger = getLogger(); - const permissionLevel = await getUserPermission(caller, context); + const permissionLevel = await getUserPermission(context, caller); // get text before : const match = label.split(":"); diff --git a/src/helpers/permit.ts b/src/helpers/permit.ts index 4a73e71ec..b1c3f5809 100644 --- a/src/helpers/permit.ts +++ b/src/helpers/permit.ts @@ -115,7 +115,7 @@ export const savePermitToDB = async (context: BotContext, bountyHunterId: number const repository = payload.repository; const organization = payload.organization; if (!issue || !repository) { - logger.error("Cannot save permit to DB, missing issue, repository or organization"); + logger.error(context, "Cannot save permit to DB, missing issue, repository or organization"); throw new Error("Cannot save permit to DB, missing issue, repository or organization"); } diff --git a/src/helpers/similarity.ts b/src/helpers/similarity.ts index a5743e562..e69cecfcd 100644 --- a/src/helpers/similarity.ts +++ b/src/helpers/similarity.ts @@ -3,10 +3,11 @@ import axios, { AxiosError } from "axios"; import { ajv } from "../utils"; import { Static, Type } from "@sinclair/typebox"; import { backOff } from "exponential-backoff"; -import { Issue } from "../types"; +import { BotContext, Issue } from "../types"; -export const extractImportantWords = async (issue: Issue): Promise => { +export const extractImportantWords = async (context: BotContext, issue: Issue): Promise => { const res = await getAnswerFromChatGPT( + context, "", `${ process.env.CHATGPT_USER_PROMPT_FOR_IMPORTANT_WORDS || @@ -18,8 +19,9 @@ export const extractImportantWords = async (issue: Issue): Promise => return res.split(/[,# ]/); }; -export const measureSimilarity = async (first: Issue, second: Issue): Promise => { +export const measureSimilarity = async (context: BotContext, first: Issue, second: Issue): Promise => { const res = await getAnswerFromChatGPT( + context, "", `${( process.env.CHATGPT_USER_PROMPT_FOR_MEASURE_SIMILARITY || @@ -48,7 +50,13 @@ const ChoicesSchema = Type.Object({ type Choices = Static; -export const getAnswerFromChatGPT = async (systemPrompt: string, userPrompt: string, temperature = 0, max_tokens = 1500): Promise => { +export const getAnswerFromChatGPT = async ( + context: BotContext, + systemPrompt: string, + userPrompt: string, + temperature = 0, + max_tokens = 1500 +): Promise => { const logger = getLogger(); const body = JSON.stringify({ model: "gpt-3.5-turbo", @@ -87,18 +95,18 @@ export const getAnswerFromChatGPT = async (systemPrompt: string, userPrompt: str const validate = ajv.compile(ChoicesSchema); const valid = validate(data); if (!valid) { - logger.error(`Error occured from OpenAI`); + logger.error(context, `Error occured from OpenAI`); return ""; } const { choices: choice } = data; if (choice.length <= 0) { - logger.error(`No result from OpenAI`); + logger.error(context, `No result from OpenAI`); return ""; } const answer = choice[0].message.content; return answer; } catch (error) { - logger.error(`Getting response from ChatGPT failed: ${error}`); + logger.error(context, `Getting response from ChatGPT failed: ${error}`); return ""; } }; diff --git a/src/utils/private.ts b/src/utils/private.ts index 44ba7fb15..cd78f6fdf 100644 --- a/src/utils/private.ts +++ b/src/utils/private.ts @@ -1,6 +1,6 @@ import _sodium from "libsodium-wrappers"; import YAML from "yaml"; -import { MergedConfig, Payload } from "../types"; +import { BotContext, MergedConfig, Payload } from "../types"; import { Context } from "probot"; import merge from "lodash/merge"; @@ -108,7 +108,7 @@ const mergeConfigs = (configs: MergedConfigs) => { return merge({}, configs.parsedDefault, configs.parsedOrg, configs.parsedRepo); }; -export const getWideConfig = async (context: Context) => { +export const getWideConfig = async (context: BotContext) => { const orgConfig = await getConfigSuperset(context, "org", CONFIG_PATH); const repoConfig = await getConfigSuperset(context, "repo", CONFIG_PATH); const payload = context.payload as Payload; @@ -119,7 +119,7 @@ export const getWideConfig = async (context: Context) => { const { valid, error } = validate(WideConfigSchema, parsedOrg); if (!valid) { const err = new Error(`Invalid org config: ${error}`); - if (payload.issue) await upsertLastCommentToIssue(payload.issue.number, err.message); + if (payload.issue) await upsertLastCommentToIssue(context, payload.issue.number, err.message); throw err; } } @@ -130,7 +130,7 @@ export const getWideConfig = async (context: Context) => { const { valid, error } = validate(WideConfigSchema, parsedRepo); if (!valid) { const err = new Error(`Invalid repo config: ${error}`); - if (payload.issue) await upsertLastCommentToIssue(payload.issue.number, err.message); + if (payload.issue) await upsertLastCommentToIssue(context, payload.issue.number, err.message); throw err; } }