Skip to content

Commit

Permalink
feat!: removed database and scrap GitHub organizations and repos
Browse files Browse the repository at this point in the history
  • Loading branch information
gentlementlegen committed Jul 29, 2024
1 parent ea07e5e commit cba2f9f
Show file tree
Hide file tree
Showing 19 changed files with 164 additions and 1,203 deletions.
Binary file removed database/sql.db
Binary file not shown.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Automated merging",
"description": "Automatically merge pull-requests.",
"ubiquity:listeners": [ "push", "pull_request.opened", "pull_request.reopened" ]
"ubiquity:listeners": [ "push" ]
}
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,16 @@
"dependencies": {
"@actions/core": "1.10.1",
"@actions/github": "6.0.0",
"@octokit/plugin-paginate-rest": "11.3.1",
"@octokit/rest": "20.1.1",
"@octokit/webhooks": "13.2.7",
"@sinclair/typebox": "0.32.33",
"@ubiquity-dao/ubiquibot-logger": "1.2.0",
"dotenv": "16.4.5",
"ms": "2.1.3",
"reflect-metadata": "0.2.2",
"sqlite3": "5.1.7",
"ts-retry": "4.2.5",
"typebox-validators": "0.3.5",
"typeorm": "0.3.20"
"typebox-validators": "0.3.5"
},
"devDependencies": {
"@commitlint/cli": "19.3.0",
Expand Down
11 changes: 0 additions & 11 deletions src/adapters/index.ts

This file was deleted.

15 changes: 0 additions & 15 deletions src/adapters/sqlite/data-source.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/adapters/sqlite/entities/pull-request.ts

This file was deleted.

47 changes: 0 additions & 47 deletions src/adapters/sqlite/helpers/pull-request-adapter.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/adapters/sqlite/helpers/sqlite.ts

This file was deleted.

15 changes: 0 additions & 15 deletions src/handlers/pull-request-opened.ts

This file was deleted.

43 changes: 27 additions & 16 deletions src/helpers/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export async function getMergeTimeoutAndApprovalRequiredCount(context: Context,

export async function getApprovalCount({ octokit, logger }: Context, { owner, repo, issue_number: pullNumber }: IssueParams) {
try {
const { data: reviews } = await octokit.pulls.listReviews({
const { data: reviews } = await octokit.rest.pulls.listReviews({
owner,
repo,
pull_number: pullNumber,
Expand All @@ -49,7 +49,7 @@ export async function isCiGreen({ octokit, logger, env }: Context, sha: string,
try {
const ref = sha;

const { data: checkSuites } = await octokit.checks.listSuitesForRef({
const { data: checkSuites } = await octokit.rest.checks.listSuitesForRef({
owner,
repo,
ref,
Expand All @@ -58,7 +58,7 @@ export async function isCiGreen({ octokit, logger, env }: Context, sha: string,
async () => {
const checkSuitePromises = checkSuites.check_suites.map(async (suite) => {
logger.debug(`Checking runs for suite ${suite.id}: ${suite.url}, and filter out ${env.workflowName}`);
const { data: checkRuns } = await octokit.checks.listForSuite({
const { data: checkRuns } = await octokit.rest.checks.listForSuite({
owner,
repo,
check_suite_id: suite.id,
Expand All @@ -74,7 +74,7 @@ export async function isCiGreen({ octokit, logger, env }: Context, sha: string,
return null;
} else if (
filteredResults.find((o) => {
logger.debug(`Workflow ${o.name}/${o.id}[${o.url}]: ${o.status},${o.conclusion}`);
logger.debug(`Workflow ${o.name}/${o.id} [${o.url}]: ${o.status},${o.conclusion}`);
return o.conclusion === "failure";
})
) {
Expand All @@ -100,18 +100,29 @@ export async function isCiGreen({ octokit, logger, env }: Context, sha: string,
}
}

export async function getOpenPullRequests({ octokit, logger }: Context, targets: string[]): Promise<string[]> {
const promises = targets.map(async (target) => {
try {
const [org, repo] = target.split("/");
const repoFilter = repo ? `repo:${repo}` : "";
await octokit.request("GET /search/issues", {
q: `is:pr is:open draft:false org:${org} ${repoFilter}`,
});
} catch (e) {
logger.error(`Error getting open pull-requests for target: ${target}`);
/**
* Returns all the pull requests that are opened and not a draft from the list of repos / organizations.
*
* https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests#search-only-issues-or-pull-requests
*/
export async function getOpenPullRequests({ octokit, logger }: Context, targets: string[]) {
const filter = targets.map((target) => {
let toExclude = "";
// If we have to exclude the target, happen a minus and remove it from the target name
if (target[0] === "-") {
toExclude = "-";
target = target.slice(1);
}
return target;
const [org, repo] = target.split("/");
return repo ? `${toExclude}repo:${org}/${repo}` : `${toExclude}org:${org}`;
});
return await Promise.all(promises);
try {
const results = await octokit.paginate("GET /search/issues", {
q: `is:pr is:open draft:false ${filter.join(" ")}`,
});
return results.flat();
} catch (e) {
logger.error(`Error getting open pull-requests for targets: [${targets.join(", ")}]. ${e}`);
return [];
}
}
44 changes: 19 additions & 25 deletions src/helpers/update-pull-requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ type IssueEvent = {
};

async function getPullRequestDetails(context: Context, { repo, owner, issue_number: pullNumber }: IssueParams) {
return (
await context.octokit.pulls.get({
repo,
owner,
pull_number: pullNumber,
})
).data;
const response = await context.octokit.rest.pulls.get({
repo,
owner,
pull_number: pullNumber,
});
console.log(response);
return response.data;
}

export async function updatePullRequests(context: Context) {
Expand All @@ -26,21 +26,16 @@ export async function updatePullRequests(context: Context) {
if (!pullRequests?.length) {
return context.logger.info("Nothing to do.");
}
for (const pullRequest of pullRequests) {
for (const { html_url } of pullRequests) {
try {
const gitHubUrl = parseGitHubUrl(pullRequest);
const gitHubUrl = parseGitHubUrl(html_url);
const pullRequestDetails = await getPullRequestDetails(context, gitHubUrl);
context.logger.debug(`Processing pull-request ${pullRequest}...`);
context.logger.debug(`Processing pull-request ${html_url}...`);
if (pullRequestDetails.merged || pullRequestDetails.closed_at) {
context.logger.info(`The pull request ${pullRequest} is already merged or closed, nothing to do.`);
try {
await context.adapters.sqlite.pullRequest.delete(pullRequest);
} catch (e) {
context.logger.error(`Failed to delete pull-request ${pullRequest}: ${e}`);
}
context.logger.info(`The pull request ${html_url} is already merged or closed, nothing to do.`);
continue;
}
const activity = await getAllTimelineEvents(context, parseGitHubUrl(pullRequest));
const activity = await getAllTimelineEvents(context, parseGitHubUrl(html_url));
const eventDates: Date[] = activity
.map((event) => {
const e = event as IssueEvent;
Expand All @@ -57,25 +52,24 @@ export async function updatePullRequests(context: Context) {
if (isNaN(lastActivityDate.getTime()) || isPastOffset(lastActivityDate, requirements.mergeTimeout)) {
if ((await getApprovalCount(context, gitHubUrl)) >= requirements.requiredApprovalCount) {
if (await isCiGreen(context, pullRequestDetails.head.sha, gitHubUrl)) {
context.logger.info(`Pull-request ${pullRequest} is past its due date (${requirements.mergeTimeout} after ${lastActivityDate}), will merge.`);
await mergePullRequest(context, pullRequest, gitHubUrl);
context.logger.info(`Pull-request ${html_url} is past its due date (${requirements.mergeTimeout} after ${lastActivityDate}), will merge.`);
await mergePullRequest(context, gitHubUrl);
} else {
context.logger.info(`Pull-request ${pullRequest} (sha: ${pullRequestDetails.head.sha}) does not pass all CI tests, won't merge.`);
context.logger.info(`Pull-request ${html_url} (sha: ${pullRequestDetails.head.sha}) does not pass all CI tests, won't merge.`);
}
} else {
context.logger.info(`Pull-request ${pullRequest} does not have sufficient reviewer approvals to be merged.`);
context.logger.info(`Pull-request ${html_url} does not have sufficient reviewer approvals to be merged.`);
}
} else {
context.logger.info(`PR ${pullRequest} has activity up until (${lastActivityDate}), nothing to do.`);
context.logger.info(`PR ${html_url} has activity up until (${lastActivityDate}), nothing to do.`);
}
} catch (e) {
context.logger.error(`Could not process pull-request ${pullRequest} for auto-merge: ${e}`);
context.logger.error(`Could not process pull-request ${html_url} for auto-merge: ${e}`);
}
}
}

async function mergePullRequest(context: Context, pullRequest: string, { repo, owner, issue_number: pullNumber }: IssueParams) {
await context.adapters.sqlite.pullRequest.delete(pullRequest);
async function mergePullRequest(context: Context, { repo, owner, issue_number: pullNumber }: IssueParams) {
await context.octokit.pulls.merge({
owner,
repo,
Expand Down
11 changes: 5 additions & 6 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { paginateRest } from "@octokit/plugin-paginate-rest";
import { Octokit } from "@octokit/rest";
import { Logs } from "@ubiquity-dao/ubiquibot-logger";
import { createAdapters } from "./adapters";
import { updatePullRequests } from "./helpers/update-pull-requests";
import { proxyCallbacks } from "./proxy";
import { Context, Env, PluginInputs } from "./types";

/**
* How a worker executes the plugin.
*/
export async function plugin(inputs: PluginInputs, env: Env) {
const octokit = new Octokit({ auth: inputs.authToken });
const octokitWithPlugin = Octokit.plugin(paginateRest);
const octokit = new octokitWithPlugin({ auth: inputs.authToken });

const context: Context = {
eventName: inputs.eventName,
Expand All @@ -18,9 +18,8 @@ export async function plugin(inputs: PluginInputs, env: Env) {
octokit,
env,
logger: new Logs("debug"),
adapters: {} as ReturnType<typeof createAdapters>,
};

await updatePullRequests(context);
return proxyCallbacks[inputs.eventName](context, env);
context.logger.info(`Will check the following repos / orgs: [${context.config.watch.join(", ")}]`);
return await updatePullRequests(context);
}
23 changes: 0 additions & 23 deletions src/proxy/index.ts

This file was deleted.

4 changes: 1 addition & 3 deletions src/types/context.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Octokit } from "@octokit/rest";
import { EmitterWebhookEvent as WebhookEvent, EmitterWebhookEventName as WebhookEventName } from "@octokit/webhooks";
import { Logs } from "@ubiquity-dao/ubiquibot-logger";
import { createAdapters } from "../adapters";
import { Env } from "./env";
import { PluginSettings } from "./plugin-inputs";

export type SupportedEventsU = "pull_request.opened" | "pull_request.reopened";
export type SupportedEventsU = "push";

export type SupportedEvents = {
[K in SupportedEventsU]: K extends WebhookEventName ? WebhookEvent<K> : never;
Expand All @@ -15,7 +14,6 @@ export interface Context<T extends SupportedEventsU = SupportedEventsU, TU exten
eventName: T;
payload: TU["payload"];
octokit: InstanceType<typeof Octokit>;
adapters: ReturnType<typeof createAdapters>;
config: PluginSettings;
env: Env;
logger: Logs;
Expand Down
2 changes: 1 addition & 1 deletion src/types/plugin-inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const pluginSettingsSchema = T.Object({
/**
* The list of organizations or repositories to watch for updates.
*/
watch: T.Array(T.String(), { default: [] }),
watch: T.Array(T.String({ minLength: 1 }), { default: [] }),
});

export const pluginSettingsValidator = new StandardValidator(pluginSettingsSchema);
Expand Down
Loading

0 comments on commit cba2f9f

Please sign in to comment.