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

Fix/workaround for character limits #21

Merged
merged 10 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript"
]
}
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SUPABASE_URL=
SUPABASE_KEY=
OPENAI_API_KEY=
UBIQUIBOT_APP_ID=
UBIQUIBOT_APP_PRIVATE_KEY=
X25519_PRIVATE_KEY=
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
dist
dist
.env
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
transform: {
'^.+\\.tsx?$': 'babel-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"main": "src/index.ts",
"license": "MIT",
"scripts": {
"start": "node --import tsx src/index.ts",
"test": "jest",
"preformat": "yarn format:prettier",
"format": "yarn format:eslint",
"postformat": "yarn format:cspell",
Expand Down Expand Up @@ -43,19 +45,23 @@
"openai": "^4.14.0",
"prettier": "^3.1.0",
"probot": "^12.3.3",
"tsx": "^4.4.0",
"tsx": "^4.7.1",
"typescript": "^5.2.2",
"yaml": "^2.3.3",
"zlib": "^1.0.5"
},
"devDependencies": {
"@babel/preset-env": "^7.23.9",
"@babel/preset-typescript": "^7.23.3",
"@types/jest": "^29.5.12",
"@types/jsdom": "^21.1.6",
"@types/libsodium-wrappers": "^0.7.13",
"@types/lodash": "^4.14.202",
"@types/markdown-it": "^13.0.7",
"@types/node": "^20.8.9",
"@types/pino-std-serializers": "^4.0.0",
"cspell": "^8.1.3"
"cspell": "^8.1.3",
"jest": "^29.7.0"
},
"lint-staged": {
"*.ts": [
Expand Down
8 changes: 3 additions & 5 deletions src/check-env.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { OpenAI } from "openai";

import { config } from "dotenv";
config();
export function checkEnvironmentVariables() {
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
if (!OPENAI_API_KEY) {
Expand All @@ -15,16 +16,13 @@ export function checkEnvironmentVariables() {
if (!SUPABASE_KEY) {
throw new Error("SUPABASE_KEY not set");
}
if (!process.env.OPENAI_API_KEY) {
throw new Error("OPENAI_API_KEY is not set");
}

// Use environment variables or other secure means to store these values
const appId = process.env.UBIQUIBOT_APP_ID;
const privateKey = process.env.UBIQUIBOT_APP_PRIVATE_KEY;
if (!privateKey) throw new Error("Missing UBIQUIBOT_APP_PRIVATE_KEY environment variable");

if (!appId) throw new Error("Missing UBIQUIBOT_APP_ID environment variable");
if (!privateKey) throw new Error("Missing UBIQUIBOT_APP_PRIVATE_KEY environment variable");

return {
SUPABASE_URL,
Expand Down
29 changes: 17 additions & 12 deletions src/handlers/issue/assignee-scoring.ts
Copy link
Member Author

@0x4007 0x4007 Feb 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically the real fixes are all in this file.

The rest of the changes are basically just 1. setting up jest to run locally 2. running the formatter

Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,27 @@ export async function assigneeScoring({
}): Promise<UserScoreDetails[]> {
// get the price label
const priceLabels = issue.labels.filter((label) => label.name.startsWith("Price: "));
if (!priceLabels) throw console.warn("Price label is undefined");

if (!priceLabels.length) {
console.warn("There are no price labels in this repository.");
return []; // Return an empty array if there are no price labels
}

// get the smallest price label
const priceLabel = priceLabels
.sort((a, b) => {
const priceA = parseFloat(a.name.replace("Price: ", ""));
const priceB = parseFloat(b.name.replace("Price: ", ""));
return priceA - priceB;
})[0]
.name.match(/\d+(\.\d+)?/)
?.shift();
const sortedPriceLabels = priceLabels.sort((a, b) => {
const priceA = parseFloat(a.name.replace("Price: ", ""));
const priceB = parseFloat(b.name.replace("Price: ", ""));
return priceA - priceB;
});

const smallestPriceLabel = sortedPriceLabels[0];
const priceLabelName = smallestPriceLabel.name;
const priceLabelMatch = priceLabelName.match(/\d+(\.\d+)?/);
const priceLabel = priceLabelMatch?.shift();

if (!priceLabel) {
throw console.warn("Price label is undefined");
console.warn("Price label is undefined");
return []; // Return an empty array if the price label is undefined
}

// get the price
Expand All @@ -46,11 +53,9 @@ export async function assigneeScoring({
// return the total
const details: UserScoreDetails = {
score: splitReward,

view: view,
role: "Assignee",
contribution: "Task",

scoring: {
issueComments: null,
reviewComments: null,
Expand Down
2 changes: 0 additions & 2 deletions src/handlers/issue/generate-erc20-permit-signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ export async function generateErc20PermitSignature({
keys: { evmPrivateEncrypted },
} = config;

console.trace({ config });

if (!evmPrivateEncrypted) throw console.warn("No bot wallet private key defined");
const { rpc, paymentToken } = getPayoutConfigByNetworkId(evmNetworkId);
const { privateKey } = await decryptKeys(evmPrivateEncrypted);
Expand Down
3 changes: 2 additions & 1 deletion src/handlers/issue/generate-permits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export async function generatePermits(
supabase: SupabaseClient
) {
const { html: comment, allTxs } = await generateComment(totals, issue, config, supabase);
console.trace({ totals });
const metadata = structuredMetadata.create("Transactions", { allTxs, totals });
return comment.concat("\n", metadata);
}
Expand Down Expand Up @@ -52,7 +53,7 @@ async function generateComment(totals: TotalsById, issue: GitHubIssue, config: B
if (error) throw error;

const beneficiaryAddress = data.length > 0 ? data[0].wallets.address : null;
if(!beneficiaryAddress) continue;
if (!beneficiaryAddress) continue;

const erc20Permits = [];
const permit = await generateErc20PermitSignature({
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/issue/relevance-scoring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ interface InEachRequestParams {

function filterSamples(batchResults: number[][], correctLength: number) {
return batchResults.filter((batchResult) => {
if(!batchResult) return [];
if (!batchResult) return [];
const filtered = batchResult.filter((score) => score >= 0 && score <= 1);
if (filtered.length == correctLength) {
return filtered;
Expand Down
48 changes: 48 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { createClient } from "@supabase/supabase-js";
import { checkEnvironmentVariables } from "./check-env";
import { DelegatedComputeInputs, getAuthenticatedOctokit, issueClosedEventHandler } from "./index";
import { GitHubEvent } from "./types/payload";
const { SUPABASE_URL, SUPABASE_KEY, openAi } = checkEnvironmentVariables();
afterEach(() => {
jest.resetAllMocks();
});
const inputs: DelegatedComputeInputs = {
eventName: "issues.closed" as GitHubEvent.ISSUES_CLOSED,
issueOwner: "ubiquibot",
issueRepository: "production",
issueNumber: "84",
collaborators: `["pavlovcik"]`,
installationId: "37627918", // "ubiquibot-dev" app
};

jest.mock("@actions/github", () => {
const inputs: DelegatedComputeInputs = {
eventName: "issues.closed" as GitHubEvent.ISSUES_CLOSED,
issueOwner: "ubiquibot",
issueRepository: "production",
issueNumber: "84",
collaborators: `["pavlovcik"]`,
installationId: "37627918", // "ubiquibot-dev" app
};

return {
context: {
payload: {
inputs,
},
},
};
});

export async function indexTest() {
const authenticatedOctokit = await getAuthenticatedOctokit();
const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY);

const output = await issueClosedEventHandler(supabaseClient, openAi, authenticatedOctokit, inputs);
console.log({ output });
}

it("runs", () =>
indexTest().then(() => {
console.log("done");
}), 60000);
10 changes: 4 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import OpenAI from "openai";
import { checkEnvironmentVariables } from "./check-env";
import { issueClosed } from "./handlers/issue/issue-closed";
import { getLinkedPullRequests } from "./helpers/get-linked-issues-and-pull-requests";
import { BotConfig } from "./types/configuration-types";
import { GitHubComment, GitHubEvent, GitHubIssue, GitHubUser } from "./types/payload";
import { generateInstallationAccessToken } from "./utils/generate-access-token";
import { generateConfiguration } from "./utils/generate-configuration";
import { BotConfig } from "./types/configuration-types";

async function getAuthenticatedOctokit() {
export async function getAuthenticatedOctokit(): Promise<Octokit> {
const { appId, privateKey } = checkEnvironmentVariables();
const webhookPayload = github.context.payload;
const inputs = webhookPayload.inputs as DelegatedComputeInputs; //as ExampleInputs;
Expand Down Expand Up @@ -45,7 +45,7 @@ getAuthenticatedOctokit()
core.setFailed(error);
});

interface DelegatedComputeInputs {
export interface DelegatedComputeInputs {
eventName: GitHubEvent;
issueOwner: string;
issueRepository: string;
Expand All @@ -60,8 +60,6 @@ async function run(authenticatedOctokit: Octokit) {
const inputs = webhookPayload.inputs as DelegatedComputeInputs; //as ExampleInputs;
const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY);

console.trace({ inputs });

const eventName = inputs.eventName;
if (GitHubEvent.ISSUES_CLOSED === eventName) {
return await issueClosedEventHandler(supabaseClient, openAi, authenticatedOctokit, inputs);
Expand All @@ -70,7 +68,7 @@ async function run(authenticatedOctokit: Octokit) {
}
}

async function issueClosedEventHandler(
export async function issueClosedEventHandler(
supabaseClient: SupabaseClient,
openAi: OpenAI,
authenticatedOctokit: Octokit,
Expand Down
51 changes: 0 additions & 51 deletions src/utils/generate-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,54 +163,3 @@ export function parseYaml(data: null | string) {
interface DecodeError extends Error {
value?: string;
}

// interface ExampleResponse {
// id: 37628281;
// account: GitHubUser;
// repository_selection: "all";
// access_tokens_url: "https://api.github.com/app/installations/37628281/access_tokens";
// repositories_url: "https://api.github.com/installation/repositories";
// html_url: "https://github.com/organizations/ubiquibot/settings/installations/37628281";
// app_id: 236521;
// app_slug: "ubiquibot";
// target_id: 133917611;
// target_type: "Organization";
// permissions: {
// issues: "write";
// actions: "write";
// members: "read";
// contents: "write";
// metadata: "read";
// pull_requests: "write";
// };
// events: GitHubEvent[];
// created_at: "2023-05-17T20:52:25.000Z";
// updated_at: "2023-12-23T09:58:37.000Z";
// single_file_name: null;
// has_multiple_single_files: false;
// single_file_paths: [];
// suspended_by: null;
// suspended_at: null;
// caller: "getInstallationOctokitForOrg";
// revision: "4c15837";
// }

// interface ExampleInstallation {
// type: "token";
// tokenType: "installation";
// token: "ghs_Pm5WyIfH7OjYg6uDv9MQGflRuaGeub2LYHu9";
// installationId: 37628281;
// permissions: {
// members: "read";
// actions: "write";
// contents: "write";
// issues: "write";
// metadata: "read";
// pull_requests: "write";
// };
// createdAt: "2023-12-23T15:08:59.876Z";
// expiresAt: "2023-12-23T16:08:59Z";
// repositorySelection: "all";
// caller: "dispatchWorkflow";
// revision: "4c15837";
// }
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
"types": [
"jest"
], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just type checking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
Expand Down
Loading