import { WorkflowEntrypoint } from "cloudflare:workers";
import type { WorkflowEvent, WorkflowStep } from "cloudflare:workers";
import { repoDb } from "../scoped-db";
import { siteDb } from "./store";
import { loadRepoById } from "../repos";
import { SCRATCH_LIMITS, STATIC_LIMITS } from "./config";
import { DeployError, extractArtifact, planGitFiles, totalBytes, uploadGitBatch } from "./collect";
import type { CollectedFiles, PlannedFile } from "./collect";
import { activateSiteDeployment, failSiteDeployment, loadSiteById, loadSiteDeployment } from "./deploy";
import { planBlockReason } from "../metering/quota";
export type SitesDeployParams = { deploymentId: string };
type Plan =
| { kind: "branch"; artifactsName: string; sha: string; folder: string; maxFiles: number; maxBytes: number }
| { kind: "artifact"; r2Key: string; folder: string }
| { kind: "skip"; error: string | null };
type Outcome<T> = { ok: true; value: T } | { ok: false; error: string };
async function attempt<T>(work: () => Promise<T>): Promise<Outcome<T>> {
try {
return { ok: true, value: await work() };
} catch (error) {
if (error instanceof DeployError) return { ok: false, error: error.message };
throw error;
}
}
async function start(deploymentId: string): Promise<Plan> {
const deployment = await loadSiteDeployment(deploymentId);
if (!deployment || deployment.status !== "queued") return { kind: "skip", error: null };
const site = await loadSiteById(deployment.site_id);
const repo = site?.repo_id ? await loadRepoById(site.repo_id) : null;
if (!site || !repo) return { kind: "skip", error: "The site is no longer linked to a repository" };
if (site.owner_id && site.scratch !== 1) {
const blocked = await planBlockReason(site.owner_id, "storage.sites");
if (blocked) return { kind: "skip", error: blocked };
}
await siteDb(site).run("UPDATE site_deployments SET status = 'building' WHERE id = ?", deploymentId);