220 lines · 9.3 KB
import { repoDb } from "../scoped-db";
import { locate, registerLocator } from "../scoped-db/locators";
import { scopedId } from "../scoped-db/ids";
import { siteDb } from "./store";
import { HttpError } from "../errors";
import { loadRepoById } from "../repos";
import { ZERO_SHA } from "../git/store";
import { env } from "cloudflare:workers";
import { labelUrl, SITE_LIMITS, slotKey } from "./config";
import type { SlotPointer } from "./config";
import { isOrphanSite } from "./sync";
import { createSiteDeployment, loadSiteForRepo, removePreview } from "./deploy";
import { previewLabel, pullLabel } from "./naming";
import type { SiteDeployRequest } from "./deploy";
import type { SiteRow } from "./config";

const MERGE_QUEUE_PREFIX = "gitfor-merge-queue/";

async function tryDeploy(input: SiteDeployRequest): Promise<boolean> {
  try {
    await createSiteDeployment(input);
    return true;
  } catch (error) {
    if (error instanceof HttpError) {
      console.warn("Site deploy skipped", input.site.id, error.message);
      return false;
    }
    throw error;
  }
}

/** Comments the pull request's `pr-N` preview link once; the pusher is the author so no bot account is needed. */
async function commentPreview(site: SiteRow, branch: string, authorId: string | null): Promise<void> {
  if (!authorId || !site.repo_id || !labelUrl(site.label)) return;
  const db = repoDb(site.repo_id);
  const pulls = await db.all<{ number: number; issue_id: string }>(
    `SELECT i.number, i.id AS issue_id FROM pull_requests p JOIN issues i ON i.id = p.issue_id
     WHERE p.repo_id = ? AND p.head_repo_id = ? AND p.head_ref = ? AND i.state = 'open' LIMIT ?`,
    site.repo_id,
    site.repo_id,