mirror of
https://github.com/homarr-labs/dashboard-icons.git
synced 2026-01-13 00:27:20 +08:00
refactor(web): batch submissions into single workflow dispatch
Updated triggerAddIconWorkflow to accept comma-separated submission IDs. Simplified triggerBulkAddIconWorkflow to join IDs and dispatch once instead of triggering multiple separate workflows. This works in tandem with the updated add-icon.yml workflow to process all submissions sequentially in a single run.
This commit is contained in:
@@ -51,15 +51,15 @@ async function verifyAdmin(
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the "Add Icon to Collection" GitHub workflow for a submission
|
||||
* Trigger the "Add Icon to Collection" GitHub workflow for one or more submissions
|
||||
* Only admins can trigger this action
|
||||
* @param authToken - The PocketBase auth token from the client
|
||||
* @param submissionId - The ID of the submission to add
|
||||
* @param submissionIds - Single ID or comma-separated IDs of submissions to add
|
||||
* @param dryRun - If true, skip actual writes (for testing)
|
||||
*/
|
||||
export async function triggerAddIconWorkflow(
|
||||
authToken: string,
|
||||
submissionId: string,
|
||||
submissionIds: string,
|
||||
dryRun = false,
|
||||
): Promise<TriggerWorkflowResult> {
|
||||
// Verify admin status using the provided token
|
||||
@@ -88,7 +88,7 @@ export async function triggerAddIconWorkflow(
|
||||
body: JSON.stringify({
|
||||
ref: "main",
|
||||
inputs: {
|
||||
submissionId: submissionId,
|
||||
submissionIds: submissionIds,
|
||||
dryRun: dryRun.toString(),
|
||||
},
|
||||
}),
|
||||
@@ -122,21 +122,16 @@ export async function triggerAddIconWorkflow(
|
||||
}
|
||||
}
|
||||
|
||||
interface BulkTriggerResult {
|
||||
submissionId: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface BulkTriggerWorkflowResult {
|
||||
success: boolean;
|
||||
results: BulkTriggerResult[];
|
||||
error?: string;
|
||||
workflowUrl?: string;
|
||||
submissionCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the "Add Icon to Collection" GitHub workflow for multiple submissions
|
||||
* Workflows are triggered sequentially with a small delay to avoid rate limiting
|
||||
* All submissions are processed in a single workflow run to avoid concurrency issues
|
||||
* @param authToken - The PocketBase auth token from the client
|
||||
* @param submissionIds - Array of submission IDs to add
|
||||
* @param dryRun - If true, skip actual writes (for testing)
|
||||
@@ -146,88 +141,22 @@ export async function triggerBulkAddIconWorkflow(
|
||||
submissionIds: string[],
|
||||
dryRun = false,
|
||||
): Promise<BulkTriggerWorkflowResult> {
|
||||
const { isAdmin, error: authError } = await verifyAdmin(authToken);
|
||||
if (!isAdmin) {
|
||||
if (submissionIds.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
results: submissionIds.map((id) => ({
|
||||
submissionId: id,
|
||||
success: false,
|
||||
error: authError || "Unauthorized",
|
||||
})),
|
||||
error: "No submission IDs provided",
|
||||
submissionCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const githubToken = process.env.GITHUB_TOKEN;
|
||||
if (!githubToken) {
|
||||
return {
|
||||
success: false,
|
||||
results: submissionIds.map((id) => ({
|
||||
submissionId: id,
|
||||
success: false,
|
||||
error: "GitHub token not configured",
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
const results: BulkTriggerResult[] = [];
|
||||
|
||||
for (const submissionId of submissionIds) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/actions/workflows/${WORKFLOW_FILE}/dispatches`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/vnd.github+json",
|
||||
Authorization: `Bearer ${githubToken}`,
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
ref: "main",
|
||||
inputs: {
|
||||
submissionId: submissionId,
|
||||
dryRun: dryRun.toString(),
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error(
|
||||
`GitHub API error for ${submissionId}:`,
|
||||
response.status,
|
||||
errorText,
|
||||
);
|
||||
results.push({
|
||||
submissionId,
|
||||
success: false,
|
||||
error: `GitHub API error: ${response.status}`,
|
||||
});
|
||||
} else {
|
||||
results.push({ submissionId, success: true });
|
||||
}
|
||||
|
||||
// Small delay between requests to avoid rate limiting
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
} catch (error) {
|
||||
console.error(`Error triggering workflow for ${submissionId}:`, error);
|
||||
results.push({
|
||||
submissionId,
|
||||
success: false,
|
||||
error:
|
||||
error instanceof Error ? error.message : "Failed to trigger workflow",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const allSucceeded = results.every((r) => r.success);
|
||||
const workflowUrl = `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/actions/workflows/${WORKFLOW_FILE}`;
|
||||
// Join all IDs with commas and trigger a single workflow
|
||||
const commaSeparatedIds = submissionIds.join(",");
|
||||
const result = await triggerAddIconWorkflow(authToken, commaSeparatedIds, dryRun);
|
||||
|
||||
return {
|
||||
success: allSucceeded,
|
||||
results,
|
||||
workflowUrl,
|
||||
success: result.success,
|
||||
error: result.error,
|
||||
workflowUrl: result.workflowUrl,
|
||||
submissionCount: submissionIds.length,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -224,37 +224,25 @@ export function useBulkTriggerWorkflow() {
|
||||
}
|
||||
|
||||
const result = await triggerBulkAddIconWorkflow(authToken, submissionIds, dryRun)
|
||||
if (!result.success) {
|
||||
throw new Error(result.error || "Failed to trigger workflow")
|
||||
}
|
||||
return result
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
const successCount = data.results.filter((r) => r.success).length
|
||||
const failCount = data.results.filter((r) => !r.success).length
|
||||
|
||||
if (failCount === 0) {
|
||||
toast.success(`Triggered ${successCount} workflow(s)`, {
|
||||
description: "All icon workflows have been queued. They will run sequentially.",
|
||||
action: data.workflowUrl
|
||||
? {
|
||||
label: "View on GitHub",
|
||||
onClick: () => window.open(data.workflowUrl, "_blank"),
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
} else {
|
||||
toast.warning(`Triggered ${successCount} of ${data.results.length} workflows`, {
|
||||
description: `${failCount} workflow(s) failed to trigger`,
|
||||
action: data.workflowUrl
|
||||
? {
|
||||
label: "View on GitHub",
|
||||
onClick: () => window.open(data.workflowUrl, "_blank"),
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
}
|
||||
toast.success(`Workflow triggered for ${data.submissionCount} icon(s)`, {
|
||||
description: "All icons will be processed sequentially in a single workflow run.",
|
||||
action: data.workflowUrl
|
||||
? {
|
||||
label: "View on GitHub",
|
||||
onClick: () => window.open(data.workflowUrl, "_blank"),
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
},
|
||||
onError: (error: Error) => {
|
||||
console.error("Error triggering bulk workflows:", error)
|
||||
toast.error("Failed to trigger workflows", {
|
||||
console.error("Error triggering bulk workflow:", error)
|
||||
toast.error("Failed to trigger workflow", {
|
||||
description: error.message || "An error occurred",
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user