67 lines · 2.2 KB
import { first } from "../db";
import { loadRepoById } from "../repos";
import { notifyQuietly, quiet } from "./deliver";
import { repoAdmins } from "./recipients";

type DeployFailure = {
  kind: "Pages" | "Sites";
  repoId: string;
  creatorId: string | null;
  target: string;
  error: string;
  settingsPath: "pages" | "sites";
};

/** Deploy failures go to whoever pushed or requested the deploy plus the repository admins. */
async function notifyDeployFailure(input: DeployFailure): Promise<void> {
  const repo = await loadRepoById(input.repoId);
  if (!repo) return;
  await notifyQuietly({
    category: "deploy",
    repoId: repo.id,
    accountId: null,
    access: "read",
    recipients: [input.creatorId, ...(await repoAdmins(repo.id))],
    title: `${input.kind} deploy failed for ${repo.owner_name}/${repo.name} (${input.target})`,
    details: [`Error: ${input.error}`],
    url: `/${repo.owner_name}/${repo.name}/settings/${input.settingsPath}`,
  });
}

async function notifyPagesDeployFailedUnsafe(deploymentId: string, error: string): Promise<void> {
  const row = await first<{ repo_id: string; creator_id: string | null; ref: string }>(
    "SELECT repo_id, creator_id, ref FROM pages_deployments WHERE id = ? AND status = 'failed'",
    deploymentId,
  );
  if (!row) return;
  await notifyDeployFailure({
    kind: "Pages",
    repoId: row.repo_id,
    creatorId: row.creator_id,