200 lines · 8.0 KB
import { env } from "cloudflare:workers";
import { all, first, run } from "../db";
import { randomId } from "../crypto";
import { HttpError, badRequest } from "../errors";
import { loadRepoById } from "../repos";
import { manifestKey, PAGES_LIMITS, slotKey } from "./config";
import type { Manifest, PagesDeploymentRow, PagesEnvironment, PagesSiteRow, SitePointer } from "./config";
import type { CollectedFiles } from "./collect";
import { notifyPagesDeployFailed } from "../notify/deploy";
import type { RepoRow } from "~/lib/types";

const HOUR = 60 * 60 * 1000;
const HTTP_TOO_MANY = 429;

export type DeployRequest = {
  repo: RepoRow;
  site: PagesSiteRow;
  environment: PagesEnvironment;
  prNumber: number | null;
  ref: string;
  sha: string;
  artifactId: string | null;
  creatorId: string | null;
};

export async function loadSite(repoId: string): Promise<PagesSiteRow | null> {
  return first<PagesSiteRow>("SELECT * FROM pages_sites WHERE repo_id = ?", repoId);
}

export async function loadDeployment(id: string): Promise<PagesDeploymentRow | null> {
  return first<PagesDeploymentRow>("SELECT * FROM pages_deployments WHERE id = ?", id);
}

/** Queues a deploy, bounded per repository per hour, and hands it to the deploy Workflow. */
export async function createDeployment(input: DeployRequest): Promise<PagesDeploymentRow> {
  if (input.repo.visibility !== "public") throw badRequest("Pages can only publish public repositories");
  const recent = await first<{ count: number }>(
    "SELECT COUNT(*) AS count FROM pages_deployments WHERE repo_id = ? AND created_at > ?",
    input.repo.id,
    Date.now() - HOUR,