Skip to content

Commit

Permalink
Merge pull request #61 from gentlementlegen/fix/pr-state
Browse files Browse the repository at this point in the history
fix: pull-request state adjustments
  • Loading branch information
gentlementlegen authored Dec 12, 2024
2 parents 0a81584 + 820e814 commit e0cce5b
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 32 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,21 @@ supabase start
Afterward, you can generate types for full auto-completion with

```shell
bun supabase:generate:local
bun run supabase:generate:local
```

### Test

To start Jest testing, run

```shell
bun test
bun run test
```

## Valid configuration

```yaml
- plugin: ubiquibot/user-activity-watcher
type: github
- plugin: ubiquity-os/daemon-disqualifier
with:
disqualification: "7 days"
warning: "3.5 days"
Expand All @@ -45,7 +44,7 @@ bun test
optOut:
- "repoName"
- "repoName2"
eventWhitelist: # these are the tail of the webhook event i.e pull_request.review_requested
eventWhitelist: # these are the tail of the webhook event i.e. pull_request.review_requested
- "review_requested"
- "ready_for_review"
- "commented"
Expand Down
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions dist/index.js

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"node": ">=20.10.0"
},
"scripts": {
"prebuild": "dotenv -- cross-env bun supabase:generate:remote",
"start": "bun --watch src/worker.ts",
"prebuild": "dotenv -- cross-env bun run supabase:generate:remote",
"format:lint": "eslint --fix .",
"format:prettier": "prettier --write .",
"format:cspell": "cspell **/*",
Expand All @@ -33,7 +34,7 @@
"@octokit/graphql-schema": "^15.25.0",
"@octokit/rest": "^21.0.2",
"@sinclair/typebox": "0.34.3",
"@ubiquity-os/plugin-sdk": "^1.1.0",
"@ubiquity-os/plugin-sdk": "^1.1.1",
"@ubiquity-os/ubiquity-os-logger": "^1.3.2",
"dotenv": "16.4.5",
"hono": "^4.6.12",
Expand Down
5 changes: 3 additions & 2 deletions src/helpers/collect-linked-pulls.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { PullRequest, User, validate } from "@octokit/graphql-schema";
import { PullRequest, validate } from "@octokit/graphql-schema";
import { ContextPlugin } from "../types/plugin-input";

type ClosedByPullRequestsReferences = {
node: Pick<PullRequest, "url" | "title" | "number" | "state" | "body"> & Pick<User, "login" | "id">;
node: Pick<PullRequest, "url" | "title" | "number" | "state" | "body" | "id"> & { author: { login: string; id: number } };
};

type IssueWithClosedByPrs = {
Expand All @@ -22,6 +22,7 @@ const query = /* GraphQL */ `
closedByPullRequestsReferences(first: 100, includeClosedPrs: false) {
edges {
node {
id
url
title
body
Expand Down
10 changes: 10 additions & 0 deletions src/helpers/pull-request-draft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const MUTATION_PULL_REQUEST_TO_DRAFT = /* GraphQL */ `
mutation ConvertPullRequestToDraft($input: ConvertPullRequestToDraftInput!) {
convertPullRequestToDraft(input: $input) {
pullRequest {
id
isDraft
}
}
}
`;
28 changes: 28 additions & 0 deletions src/helpers/remind-and-remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ListIssueForRepo } from "../types/github-types";
import { ContextPlugin } from "../types/plugin-input";
import { collectLinkedPullRequests } from "./collect-linked-pulls";
import { parseIssueUrl } from "./github-url";
import { MUTATION_PULL_REQUEST_TO_DRAFT } from "./pull-request-draft";
import { createStructuredMetadata } from "./structured-metadata";

export async function unassignUserFromIssue(context: ContextPlugin, issue: ListIssueForRepo) {
Expand Down Expand Up @@ -68,6 +69,11 @@ async function remindAssignees(context: ContextPlugin, issue: ListIssueForRepo)
issue_number: prNumber,
body: [logMessage.logMessage.raw, metadata].join("\n"),
});
await octokit.graphql(MUTATION_PULL_REQUEST_TO_DRAFT, {
input: {
pullRequestId: pullRequest.id,
},
});
} catch (e) {
logger.error(`Could not post to ${pullRequest.url} will post to the issue instead.`, { e });
shouldPostToMainIssue = true;
Expand Down Expand Up @@ -118,3 +124,25 @@ async function removeAllAssignees(context: ContextPlugin, issue: ListIssueForRep
});
return true;
}

