Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/development' into config-valid…
Browse files Browse the repository at this point in the history
…ation-error
  • Loading branch information
whilefoo committed Sep 12, 2023
2 parents 4098d1b + 7a42059 commit 2aa36c0
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 71 deletions.
14 changes: 9 additions & 5 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<!-- RULES TO CONTRIBUTE TO UBIQUIBOT
1. You must link the issue number e.g. "Resolves #1234"
2. You must link proof that your code works from a test issue on your forked repo e.g. "Quality Assurance https://github.com/user/repo/issues/1#issuecomment-1"
3. Please do not replace the keyword "Resolves" https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword
-->

Resolves #

<!--
- You must link the issue number e.g. "Resolves #1234"
- You must link the QA issue on your forked repo e.g. "QA for #1234"
- Please do not replace the keyword "Resolves" https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword
-->
Quality Assurance:
5 changes: 1 addition & 4 deletions .github/ubiquibot-config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
price-multiplier: 1.5
default-labels:
- "Time: <1 Hour"
- "Priority: 1 (Normal)"
price-multiplier: 1.5
7 changes: 4 additions & 3 deletions src/handlers/comment/action.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getBotConfig, getBotContext, getLogger } from "../../bindings";
import { Payload } from "../../types";
import { ErrorDiff } from "../../utils/helpers";

Check failure on line 3 in src/handlers/comment/action.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module '../../utils/helpers' or its corresponding type declarations.
import { IssueCommentCommands } from "./commands";
import { commentParser, userCommands } from "./handlers";
import { verifyFirstCheck } from "./handlers/first";
Expand Down Expand Up @@ -40,8 +41,8 @@ export const handleComment = async (): Promise<void> => {
const feature = config.command.find((e) => e.name === id.split("/")[1]);

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);
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);
continue;
}

Expand All @@ -54,7 +55,7 @@ export const handleComment = async (): Promise<void> => {
if (failureComment) {
await callback(issue.number, failureComment, payload.action, payload.comment);
}
await callback(issue.number, `Error: ${err}`, payload.action, payload.comment);
await callback(issue.number, ErrorDiff(err), payload.action, payload.comment);
}
} else {
logger.info(`Skipping for a command: ${command}`);
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/comment/handlers/assign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ const getMultiplierInfoToDisplay = async (senderLogin: string, org_id: string, i
} else {
_multiplierToDisplay = multiplier;
_reasonToDisplay = reason;
_bountyToDisplay = `Permit generation skipped since price label is not set`;
_bountyToDisplay = `Permit generation disabled because price label is not set.`;
const issueDetailed = bountyInfo(issue);
if (issueDetailed.priceLabel) {
_bountyToDisplay = (+issueDetailed.priceLabel.substring(7, issueDetailed.priceLabel.length - 4) * value).toString() + " USD";
Expand Down
35 changes: 20 additions & 15 deletions src/handlers/comment/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { handleIssueClosed } from "../../payout";
import { query } from "./query";
import { autoPay } from "./payout";
import { getTargetPriceLabel } from "../../shared";
import { ErrorDiff } from "../../../utils/helpers";

Check failure on line 30 in src/handlers/comment/handlers/index.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module '../../../utils/helpers' or its corresponding type declarations.

export * from "./assign";
export * from "./wallet";
Expand Down Expand Up @@ -71,7 +72,7 @@ export const issueClosedCallback = async (): Promise<void> => {
const comment = await handleIssueClosed();
if (comment) await addCommentToIssue(comment + comments.promotionComment, issue.number);
} catch (err: unknown) {
return await addCommentToIssue(`Error: ${err}`, issue.number);
return await addCommentToIssue(ErrorDiff(err), issue.number);
}
};

Expand All @@ -90,7 +91,7 @@ export const issueCreatedCallback = async (): Promise<void> => {
const { assistivePricing } = config.mode;

if (!assistivePricing) {
logger.info("Skipping adding label to issue because assistive pricing is disabled");
logger.info("Skipping adding label to issue because assistive pricing is disabled.");
return;
}

Expand All @@ -112,7 +113,7 @@ export const issueCreatedCallback = async (): Promise<void> => {
await addLabelToIssue(targetPriceLabel);
}
} catch (err: unknown) {
await addCommentToIssue(`Error: ${err}`, issue.number);
await addCommentToIssue(ErrorDiff(err), issue.number);
}
};

Expand Down Expand Up @@ -176,20 +177,24 @@ export const issueReopenedCallback = async (): Promise<void> => {
}
const assignee = events[0].assignee.login;

// write penalty to db
try {
await addPenalty(assignee, repository.full_name, tokenAddress, networkId.toString(), amount);
} catch (err) {
logger.error(`Error writing penalty to db: ${err}`);
return;
}
if (parseFloat(formattedAmount) > 0) {
// write penalty to db
try {
await addPenalty(assignee, repository.full_name, tokenAddress, networkId.toString(), amount);
} catch (err) {
logger.error(`Error writing penalty to db: ${err}`);
return;
}

await addCommentToIssue(
`@${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
);
await addCommentToIssue(
`@${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
);
} else {
logger.info(`Skipped penalty because amount is 0`);
}
} catch (err: unknown) {
await addCommentToIssue(`Error: ${err}`, issue.number);
await addCommentToIssue(ErrorDiff(err), issue.number);
}
};

