import type { Metadata } from "next"; import { notFound } from "next/navigation"; import { getPaths } from "yt-dlp-transcript-common/lib/paths"; import { getSettings } from "yt-dlp-transcript-common/lib/settings"; import { readBuiltStamp, readDeployedFile, type DeployRecord, } from "yt-dlp-transcript-common/publish/stamps"; import { BuildDeployButton } from "../../components/BuildDeployButton"; import { BuildExportButton } from "../../components/BuildExportButton"; import { DeployButton } from "../../components/DeployButton"; import { getSiteCached } from "../lib/siteCache"; export const dynamic = "force-dynamic"; // → "Publish — — Sites" through the layout's title template. export const metadata: Metadata = { title: "Publish" }; const VERDICT: Record = { ok: "live check ok", "stale-edge": "live check: the edge still serves an older build", mismatch: "live check: a different build answers", unreachable: "live check: unreachable", skipped: "live check skipped", }; function when(at: number): string { return new Date(at).toLocaleString(); } function recordLine(r: DeployRecord): string { const verdict = r.liveCheck ? ` · ${VERDICT[r.liveCheck.verdict] ?? r.liveCheck.verdict}` : ""; return `${when(r.at)}${r.url ? ` · ${r.url}` : ""}${verdict}`; } export default async function SitePublishPage({ params, }: { params: Promise<{ siteId: string }>; }) { const { siteId } = await params; const site = getSiteCached(siteId); if (!site) notFound(); const siteTitle = site.siteTitle || siteId; const paths = getPaths(); // This site's own records (release 18): its bundle's built.json and what // was shipped from it, deployed.json — no longer export/out's mtime, which // was the family's last build, whichever site that was. const [built, deployed] = await Promise.all([ readBuiltStamp(paths, siteId), readDeployedFile(paths, siteId), ]); const previews = Object.entries(deployed?.previews ?? {}).sort((a, b) => b[1].at - a[1].at); const lastPreview = previews[0]; const previewBranch = getSettings().publish.previewBranch; return (
{/* 1 — Build & deploy (primary path) for this site. */}

Build & deploy

Updates the index when it is stale, builds this site into its own bundle, then deploys that bundle to Cloudflare Pages production — stages on the publish queue, one at a time. Cancelling the build leaves the deploy nothing new to ship: it ends refused.

Built:
{built ? `${when(built.builtAt)}${built.branch ? ` from ${built.branch}` : ""}` : "never"}
Last deployed:
{deployed?.production ? recordLine(deployed.production) : "never"}
Last preview:
{lastPreview ? `${lastPreview[0]} · ${recordLine(lastPreview[1])}` : "never"}
{/* 2 — Individual steps, for when you only want one half. */}
Individual steps

Build static export

The site’s build stage: compose, then{" "} next build into{" "} export/.export-builds/{siteId}/out (and{" "} export/out links to it). The index is updated first when it is stale. No deploy.

Deploy static export

Publishes this site’s built bundle to Cloudflare Pages — to production, or to a preview branch you can look at first — and checks the live site. Build first.

); }