Skip to content
Open
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
11 changes: 10 additions & 1 deletion src/handlers/start/api/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const startQueryParamSchema = T.Object(
return parsed;
})
.Encode((val) => val.toString()),
issueUrl: T.String({ minLength: 1 }),
issueUrl: T.Optional(T.String({ minLength: 1 })),
issueUrls: T.Optional(T.Array(T.String({ minLength: 1 }))),
environment: T.Optional(T.Union([T.Literal("development"), T.Literal("production")])),
},
{
Expand All @@ -29,6 +30,14 @@ export type IssueUrlParts = {
issue_number: number;
};

export type MultiUrlResult = {
issueUrl: string;
ok: boolean;
computed?: StartEligibilityResult["computed"];
warnings?: LogReturn[] | null;
reasons?: string[] | null;
};

export type DatabaseUser = {
id: number | string;
wallet_id: number | null;
Expand Down
16 changes: 14 additions & 2 deletions src/handlers/start/api/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { extractJwtFromHeader, verifyJwt } from "./helpers/auth";
import { buildShallowContextObject } from "./helpers/context-builder";
import { fetchMergedPluginSettings } from "./helpers/get-plugin-config";
import { StartQueryParams, startQueryParamSchema } from "./helpers/types";
import { handleValidateOrExecute } from "./validate-or-execute";
import { handleMultiUrlValidateOrExecute, handleValidateOrExecute } from "./validate-or-execute";

/**
* Main handler for the public start API endpoint.
Expand Down Expand Up @@ -62,7 +62,7 @@ export async function handlePublicStart(honoCtx: HonoContext, env: Env, logger:
// Validate environment and parse request query params
const params = await validateQueryParams(honoCtx, logger);
if (params instanceof Response) return params;
const { issueUrl, userId, environment } = params;
const { issueUrl, issueUrls, userId, environment } = params;

// Build context and load merged plugin settings from org/repo config
const context = await buildShallowContextObject({
Expand All @@ -72,6 +72,18 @@ export async function handlePublicStart(honoCtx: HonoContext, env: Env, logger:
logger,
});

// Handle multi-URL case
if (issueUrls && issueUrls.length > 0) {
context.config = await fetchMergedPluginSettings({
env,
issueUrl: issueUrls[0],
logger,
environment,
jwt,
});
return await handleMultiUrlValidateOrExecute({ context, mode, issueUrls, jwt });
}

context.config = await fetchMergedPluginSettings({
env,
issueUrl,
Expand Down
40 changes: 40 additions & 0 deletions src/handlers/start/api/validate-or-execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,32 @@ import { performAssignment } from "../perform-assignment";
import { createCommand, createPayload, ShallowContext } from "./helpers/context-builder";
import { createRepoOctokit, createUserOctokit } from "./helpers/octokit";
import { parseIssueUrl } from "./helpers/parsers";
import type { MultiUrlResult } from "./helpers/types";

/**
* Handles multiple issue URLs and returns results for each.
*/
export async function handleMultiUrlValidateOrExecute({
context,
mode,
issueUrls,
jwt,
}: {
context: ShallowContext;
mode: "validate" | "execute";
issueUrls: string[];
jwt: string;
}): Promise<Response> {
const results: MultiUrlResult[] = [];

for (const issueUrl of issueUrls) {
const result = await handleSingleUrl({ context, mode, issueUrl, jwt });
const body = await result.clone().json();
results.push({ issueUrl, ...body });
}

return Response.json({ results }, { status: 200 });
}

/**
* Handles the validate or execute flow for a specific issue.
Expand All @@ -21,6 +47,20 @@ export async function handleValidateOrExecute({
mode: "validate" | "execute";
issueUrl: string;
jwt: string;
}): Promise<Response> {
return handleSingleUrl({ context, mode, issueUrl, jwt });
}

async function handleSingleUrl({
context,
mode,
issueUrl,
jwt,
}: {
context: ShallowContext;
mode: "validate" | "execute";
issueUrl: string;
jwt: string;
}): Promise<Response> {
const { owner, repo, issue_number: issueNumber } = parseIssueUrl(issueUrl, context.logger);
let issue, repository, organization;
Expand Down