Expand Down
37 changes: 18 additions & 19 deletions src/handlers/comment/handlers/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,22 @@ export const tableComment = ({
}) => {
return `
<code>
<table>
${
isBountyStale
? `<tr><td>Warning!</td> <td>This task was created over ${days} days ago. Please confirm that this issue specification is accurate before starting.</td></tr>`
: ``
}
<tr>
<td>Deadline</td>
<td>${deadline}</td>
</tr>
<tr>
<td>Registered Wallet</td>
<td>${wallet}</td>
</tr>
${multiplier ? `<tr><td>Payment Multiplier</td><td>${multiplier}</td></tr>` : ``}
${reason ? `<tr><td>Multiplier Reason</td><td>${reason}</td></tr>` : ``}
${bounty ? `<tr><td>Total Bounty</td><td>${bounty}</td></tr>` : ``}
</table>
</code>`;
<table>
${
isBountyStale
? `<tr><td>Warning!</td> <td>This task was created over ${days} days ago. Please confirm that this issue specification is accurate before starting.</td></tr>`
: ``
}
<tr>
<td>Deadline</td>
<td>${deadline}</td>
</tr>
<tr>
<td>Registered Wallet</td>
<td>${wallet}</td>
</tr>
${multiplier ? `<tr><td>Payment Multiplier</td><td>${multiplier}</td></tr>` : ``}
${reason ? `<tr><td>Multiplier Reason</td><td>${reason}</td></tr>` : ``}
${bounty ? `<tr><td>Total Bounty</td><td>${bounty}</td></tr>` : ``}
</table></code>`;
};
38 changes: 19 additions & 19 deletions src/handlers/payout/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const handleIssueClosed = async () => {
if (accessControl.organization) {
const userHasPermission = await checkUserPermissionForRepoAndOrg(payload.sender.login, context);

if (!userHasPermission) return "Permit generation skipped because this issue has been closed by an external contributor.";
if (!userHasPermission) return "Permit generation disabled because this issue has been closed by an external contributor.";
}

const comments = await getAllIssueComments(issue.number);
Expand Down Expand Up @@ -94,19 +94,19 @@ export const handleIssueClosed = async () => {
return;
}
if (privateKey == "") {
logger.info("Permit generation skipped because wallet private key is not set");
return "Permit generation skipped because wallet private key is not set";
logger.info("Permit generation disabled because wallet private key is not set.");
return "Permit generation disabled because wallet private key is not set.";
}
if (issue.state_reason !== StateReason.COMPLETED) {
logger.info("Permit generation skipped because the issue was not closed as completed");
return "Permit generation skipped because the issue was not closed as completed";
logger.info("Permit generation disabled because this is marked as unplanned.");
return "Permit generation disabled because this is marked as unplanned.";
}

logger.info(`Checking if the issue is a parent issue.`);
if (issue.body && isParentIssue(issue.body)) {
logger.error("Permit generation skipped since the issue is identified as parent issue.");
logger.error("Permit generation disabled because this is a collection of issues.");
await clearAllPriceLabelsOnIssue();
return "Permit generation skipped since the issue is identified as parent issue.";
return "Permit generation disabled because this is a collection of issues.";
}

logger.info(`Handling issues.closed event, issue: ${issue.number}`);
Expand All @@ -118,7 +118,7 @@ export const handleIssueClosed = async () => {
if (res) {
if (res[1] === "false") {
logger.info(`Skipping to generate permit2 url, reason: autoPayMode for this issue: false`);
return `Permit generation skipped since automatic payment for this issue is disabled.`;
return `Permit generation disabled because automatic payment for this issue is disabled.`;
}
break;
}
Expand All @@ -127,25 +127,25 @@ export const handleIssueClosed = async () => {

if (paymentPermitMaxPrice == 0 || !paymentPermitMaxPrice) {
logger.info(`Skipping to generate permit2 url, reason: { paymentPermitMaxPrice: ${paymentPermitMaxPrice}}`);
return `Permit generation skipped since paymentPermitMaxPrice is 0`;
return `Permit generation disabled because paymentPermitMaxPrice is 0.`;
}

const issueDetailed = bountyInfo(issue);
if (!issueDetailed.isBounty) {
logger.info(`Skipping... its not a bounty`);
return `Permit generation skipped since this issue didn't qualify as bounty`;
logger.info(`Skipping... its not a bounty.`);
return `Permit generation disabled because this issue didn't qualify as bounty.`;
}