export async function closeLinkedPullRequests(context: ContextPlugin, issue: ListIssueForRepo) {
const { octokit, logger } = context;
const { repo, owner, issue_number } = parseIssueUrl(issue.html_url);
const pullRequestsFromAssignees = (await collectLinkedPullRequests(context, { repo, owner, issue_number })).filter((o) =>
issue.assignees?.some((assignee) => assignee.id === o.author.id)
);

for (const pullRequest of pullRequestsFromAssignees) {
const { owner: prOwner, repo: prRepo, issue_number: prNumber } = parseIssueUrl(pullRequest.url);
try {
await octokit.rest.pulls.update({
owner: prOwner,
repo: prRepo,
pull_number: prNumber,
state: "closed",
});
} catch (e) {
logger.error(`Could not close pull-request ${pullRequest.url}.`, { e });
}
}
}
9 changes: 5 additions & 4 deletions src/helpers/task-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { ContextPlugin, TimelineEvent } from "../types/plugin-input";
import { collectLinkedPullRequests } from "./collect-linked-pulls";
import { getAssigneesActivityForIssue } from "./get-assignee-activity";
import { parseIssueUrl } from "./github-url";
import { remindAssigneesForIssue, unassignUserFromIssue } from "./remind-and-remove";
import { closeLinkedPullRequests, remindAssigneesForIssue, unassignUserFromIssue } from "./remind-and-remove";
import { getCommentsFromMetadata } from "./structured-metadata";
import { getTaskAssignmentDetails, parsePriorityLabel } from "./task-metadata";

const getMostRecentActivityDate = (assignedEventDate: DateTime, activityEventDate?: DateTime): DateTime => {
function getMostRecentActivityDate(assignedEventDate: DateTime, activityEventDate?: DateTime): DateTime {
return activityEventDate && activityEventDate > assignedEventDate ? activityEventDate : assignedEventDate;
};
}

export async function updateTaskReminder(context: ContextPlugin, repo: ListForOrg["data"][0], issue: ListIssueForRepo) {
const {
Expand Down Expand Up @@ -79,8 +79,9 @@ export async function updateTaskReminder(context: ContextPlugin, repo: ListForOr
mostRecentActivityDate = lastReminderTime > mostRecentActivityDate ? lastReminderTime : mostRecentActivityDate;
if (mostRecentActivityDate.plus({ milliseconds: prioritySpeed ? disqualificationTimeDifference / priorityLevel : disqualificationTimeDifference }) <= now) {
await unassignUserFromIssue(context, issue);
await closeLinkedPullRequests(context, issue);
} else {
logger.info(`Reminder was sent for ${issue.html_url} already, not beyond disqualification disqualification threshold yet.`, {
logger.info(`Reminder was sent for ${issue.html_url} already, not beyond disqualification deadline threshold yet.`, {
now: now.toLocaleString(DateTime.DATETIME_MED),
assignedDate: DateTime.fromISO(assignedEvent.created_at).toLocaleString(DateTime.DATETIME_MED),
lastReminderComment: lastReminderComment ? DateTime.fromISO(lastReminderComment.created_at).toLocaleString(DateTime.DATETIME_MED) : "none",
Expand Down
33 changes: 16 additions & 17 deletions src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import { createPlugin } from "@ubiquity-os/plugin-sdk";
import { Manifest } from "@ubiquity-os/plugin-sdk/dist/manifest";
import { LOG_LEVEL } from "@ubiquity-os/ubiquity-os-logger";
import { ExecutionContext } from "hono";
import manifest from "../manifest.json";
import { run } from "./run";
import { Env, envSchema, PluginSettings, pluginSettingsSchema, SupportedEvents } from "./types/plugin-input";

export default {
async fetch(request: Request, env: Record<string, string>, executionCtx?: ExecutionContext) {
return createPlugin<PluginSettings, Env, null, SupportedEvents>(
(context) => {
return run(context);
},
manifest as Manifest,
{
envSchema: envSchema,
settingsSchema: pluginSettingsSchema,
logLevel: process.env.LOG_LEVEL || LOG_LEVEL.INFO,
postCommentOnError: false,
...(env.KERNEL_PUBLIC_KEY && { kernelPublicKey: env.KERNEL_PUBLIC_KEY }),
bypassSignatureVerification: process.env.NODE_ENV === "local",
}
).fetch(request, env, executionCtx);
const app = createPlugin<PluginSettings, Env, null, SupportedEvents>(
(context) => {
return run(context);
},
manifest as Manifest,
{
envSchema: envSchema,
settingsSchema: pluginSettingsSchema,
logLevel: process.env.LOG_LEVEL || LOG_LEVEL.INFO,
postCommentOnError: false,
kernelPublicKey: process.env.KERNEL_PUBLIC_KEY,
bypassSignatureVerification: process.env.NODE_ENV === "local",
}
);

export default {
fetch: app.fetch,
port: 4000,
};

0 comments on commit e0cce5b

Please sign in to comment.