Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Refactor/time strings #21

Merged
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ To configure your Ubiquibot to run this plugin, add the following to the `.ubiqu
command: "\/start|\/stop"
example: "/start" # or "/stop"
with:
timers:
reviewDelayTolerance: 86000
taskStaleTimeoutDuration: 2580000
miscellaneous:
maxConcurrentTasks: 3
startRequiresWallet: true # default is true
reviewDelayTolerance: "3 Days"
taskStaleTimeoutDuration: "30 Days"
Keyrxng marked this conversation as resolved.
Show resolved Hide resolved
maxConcurrentTasks: 3
startRequiresWallet: true # default is true
```

# Testing
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/supabase/helpers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class User extends Super {
const { data, error } = (await this.supabase.from("users").select("wallets(*)").eq("id", userId).single()) as { data: { wallets: Wallet }; error: unknown };
if ((error && !data) || !data.wallets?.address) {
this.context.logger.error("No wallet address found", { userId, issueNumber });
if (this.context.config.miscellaneous.startRequiresWallet) {
if (this.context.config.startRequiresWallet) {
await addCommentToIssue(this.context, "```diff\n! Please set your wallet address with the /wallet command first and try again.\n```");
throw new Error("No wallet address found");
} else {
Expand Down
14 changes: 8 additions & 6 deletions src/handlers/shared/check-task-stale.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export function checkTaskStale(staleTask: number, createdAt: string) {
if (staleTask !== 0) {
const days = Math.floor((new Date().getTime() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24));
const staleToDays = Math.floor(staleTask / (1000 * 60 * 60 * 24));
return days >= staleToDays && staleToDays > 0;
export function checkTaskStale(staleTaskMilliseconds: number, createdAt: string): boolean {
if (staleTaskMilliseconds === 0) {
return false;
}

return false;
const currentDate = new Date();
const createdDate = new Date(createdAt);
const millisecondsSinceCreation = currentDate.getTime() - createdDate.getTime();

return millisecondsSinceCreation >= staleTaskMilliseconds
}
7 changes: 3 additions & 4 deletions src/handlers/shared/start.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Assignee, Context, ISSUE_TYPE, Label } from "../../types";
import { isParentIssue, getAvailableOpenedPullRequests, getAssignedIssues, addAssignees, addCommentToIssue } from "../../utils/issue";
import { isParentIssue, getAvailableOpenedPullRequests, getAssignedIssues, addAssignees, addCommentToIssue, getTimeValue } from "../../utils/issue";
import { calculateDurations } from "../../utils/shared";
import { checkTaskStale } from "./check-task-stale";
import { generateAssignmentComment } from "./generate-assignment-comment";
Expand All @@ -8,8 +8,7 @@ import { assignTableComment } from "./table";

export async function start(context: Context, issue: Context["payload"]["issue"], sender: Context["payload"]["sender"]) {
const { logger, config } = context;
const { maxConcurrentTasks } = config.miscellaneous;
const { taskStaleTimeoutDuration } = config.timers;
const { maxConcurrentTasks, taskStaleTimeoutDuration } = config;

// is it a child issue?
if (issue.body && isParentIssue(issue.body)) {
Expand Down Expand Up @@ -93,7 +92,7 @@ export async function start(context: Context, issue: Context["payload"]["issue"]
await addAssignees(context, issue.number, [login]);
}

const isTaskStale = checkTaskStale(taskStaleTimeoutDuration, issue.created_at);
const isTaskStale = checkTaskStale(getTimeValue(taskStaleTimeoutDuration), issue.created_at);

await addCommentToIssue(
context,
Expand Down
29 changes: 11 additions & 18 deletions src/types/plugin-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,17 @@ export interface PluginInputs<T extends SupportedEventsU = SupportedEventsU, TU
ref: string;
}

const ONE_DAY = 24 * 60 * 60 * 1000;

export const startStopSchema = T.Object({
timers: T.Object(
{
reviewDelayTolerance: T.Number(),
taskStaleTimeoutDuration: T.Number(),
},
{ default: { reviewDelayTolerance: ONE_DAY * 5, taskStaleTimeoutDuration: ONE_DAY * 30 } }
),
miscellaneous: T.Object(
{
maxConcurrentTasks: T.Number(),
startRequiresWallet: T.Boolean(),
},
{ default: { maxConcurrentTasks: 3, startRequiresWallet: true } }
),
});
export const startStopSchema = T.Object(
{
reviewDelayTolerance: T.String({ default: "1 Day" }),
taskStaleTimeoutDuration: T.String({ default: "30 Days" }),
maxConcurrentTasks: T.Number({ default: 3 }),
startRequiresWallet: T.Boolean({ default: true }),
},
{
default: {},
}
);

export type StartStopSettings = StaticDecode<typeof startStopSchema>;
export const startStopSettingsValidator = new StandardValidator(startStopSchema);
15 changes: 13 additions & 2 deletions src/utils/issue.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ms from "ms";
import { Context } from "../types/context";
import { Issue, ISSUE_TYPE, PullRequest, Review } from "../types/payload";
import { getLinkedPullRequests, GetLinkedResults } from "./get-linked-prs";
Expand Down Expand Up @@ -166,7 +167,7 @@ export async function getAllPullRequestReviews(context: Context, pullNumber: num
}

export async function getAvailableOpenedPullRequests(context: Context, username: string) {
const { reviewDelayTolerance } = context.config.timers;
const { reviewDelayTolerance } = context.config;
if (!reviewDelayTolerance) return [];

const openedPullRequests = await getOpenedPullRequests(context, username);
Expand All @@ -183,13 +184,23 @@ export async function getAvailableOpenedPullRequests(context: Context, username:
}
}

if (reviews.length === 0 && (new Date().getTime() - new Date(openedPullRequest.created_at).getTime()) / (1000 * 60 * 60) >= reviewDelayTolerance) {
if (reviews.length === 0 && (new Date().getTime() - new Date(openedPullRequest.created_at).getTime()) / ms("1h") >= getTimeValue(reviewDelayTolerance)) {
Keyrxng marked this conversation as resolved.
Show resolved Hide resolved
result.push(openedPullRequest);
}
}
return result;
}

export function getTimeValue(timeString: string): number {
const timeValue = ms(timeString);

if (!timeValue || timeValue <= 0 || isNaN(timeValue)) {
throw new Error("Invalid config time value");
}

return timeValue;
}

async function getOpenedPullRequests(context: Context, username: string): Promise<ReturnType<typeof getAllPullRequests>> {
const prs = await getAllPullRequests(context, "open");
return prs.filter((pr) => !pr.draft && (pr.user?.login === username || !username));
Expand Down
30 changes: 8 additions & 22 deletions tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@ type Sender = Context["payload"]["sender"];
const octokit = jest.requireActual("@octokit/rest");
const TEST_REPO = "ubiquity/test-repo";

const url = process.env.SUPABASE_URL;
const key = process.env.SUPABASE_KEY;

if (!url || !key) {
throw new Error("Supabase URL and Key are required");
}

beforeAll(() => {
server.listen();
});
Expand Down Expand Up @@ -524,37 +517,30 @@ async function setupTests() {
});
}

function createContext(issue: Record<string, unknown>, sender: Record<string, unknown>, body = "/start") {
function createContext(issue: Record<string, unknown>, sender: Record<string, unknown>, body = "/start"): Context {
return {
adapters: {} as ReturnType<typeof createAdapters>,
payload: {
issue: issue as unknown as Context["payload"]["issue"],
sender: sender as unknown as Context["payload"]["sender"],
repository: db.repo.findFirst({ where: { id: { equals: 1 } } }) as unknown as Context["payload"]["repository"],
comment: { body } as unknown as Context["payload"]["comment"],
action: "created" as string,
action: "created",
installation: { id: 1 } as unknown as Context["payload"]["installation"],
organization: { login: "ubiquity" } as unknown as Context["payload"]["organization"],
},
logger: new Logs("debug"),
config: {
timers: {
reviewDelayTolerance: 86000,
taskStaleTimeoutDuration: 2580000,
},
miscellaneous: {
maxConcurrentTasks: 3,
},
labels: {
time: ["Time: 1h", "Time: <4 hours", "Time: <1 Day", "Time: <3 Days", "Time: <1 Week"],
priority: ["Priority: 1 (Normal)", "Priority: 2 (High)", "Priority: 3 (Critical)"],
},
reviewDelayTolerance: "3 Days",
taskStaleTimeoutDuration: "30 Days",
maxConcurrentTasks: 3,
startRequiresWallet: false,
},
octokit: new octokit.Octokit(),
eventName: "issue_comment.created" as SupportedEventsU,
env: {
SUPABASE_KEY: key,
SUPABASE_URL: url,
SUPABASE_KEY: "key",
SUPABASE_URL: "url",
},
};
}
Expand Down