const assignees = issue?.assignees ?? [];
const assignee = assignees.length > 0 ? assignees[0] : undefined;
if (!assignee) {
logger.info("Skipping to proceed the payment because `assignee` is undefined");
return `Permit generation skipped since assignee is undefined`;
logger.info("Skipping to proceed the payment because `assignee` is undefined.");
return `Permit generation disabled because assignee is undefined.`;
}

if (!issueDetailed.priceLabel) {
logger.info("Skipping to proceed the payment because price not set");
return `Permit generation skipped since price label is not set`;
return `Permit generation disabled because price label is not set.`;
}

const recipient = await getWalletAddress(assignee.login);
Expand All @@ -164,8 +164,8 @@ export const handleIssueClosed = async () => {

let priceInEth = new Decimal(issueDetailed.priceLabel.substring(7, issueDetailed.priceLabel.length - 4)).mul(multiplier);
if (priceInEth.gt(paymentPermitMaxPrice)) {
logger.info("Skipping to proceed the payment because bounty payout is higher than paymentPermitMaxPrice");
return `Permit generation skipped since issue's bounty is higher than ${paymentPermitMaxPrice}`;
logger.info("Skipping to proceed the payment because bounty payout is higher than paymentPermitMaxPrice.");
return `Permit generation disabled because issue's bounty is higher than ${paymentPermitMaxPrice}.`;
}

// if bounty hunter has any penalty then deduct it from the bounty
Expand All @@ -176,7 +176,7 @@ export const handleIssueClosed = async () => {
const bountyAmountAfterPenalty = bountyAmount.sub(penaltyAmount);
if (bountyAmountAfterPenalty.lte(0)) {
await removePenalty(assignee.login, payload.repository.full_name, paymentToken, networkId.toString(), bountyAmount);
const msg = `Permit generation skipped because bounty amount after penalty is 0`;
const msg = `Permit generation disabled because bounty amount after penalty is 0.`;
logger.info(msg);
return msg;
}
Expand All @@ -191,8 +191,8 @@ export const handleIssueClosed = async () => {
`#### Task Assignee Reward\n### [ **[ CLAIM ${priceInEth} ${tokenSymbol.toUpperCase()} ]** ](${payoutUrl})\n` + "```" + shortenRecipient + "```";
const permitComments = comments.filter((content) => content.body.includes("https://pay.ubq.fi?claim=") && content.user.type == UserType.Bot);
if (permitComments.length > 0) {
logger.info(`Skip to generate a permit url because it has been already posted`);
return `Permit generation skipped because it was already posted to this issue.`;
logger.info(`Skip to generate a permit url because it has been already posted.`);
return `Permit generation disabled because it was already posted to this issue.`;
}
await deleteLabel(issueDetailed.priceLabel);
await addLabelToIssue("Permitted");
Expand Down
4 changes: 2 additions & 2 deletions src/handlers/payout/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const incentivizeComments = async () => {
}

if (issue.state_reason !== StateReason.COMPLETED) {
logger.info("incentivizeComments: comment incentives skipped because the issue was not closed as completed");
logger.info("incentivizeComments: comment incentives disabled because the issue was not closed as completed.");
return;
}

Expand Down Expand Up @@ -143,7 +143,7 @@ export const incentivizeCreatorComment = async () => {
}

if (issue.state_reason !== StateReason.COMPLETED) {
logger.info("incentivizeCreatorComment: comment incentives skipped because the issue was not closed as completed");
logger.info("incentivizeCreatorComment: comment incentives disabled because the issue was not closed as completed.");
return;
}

Expand Down
18 changes: 15 additions & 3 deletions src/handlers/wildcard/unassign.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { closePullRequestForAnIssue } from "../assign";
import { getBotConfig, getLogger } from "../../bindings";
import { getBotConfig, getBotContext, getLogger } from "../../bindings";
import { GLOBAL_STRINGS } from "../../configs/strings";
import {
addCommentToIssue,
getAllIssueComments,
getCommitsOnPullRequest,
getOpenedPullRequestsForAnIssue,
getReviewRequests,
listAllIssuesForRepo,
removeAssignees,
} from "../../helpers";
import { Comment, Issue, IssueType } from "../../types";
import { Comment, Issue, IssueType, Payload } from "../../types";

/**
* @dev Check out the bounties which haven't been completed within the initial timeline
Expand All @@ -31,6 +32,8 @@ export const checkBountiesToUnassign = async () => {
};

const checkBountyToUnassign = async (issue: Issue): Promise<boolean> => {
const context = getBotContext();
const payload = context.payload as Payload;
const logger = getLogger();
const {
unassign: { followUpTime, disqualifyTime },
Expand All @@ -49,6 +52,14 @@ const checkBountyToUnassign = async (issue: Issue): Promise<boolean> => {
const curTimestamp = new Date().getTime();
const lastActivity = await lastActivityTime(issue, comments);
const passedDuration = curTimestamp - lastActivity.getTime();
const pullRequest = await getOpenedPullRequestsForAnIssue(issue.number, issue.assignee.login);

if (pullRequest.length > 0) {
const reviewRequests = await getReviewRequests(context, pullRequest[0].number, payload.repository.owner.login, payload.repository.name);
if (!reviewRequests || reviewRequests.users?.length > 0) {
return false;
}
}

if (passedDuration >= disqualifyTime || passedDuration >= followUpTime) {
if (passedDuration >= disqualifyTime) {
Expand All @@ -70,11 +81,12 @@ const checkBountyToUnassign = async (issue: Issue): Promise<boolean> => {
logger.info(
`Skipping posting an update message cause its been already asked, lastAskTime: ${lastAskTime}, lastActivityTime: ${lastActivity.getTime()}`
);
} else
} else {
await addCommentToIssue(
`${askUpdate} @${assignees[0]}? If you would like to release the bounty back to the DevPool, please comment \`/stop\` \nLast activity time: ${lastActivity}`,
issue.number
);
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/helpers/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,20 @@ export const getPullRequestReviews = async (context: Context, pull_number: numbe
}
};

export const getReviewRequests = async (context: Context, pull_number: number, owner: string, repo: string) => {
const logger = getLogger();
try {
const response = await context.octokit.pulls.listRequestedReviewers({
owner: owner,
repo: repo,
pull_number: pull_number,
});
return response.data;
} catch (e: unknown) {
logger.error(`Error: could not get requested reviewers, reason: ${e}`);
return null;
}
};
// Get issues by issue number
export const getIssueByNumber = async (context: Context, issue_number: number) => {
const logger = getLogger();
Expand Down

0 comments on commit 2aa36c0

Please sign in to comment.